<commit_before>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/vision.h>
#include <af/array.h>
#include "error.hpp"

namespace af
{

void sift(features& feat, array& desc, const array& in,
          const unsigned n_layers, const float contrast_thr,
          const float edge_thr, const float init_sigma,
          const bool double_input, const float img_scale,
          const float feature_ratio)
{
    af_features temp_feat;
    af_array temp_desc = 0;
    AF_THROW(af_sift(&temp_feat, &temp_desc, in.get(), n_layers, contrast_thr,
                     edge_thr, init_sigma, double_input, img_scale, feature_ratio));

    dim_t num = 0;
    AF_THROW(af_get_features_num(&num, temp_feat));
    feat = features(temp_feat);
    desc = array(temp_desc);
}

}
<commit_msg>Added C++ API for GLOH<commit_after>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/vision.h>
#include <af/array.h>
#include "error.hpp"

namespace af
{

void sift(features& feat, array& desc, const array& in,
          const unsigned n_layers, const float contrast_thr,
          const float edge_thr, const float init_sigma,
          const bool double_input, const float img_scale,
          const float feature_ratio)
{
    af_features temp_feat;
    af_array temp_desc = 0;
    AF_THROW(af_sift(&temp_feat, &temp_desc, in.get(), n_layers, contrast_thr,
                     edge_thr, init_sigma, double_input, img_scale, feature_ratio));

    dim_t num = 0;
    AF_THROW(af_get_features_num(&num, temp_feat));
    feat = features(temp_feat);
    desc = array(temp_desc);
}

void gloh(features& feat, array& desc, const array& in,
          const unsigned n_layers, const float contrast_thr,
          const float edge_thr, const float init_sigma,
          const bool double_input, const float img_scale,
          const float feature_ratio)
{
    af_features temp_feat;
    af_array temp_desc = 0;
    AF_THROW(af_gloh(&temp_feat, &temp_desc, in.get(), n_layers, contrast_thr,
                     edge_thr, init_sigma, double_input, img_scale, feature_ratio));

    dim_t num = 0;
    AF_THROW(af_get_features_num(&num, temp_feat));
    feat = features(temp_feat);
    desc = array(temp_desc);
}

}
<|endoftext|>


<commit_before>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#define CAF_SUITE response_handle

#include "caf/response_handle.hpp"

#include "core-test.hpp"

#include "caf/scheduled_actor/flow.hpp"

using namespace caf;

namespace {

struct dummy_state {
  static inline const char* name = "dummy";

  caf::behavior make_behavior() {
    return {
      [](int32_t x) -> result<int32_t> {
        if (x % 2 == 0)
          return x + x;
        else
          return make_error(sec::invalid_argument);
      },
    };
  }
};

using dummy_actor = stateful_actor<dummy_state>;

struct fixture : test_coordinator_fixture<> {
  actor dummy;
  actor aut;

  fixture() {
    dummy = sys.spawn<dummy_actor>();
    sched.run();
  }
};

} // namespace

BEGIN_FIXTURE_SCOPE(fixture)

SCENARIO("response handles are convertible to observables and singles") {
  GIVEN("a response handle that produces a valid result") {
    WHEN("calling as_single") {
      THEN("observers see the result") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{42})
          .as_single<int32_t>()
          .subscribe([&result](int32_t val) { result = val; },
                     [&result](const error& what) { result = what; });
        launch();
        expect((int32_t), from(aut).to(dummy).with(42));
        expect((int32_t), from(dummy).to(aut).with(84));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{84});
      }
    }
    WHEN("calling as_observable") {
      THEN("observers see the result") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        size_t on_next_calls = 0;
        bool completed = false;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{42})
          .as_observable<int32_t>()
          .for_each(
            [&](int32_t val) {
              result = val;
              ++on_next_calls;
            },
            [&](const error& what) { result = what; },
            [&] { completed = true; });
        launch();
        expect((int32_t), from(aut).to(dummy).with(42));
        expect((int32_t), from(dummy).to(aut).with(84));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{84});
        CHECK_EQ(on_next_calls, 1u);
        CHECK(completed);
      }
    }
  }
  GIVEN("a response handle that produces an error") {
    WHEN("calling as_single") {
      THEN("observers see an error") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{13})
          .as_single<int32_t>()
          .subscribe([&result](int32_t val) { result = val; },
                     [&result](const error& what) { result = what; });
        launch();
        expect((int32_t), from(aut).to(dummy).with(13));
        expect((error), from(dummy).to(aut));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{make_error(sec::invalid_argument)});
      }
    }
    WHEN("calling as_observable") {
      THEN("observers see an error") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        size_t on_next_calls = 0;
        bool completed = false;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{13})
          .as_observable<int32_t>()
          .for_each(
            [&](int32_t val) {
              result = val;
              ++on_next_calls;
            },
            [&](const error& what) { result = what; },
            [&] { completed = true; });
        launch();
        expect((int32_t), from(aut).to(dummy).with(13));
        expect((error), from(dummy).to(aut));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{make_error(sec::invalid_argument)});
        CHECK_EQ(on_next_calls, 0u);
        CHECK(!completed);
      }
    }
  }
}

END_FIXTURE_SCOPE()
<commit_msg>Fix unit test checks<commit_after>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#define CAF_SUITE response_handle

#include "caf/response_handle.hpp"

#include "core-test.hpp"

#include "caf/scheduled_actor/flow.hpp"

using namespace caf;

namespace {

struct dummy_state {
  static inline const char* name = "dummy";

  caf::behavior make_behavior() {
    return {
      [](int32_t x) -> result<int32_t> {
        if (x % 2 == 0)
          return x + x;
        else
          return make_error(sec::invalid_argument);
      },
    };
  }
};

using dummy_actor = stateful_actor<dummy_state>;

struct fixture : test_coordinator_fixture<> {
  actor dummy;

  fixture() {
    dummy = sys.spawn<dummy_actor>();
    sched.run();
  }
};

} // namespace

BEGIN_FIXTURE_SCOPE(fixture)

SCENARIO("response handles are convertible to observables and singles") {
  GIVEN("a response handle that produces a valid result") {
    WHEN("calling as_single") {
      THEN("observers see the result") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{42})
          .as_single<int32_t>()
          .subscribe([&result](int32_t val) { result = val; },
                     [&result](const error& what) { result = what; });
        auto aut = actor{self};
        launch();
        expect((int32_t), from(aut).to(dummy).with(42));
        expect((int32_t), from(dummy).to(aut).with(84));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{84});
      }
    }
    WHEN("calling as_observable") {
      THEN("observers see the result") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        size_t on_next_calls = 0;
        bool completed = false;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{42})
          .as_observable<int32_t>()
          .for_each(
            [&](int32_t val) {
              result = val;
              ++on_next_calls;
            },
            [&](const error& what) { result = what; },
            [&] { completed = true; });
        auto aut = actor{self};
        launch();
        expect((int32_t), from(aut).to(dummy).with(42));
        expect((int32_t), from(dummy).to(aut).with(84));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{84});
        CHECK_EQ(on_next_calls, 1u);
        CHECK(completed);
      }
    }
  }
  GIVEN("a response handle that produces an error") {
    WHEN("calling as_single") {
      THEN("observers see an error") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{13})
          .as_single<int32_t>()
          .subscribe([&result](int32_t val) { result = val; },
                     [&result](const error& what) { result = what; });
        auto aut = actor{self};
        launch();
        expect((int32_t), from(aut).to(dummy).with(13));
        expect((error), from(dummy).to(aut));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{make_error(sec::invalid_argument)});
      }
    }
    WHEN("calling as_observable") {
      THEN("observers see an error") {
        using result_t = std::variant<none_t, int32_t, caf::error>;
        size_t on_next_calls = 0;
        bool completed = false;
        result_t result;
        auto [self, launch] = sys.spawn_inactive<event_based_actor>();
        self->request(dummy, infinite, int32_t{13})
          .as_observable<int32_t>()
          .for_each(
            [&](int32_t val) {
              result = val;
              ++on_next_calls;
            },
            [&](const error& what) { result = what; },
            [&] { completed = true; });
        auto aut = actor{self};
        launch();
        expect((int32_t), from(aut).to(dummy).with(13));
        expect((error), from(dummy).to(aut));
        CHECK(!sched.has_job());
        CHECK_EQ(result, result_t{make_error(sec::invalid_argument)});
        CHECK_EQ(on_next_calls, 0u);
        CHECK(!completed);
      }
    }
  }
}

END_FIXTURE_SCOPE()
<|endoftext|>


<commit_before>/*****************************************************************************************
*                                                                                *
* OpenSpace                                                                             *
*                                                                                *
* Copyright (c) 2014-2016                                                               *
*                                                                                *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify,    *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
* permit persons to whom the Software is furnished to do so, subject to the following   *
* conditions:                                                                           *
*                                                                                *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software.                                              *
*                                                                                *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
****************************************************************************************/

#include <modules/globebrowsing/globes/renderableglobe.h>

#include <ghoul/misc/threadpool.h>

#include <modules/globebrowsing/tile/tileselector.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>

// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/scene/scenegraphnode.h>

#include <modules/debugging/rendering/debugrenderer.h>

// ghoul includes
#include <ghoul/misc/assert.h>

namespace {
    const std::string _loggerCat = "RenderableGlobe";

    // Keys for the dictionary
    const std::string keyFrame = "Frame";
    const std::string keyRadii = "Radii";
    const std::string keyInteractionDepthBelowEllipsoid =
        "InteractionDepthBelowEllipsoid";
    const std::string keyCameraMinHeight = "CameraMinHeight";
    const std::string keySegmentsPerPatch = "SegmentsPerPatch";
    const std::string keyTextures = "Textures";
    const std::string keyColorTextures = "ColorTextures";
    const std::string keyHeightMaps = "HeightMaps";
}

namespace openspace {
namespace globebrowsing {

    SingleTexturePropertyOwner::SingleTexturePropertyOwner(std::string name)
    : isEnabled("isEnabled", "isEnabled", true) {
        setName(name);
        addProperty(isEnabled);
    }

    SingleTexturePropertyOwner::~SingleTexturePropertyOwner() {

    }

    LayeredCategoryPropertyOwner::LayeredCategoryPropertyOwner(
        LayeredTextures::TextureCategory category,
        TileProviderManager& tileProviderManager)
    : _tileProviderManager(tileProviderManager)
    , _levelBlendingEnabled("blendTileLevels", "blend tile levels", true){
        setName(LayeredTextures::TEXTURE_CATEGORY_NAMES[category]);

        // Create the property owners
        auto& layerGroup = _tileProviderManager.getTileProviderGroup(category);
        for (NamedTileProvider& tileProvider : layerGroup.tileProviders) {
            _texturePropertyOwners.push_back(
                std::make_unique<SingleTexturePropertyOwner>(tileProvider.name));
        }

        // Specify and add the property owners
        for (int i = 0; i < layerGroup.tileProviders.size(); i++) {
            NamedTileProvider &tileProvider = layerGroup.tileProviders[i];
            SingleTexturePropertyOwner &prop = *_texturePropertyOwners[i].get();
            prop.isEnabled.set(tileProvider.isActive);
            prop.isEnabled.onChange([&]{
                tileProvider.isActive = prop.isEnabled;
            });

            for (auto setting : tileProvider.settings.array()) {
                prop.addProperty(setting->property());
            }

            addPropertySubOwner(prop);
        }

        _levelBlendingEnabled.set(layerGroup.levelBlendingEnabled);
        _levelBlendingEnabled.onChange([&]{
            layerGroup.levelBlendingEnabled = _levelBlendingEnabled;
        });
        addProperty(_levelBlendingEnabled);
    }

    LayeredCategoryPropertyOwner::~LayeredCategoryPropertyOwner() {

    }

    RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
    : _generalProperties({
        properties::BoolProperty("enabled", "Enabled", true),
        properties::BoolProperty("performShading", "perform shading", true),
        properties::BoolProperty("atmosphere", "atmosphere", false),
        properties::FloatProperty("lodScaleFactor", "lodScaleFactor",10.0f, 1.0f, 50.0f),
        properties::FloatProperty(
            "cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)
    })
    , _debugProperties({
        properties::BoolProperty("saveOrThrowCamera", "save or throw camera", false),
        properties::BoolProperty("showChunkEdges", "show chunk edges", false),
        properties::BoolProperty("showChunkBounds", "show chunk bounds", false),
        properties::BoolProperty("showChunkAABB", "show chunk AABB", false),
    	properties::BoolProperty("showHeightResolution", "show height resolution", false),
        properties::BoolProperty(
            "showHeightIntensities", "show height intensities", false),
        properties::BoolProperty(
            "performFrustumCulling", "perform frustum culling", true),
        properties::BoolProperty(
            "performHorizonCulling", "perform horizon culling", true),
        properties::BoolProperty(
            "levelByProjectedAreaElseDistance", "level by projected area (else distance)",
            false),
        properties::BoolProperty("resetTileProviders", "reset tile providers", false),
        properties::BoolProperty(
            "toggleEnabledEveryFrame", "toggle enabled every frame", false)})
    {
        setName("RenderableGlobe");

        dictionary.getValue(keyFrame, _frame);

        // Read the radii in to its own dictionary
        Vec3 radii;
        dictionary.getValue(keyRadii, radii);
        _ellipsoid = Ellipsoid(radii);
        setBoundingSphere(pss(_ellipsoid.averageRadius(), 0.0));

        // Ghoul can't read ints from lua dictionaries...
        double patchSegmentsd;
        dictionary.getValue(keySegmentsPerPatch, patchSegmentsd);
        int patchSegments = patchSegmentsd;

        dictionary.getValue(keyInteractionDepthBelowEllipsoid,
            _interactionDepthBelowEllipsoid);
        float cameraMinHeight;
        dictionary.getValue(keyCameraMinHeight, cameraMinHeight);
        _generalProperties.cameraMinHeight.set(cameraMinHeight);

        // Init tile provider manager
        ghoul::Dictionary texturesDictionary;
        dictionary.getValue(keyTextures, texturesDictionary);

        _tileProviderManager = std::make_shared<TileProviderManager>(texturesDictionary);

        _chunkedLodGlobe = std::make_shared<ChunkedLodGlobe>(
            *this, patchSegments, _tileProviderManager);
        _pointGlobe = std::make_shared<PointGlobe>(*this);

        _distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e9);
        _distanceSwitch.addSwitchValue(_pointGlobe, 1e12);

        _debugPropertyOwner.setName("Debug");
        _texturePropertyOwner.setName("Textures");

        addProperty(_generalProperties.isEnabled);
        addProperty(_generalProperties.atmosphereEnabled);
        addProperty(_generalProperties.performShading);
        addProperty(_generalProperties.lodScaleFactor);
        addProperty(_generalProperties.cameraMinHeight);

        _debugPropertyOwner.addProperty(_debugProperties.saveOrThrowCamera);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkBounds);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkAABB);
        _debugPropertyOwner.addProperty(_debugProperties.showHeightResolution);
        _debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities);
        _debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling);
        _debugPropertyOwner.addProperty(_debugProperties.performHorizonCulling);
        _debugPropertyOwner.addProperty(
            _debugProperties.levelByProjectedAreaElseDistance);
        _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
        _debugPropertyOwner.addProperty(_debugProperties.toggleEnabledEveryFrame);

        for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++) {
            _textureProperties.push_back(std::make_unique<LayeredCategoryPropertyOwner>
                (LayeredTextures::TextureCategory(i), *_tileProviderManager));
            _texturePropertyOwner.addPropertySubOwner(*_textureProperties[i]);
        }

        addPropertySubOwner(_debugPropertyOwner);
        addPropertySubOwner(_texturePropertyOwner);
    }

    RenderableGlobe::~RenderableGlobe() {

    }

    bool RenderableGlobe::initialize() {
        return _distanceSwitch.initialize();
    }

    bool RenderableGlobe::deinitialize() {
        return _distanceSwitch.deinitialize();
    }

    bool RenderableGlobe::isReady() const {
        return _distanceSwitch.isReady();
    }

    void RenderableGlobe::render(const RenderData& data) {
        if (_debugProperties.toggleEnabledEveryFrame.value()) {
            _generalProperties.isEnabled.setValue(
                !_generalProperties.isEnabled.value());
        }
        if (_generalProperties.isEnabled.value()) {
            if (_debugProperties.saveOrThrowCamera.value()) {
                _debugProperties.saveOrThrowCamera.setValue(false);

                if (savedCamera() == nullptr) { // save camera
                    LDEBUG("Saving snapshot of camera!");
                    setSaveCamera(std::make_shared<Camera>(data.camera));
                }
                else { // throw camera
                    LDEBUG("Throwing away saved camera!");
                    setSaveCamera(nullptr);
                }
            }
            _distanceSwitch.render(data);
        }
        if (_savedCamera != nullptr) {
            DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera);
        }
    }

    void RenderableGlobe::update(const UpdateData& data) {
        _time = data.time;
        _distanceSwitch.update(data);

        glm::dmat4 translation =
            glm::translate(glm::dmat4(1.0), data.modelTransform.translation);
        glm::dmat4 rotation = glm::dmat4(data.modelTransform.rotation);
        glm::dmat4 scaling =
            glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale,
                data.modelTransform.scale, data.modelTransform.scale));

        _cachedModelTransform = translation * rotation * scaling;
        _cachedInverseModelTransform = glm::inverse(_cachedModelTransform);

        if (_debugProperties.resetTileProviders) {
            _tileProviderManager->reset();
            _debugProperties.resetTileProviders = false;
        }
        _tileProviderManager->update();
        _chunkedLodGlobe->update(data);
    }

    glm::dvec3 RenderableGlobe::projectOnEllipsoid(glm::dvec3 position) {
        return _ellipsoid.geodeticSurfaceProjection(position);
    }

    float RenderableGlobe::getHeight(glm::dvec3 position) {
        // Get the tile provider for the height map
        const auto& heightMapProviders = _tileProviderManager->getTileProviderGroup(
            LayeredTextures::HeightMaps).getActiveTileProviders();
        if (heightMapProviders.size() == 0)
            return 0;
        const auto& tileProvider = heightMapProviders[0];

        // Get the uv coordinates to sample from
        Geodetic2 geodeticPosition = _ellipsoid.cartesianToGeodetic2(position);
        int chunkLevel = _chunkedLodGlobe->findChunkNode(
            geodeticPosition).getChunk().tileIndex().level;

        TileIndex chunkIdx = TileIndex(geodeticPosition, chunkLevel);
        GeodeticPatch patch = GeodeticPatch(chunkIdx);
        Geodetic2 geoDiffPatch =
            patch.getCorner(Quad::NORTH_EAST) -
            patch.getCorner(Quad::SOUTH_WEST);
        Geodetic2 geoDiffPoint = geodeticPosition - patch.getCorner(Quad::SOUTH_WEST);
        glm::vec2 patchUV = glm::vec2(
            geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat);

        // Transform the uv coordinates to the current tile texture
        TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(
            tileProvider.get(), chunkIdx);
        const auto& tile = tileAndTransform.tile;
        const auto& uvTransform = tileAndTransform.uvTransform;
        const auto& depthTransform = tileProvider->depthTransform();
        if (tile.status != Tile::Status::OK) {
            return 0;
        }
        //glm::vec2 transformedUv = uvTransform.uvOffset + uvTransform.uvScale * patchUV;

        glm::vec2 transformedUv = Tile::TileUvToTextureSamplePosition(
            uvTransform,
            patchUV,
            glm::uvec2(tile.texture->dimensions()));

        // Sample and do linear interpolation
        // (could possibly be moved as a function in ghoul texture)
        glm::uvec3 dimensions = tile.texture->dimensions();

        glm::vec2 samplePos = transformedUv * glm::vec2(dimensions);
        glm::uvec2 samplePos00 = samplePos;
        samplePos00 = glm::clamp(
            samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00);

        glm::uvec2 samplePos10 = glm::min(
            samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::uvec2 samplePos01 = glm::min(
            samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::uvec2 samplePos11 = glm::min(
            samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1));

        float sample00 = tile.texture->texelAsFloat(samplePos00).x;
        float sample10 = tile.texture->texelAsFloat(samplePos10).x;
        float sample01 = tile.texture->texelAsFloat(samplePos01).x;
        float sample11 = tile.texture->texelAsFloat(samplePos11).x;

        float sample0 = sample00 * (1.0 - samplePosFract.x) + sample10 * samplePosFract.x;
        float sample1 = sample01 * (1.0 - samplePosFract.x) + sample11 * samplePosFract.x;

        float sample = sample0 * (1.0 - samplePosFract.y) + sample1 * samplePosFract.y;

        // Perform depth transform to get the value in meters
        float height = depthTransform.depthOffset + depthTransform.depthScale * sample;

        // Return the result
        return height;
    }

    std::shared_ptr<ChunkedLodGlobe> RenderableGlobe::chunkedLodGlobe() const{
        return _chunkedLodGlobe;
    }

    const Ellipsoid& RenderableGlobe::ellipsoid() const{
        return _ellipsoid;
    }

    const glm::dmat4& RenderableGlobe::modelTransform() const{
        return _cachedModelTransform;
    }

    const glm::dmat4& RenderableGlobe::inverseModelTransform() const{
        return _cachedInverseModelTransform;
    }

    const RenderableGlobe::DebugProperties&
        RenderableGlobe::debugProperties() const{
        return _debugProperties;
    }

    const RenderableGlobe::GeneralProperties&
        RenderableGlobe::generalProperties() const{
        return _generalProperties;
    }

    const std::shared_ptr<const Camera> RenderableGlobe::savedCamera() const {
        return _savedCamera;
    }

    double RenderableGlobe::interactionDepthBelowEllipsoid() {
        return _interactionDepthBelowEllipsoid;
    }

    void RenderableGlobe::setSaveCamera(std::shared_ptr<Camera> camera) {
        _savedCamera = camera;
    }
} // namespace globebrowsing
} // namespace openspace

<commit_msg>Remove toggle every frame debug property from gui.<commit_after>/*****************************************************************************************
*                                                                                *
* OpenSpace                                                                             *
*                                                                                *
* Copyright (c) 2014-2016                                                               *
*                                                                                *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify,    *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
* permit persons to whom the Software is furnished to do so, subject to the following   *
* conditions:                                                                           *
*                                                                                *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software.                                              *
*                                                                                *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
****************************************************************************************/

#include <modules/globebrowsing/globes/renderableglobe.h>

#include <ghoul/misc/threadpool.h>

#include <modules/globebrowsing/tile/tileselector.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>

// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/scene/scenegraphnode.h>

#include <modules/debugging/rendering/debugrenderer.h>

// ghoul includes
#include <ghoul/misc/assert.h>

namespace {
    const std::string _loggerCat = "RenderableGlobe";

    // Keys for the dictionary
    const std::string keyFrame = "Frame";
    const std::string keyRadii = "Radii";
    const std::string keyInteractionDepthBelowEllipsoid =
        "InteractionDepthBelowEllipsoid";
    const std::string keyCameraMinHeight = "CameraMinHeight";
    const std::string keySegmentsPerPatch = "SegmentsPerPatch";
    const std::string keyTextures = "Textures";
    const std::string keyColorTextures = "ColorTextures";
    const std::string keyHeightMaps = "HeightMaps";
}

namespace openspace {
namespace globebrowsing {

    SingleTexturePropertyOwner::SingleTexturePropertyOwner(std::string name)
    : isEnabled("isEnabled", "isEnabled", true) {
        setName(name);
        addProperty(isEnabled);
    }

    SingleTexturePropertyOwner::~SingleTexturePropertyOwner() {

    }

    LayeredCategoryPropertyOwner::LayeredCategoryPropertyOwner(
        LayeredTextures::TextureCategory category,
        TileProviderManager& tileProviderManager)
    : _tileProviderManager(tileProviderManager)
    , _levelBlendingEnabled("blendTileLevels", "blend tile levels", true){
        setName(LayeredTextures::TEXTURE_CATEGORY_NAMES[category]);

        // Create the property owners
        auto& layerGroup = _tileProviderManager.getTileProviderGroup(category);
        for (NamedTileProvider& tileProvider : layerGroup.tileProviders) {
            _texturePropertyOwners.push_back(
                std::make_unique<SingleTexturePropertyOwner>(tileProvider.name));
        }

        // Specify and add the property owners
        for (int i = 0; i < layerGroup.tileProviders.size(); i++) {
            NamedTileProvider &tileProvider = layerGroup.tileProviders[i];
            SingleTexturePropertyOwner &prop = *_texturePropertyOwners[i].get();
            prop.isEnabled.set(tileProvider.isActive);
            prop.isEnabled.onChange([&]{
                tileProvider.isActive = prop.isEnabled;
            });

            for (auto setting : tileProvider.settings.array()) {
                prop.addProperty(setting->property());
            }

            addPropertySubOwner(prop);
        }

        _levelBlendingEnabled.set(layerGroup.levelBlendingEnabled);
        _levelBlendingEnabled.onChange([&]{
            layerGroup.levelBlendingEnabled = _levelBlendingEnabled;
        });
        addProperty(_levelBlendingEnabled);
    }

    LayeredCategoryPropertyOwner::~LayeredCategoryPropertyOwner() {

    }

    RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
    : _generalProperties({
        properties::BoolProperty("enabled", "Enabled", true),
        properties::BoolProperty("performShading", "perform shading", true),
        properties::BoolProperty("atmosphere", "atmosphere", false),
        properties::FloatProperty("lodScaleFactor", "lodScaleFactor",10.0f, 1.0f, 50.0f),
        properties::FloatProperty(
            "cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)
    })
    , _debugProperties({
        properties::BoolProperty("saveOrThrowCamera", "save or throw camera", false),
        properties::BoolProperty("showChunkEdges", "show chunk edges", false),
        properties::BoolProperty("showChunkBounds", "show chunk bounds", false),
        properties::BoolProperty("showChunkAABB", "show chunk AABB", false),
    	properties::BoolProperty("showHeightResolution", "show height resolution", false),
        properties::BoolProperty(
            "showHeightIntensities", "show height intensities", false),
        properties::BoolProperty(
            "performFrustumCulling", "perform frustum culling", true),
        properties::BoolProperty(
            "performHorizonCulling", "perform horizon culling", true),
        properties::BoolProperty(
            "levelByProjectedAreaElseDistance", "level by projected area (else distance)",
            false),
        properties::BoolProperty("resetTileProviders", "reset tile providers", false),
        properties::BoolProperty(
            "toggleEnabledEveryFrame", "toggle enabled every frame", false)})
    {
        setName("RenderableGlobe");

        dictionary.getValue(keyFrame, _frame);

        // Read the radii in to its own dictionary
        Vec3 radii;
        dictionary.getValue(keyRadii, radii);
        _ellipsoid = Ellipsoid(radii);
        setBoundingSphere(pss(_ellipsoid.averageRadius(), 0.0));

        // Ghoul can't read ints from lua dictionaries...
        double patchSegmentsd;
        dictionary.getValue(keySegmentsPerPatch, patchSegmentsd);
        int patchSegments = patchSegmentsd;

        dictionary.getValue(keyInteractionDepthBelowEllipsoid,
            _interactionDepthBelowEllipsoid);
        float cameraMinHeight;
        dictionary.getValue(keyCameraMinHeight, cameraMinHeight);
        _generalProperties.cameraMinHeight.set(cameraMinHeight);

        // Init tile provider manager
        ghoul::Dictionary texturesDictionary;
        dictionary.getValue(keyTextures, texturesDictionary);

        _tileProviderManager = std::make_shared<TileProviderManager>(texturesDictionary);

        _chunkedLodGlobe = std::make_shared<ChunkedLodGlobe>(
            *this, patchSegments, _tileProviderManager);
        _pointGlobe = std::make_shared<PointGlobe>(*this);

        _distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e9);
        _distanceSwitch.addSwitchValue(_pointGlobe, 1e12);

        _debugPropertyOwner.setName("Debug");
        _texturePropertyOwner.setName("Textures");

        addProperty(_generalProperties.isEnabled);
        addProperty(_generalProperties.atmosphereEnabled);
        addProperty(_generalProperties.performShading);
        addProperty(_generalProperties.lodScaleFactor);
        addProperty(_generalProperties.cameraMinHeight);

        _debugPropertyOwner.addProperty(_debugProperties.saveOrThrowCamera);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkBounds);
        _debugPropertyOwner.addProperty(_debugProperties.showChunkAABB);
        _debugPropertyOwner.addProperty(_debugProperties.showHeightResolution);
        _debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities);
        _debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling);
        _debugPropertyOwner.addProperty(_debugProperties.performHorizonCulling);
        _debugPropertyOwner.addProperty(
            _debugProperties.levelByProjectedAreaElseDistance);
        _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
        //_debugPropertyOwner.addProperty(_debugProperties.toggleEnabledEveryFrame);

        for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++) {
            _textureProperties.push_back(std::make_unique<LayeredCategoryPropertyOwner>
                (LayeredTextures::TextureCategory(i), *_tileProviderManager));
            _texturePropertyOwner.addPropertySubOwner(*_textureProperties[i]);
        }

        addPropertySubOwner(_debugPropertyOwner);
        addPropertySubOwner(_texturePropertyOwner);
    }

    RenderableGlobe::~RenderableGlobe() {

    }

    bool RenderableGlobe::initialize() {
        return _distanceSwitch.initialize();
    }

    bool RenderableGlobe::deinitialize() {
        return _distanceSwitch.deinitialize();
    }

    bool RenderableGlobe::isReady() const {
        return _distanceSwitch.isReady();
    }

    void RenderableGlobe::render(const RenderData& data) {
        if (_debugProperties.toggleEnabledEveryFrame.value()) {
            _generalProperties.isEnabled.setValue(
                !_generalProperties.isEnabled.value());
        }
        if (_generalProperties.isEnabled.value()) {
            if (_debugProperties.saveOrThrowCamera.value()) {
                _debugProperties.saveOrThrowCamera.setValue(false);

                if (savedCamera() == nullptr) { // save camera
                    LDEBUG("Saving snapshot of camera!");
                    setSaveCamera(std::make_shared<Camera>(data.camera));
                }
                else { // throw camera
                    LDEBUG("Throwing away saved camera!");
                    setSaveCamera(nullptr);
                }
            }
            _distanceSwitch.render(data);
        }
        if (_savedCamera != nullptr) {
            DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera);
        }
    }

    void RenderableGlobe::update(const UpdateData& data) {
        _time = data.time;
        _distanceSwitch.update(data);

        glm::dmat4 translation =
            glm::translate(glm::dmat4(1.0), data.modelTransform.translation);
        glm::dmat4 rotation = glm::dmat4(data.modelTransform.rotation);
        glm::dmat4 scaling =
            glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale,
                data.modelTransform.scale, data.modelTransform.scale));

        _cachedModelTransform = translation * rotation * scaling;
        _cachedInverseModelTransform = glm::inverse(_cachedModelTransform);

        if (_debugProperties.resetTileProviders) {
            _tileProviderManager->reset();
            _debugProperties.resetTileProviders = false;
        }
        _tileProviderManager->update();
        _chunkedLodGlobe->update(data);
    }

    glm::dvec3 RenderableGlobe::projectOnEllipsoid(glm::dvec3 position) {
        return _ellipsoid.geodeticSurfaceProjection(position);
    }

    float RenderableGlobe::getHeight(glm::dvec3 position) {
        // Get the tile provider for the height map
        const auto& heightMapProviders = _tileProviderManager->getTileProviderGroup(
            LayeredTextures::HeightMaps).getActiveTileProviders();
        if (heightMapProviders.size() == 0)
            return 0;
        const auto& tileProvider = heightMapProviders[0];

        // Get the uv coordinates to sample from
        Geodetic2 geodeticPosition = _ellipsoid.cartesianToGeodetic2(position);
        int chunkLevel = _chunkedLodGlobe->findChunkNode(
            geodeticPosition).getChunk().tileIndex().level;

        TileIndex chunkIdx = TileIndex(geodeticPosition, chunkLevel);
        GeodeticPatch patch = GeodeticPatch(chunkIdx);
        Geodetic2 geoDiffPatch =
            patch.getCorner(Quad::NORTH_EAST) -
            patch.getCorner(Quad::SOUTH_WEST);
        Geodetic2 geoDiffPoint = geodeticPosition - patch.getCorner(Quad::SOUTH_WEST);
        glm::vec2 patchUV = glm::vec2(
            geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat);

        // Transform the uv coordinates to the current tile texture
        TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(
            tileProvider.get(), chunkIdx);
        const auto& tile = tileAndTransform.tile;
        const auto& uvTransform = tileAndTransform.uvTransform;
        const auto& depthTransform = tileProvider->depthTransform();
        if (tile.status != Tile::Status::OK) {
            return 0;
        }
        //glm::vec2 transformedUv = uvTransform.uvOffset + uvTransform.uvScale * patchUV;

        glm::vec2 transformedUv = Tile::TileUvToTextureSamplePosition(
            uvTransform,
            patchUV,
            glm::uvec2(tile.texture->dimensions()));

        // Sample and do linear interpolation
        // (could possibly be moved as a function in ghoul texture)
        glm::uvec3 dimensions = tile.texture->dimensions();

        glm::vec2 samplePos = transformedUv * glm::vec2(dimensions);
        glm::uvec2 samplePos00 = samplePos;
        samplePos00 = glm::clamp(
            samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00);

        glm::uvec2 samplePos10 = glm::min(
            samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::uvec2 samplePos01 = glm::min(
            samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1));
        glm::uvec2 samplePos11 = glm::min(
            samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1));

        float sample00 = tile.texture->texelAsFloat(samplePos00).x;
        float sample10 = tile.texture->texelAsFloat(samplePos10).x;
        float sample01 = tile.texture->texelAsFloat(samplePos01).x;
        float sample11 = tile.texture->texelAsFloat(samplePos11).x;

        float sample0 = sample00 * (1.0 - samplePosFract.x) + sample10 * samplePosFract.x;
        float sample1 = sample01 * (1.0 - samplePosFract.x) + sample11 * samplePosFract.x;

        float sample = sample0 * (1.0 - samplePosFract.y) + sample1 * samplePosFract.y;

        // Perform depth transform to get the value in meters
        float height = depthTransform.depthOffset + depthTransform.depthScale * sample;

        // Return the result
        return height;
    }

    std::shared_ptr<ChunkedLodGlobe> RenderableGlobe::chunkedLodGlobe() const{
        return _chunkedLodGlobe;
    }

    const Ellipsoid& RenderableGlobe::ellipsoid() const{
        return _ellipsoid;
    }

    const glm::dmat4& RenderableGlobe::modelTransform() const{
        return _cachedModelTransform;
    }

    const glm::dmat4& RenderableGlobe::inverseModelTransform() const{
        return _cachedInverseModelTransform;
    }

    const RenderableGlobe::DebugProperties&
        RenderableGlobe::debugProperties() const{
        return _debugProperties;
    }

    const RenderableGlobe::GeneralProperties&
        RenderableGlobe::generalProperties() const{
        return _generalProperties;
    }

    const std::shared_ptr<const Camera> RenderableGlobe::savedCamera() const {
        return _savedCamera;
    }

    double RenderableGlobe::interactionDepthBelowEllipsoid() {
        return _interactionDepthBelowEllipsoid;
    }

    void RenderableGlobe::setSaveCamera(std::shared_ptr<Camera> camera) {
        _savedCamera = camera;
    }
} // namespace globebrowsing
} // namespace openspace

<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkIOCommon.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkIOCommon.h"
#include <sys/stat.h>

#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
#include <string.h>
#include <windows.h>
#include <direct.h>
#define _unlink unlink
#else
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#endif

namespace itk
{
  // CODE STOLEN STRAIGHT FROM CMAKE
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
inline int Mkdir(const char* dir)
{
  return _mkdir(dir);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return _getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  #if defined(__BORLANDC__)
  return chdir(dir);
  #else
  return _chdir(dir);
  #endif
}
#else
inline int Mkdir(const char* dir)
{
  return mkdir(dir, 00777);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  return chdir(dir);
}
#endif

::std::string IOCommon
::AtomicPixelTypeToString(const AtomicPixelType pixelType)
{
  switch(pixelType)
    {
    case ITK_UCHAR:
      return "unsigned char";
      break;
    case ITK_CHAR:
      return "char";
      break;
    case ITK_USHORT:
      return "unsigned short";
      break;
    case ITK_SHORT:
      return "short";
      break;
    case ITK_UINT:
      return "unsigned int";
      break;
    case ITK_INT:
      return "int";
      break;
    case ITK_ULONG:
      return "unsigned long";
      break;
    case ITK_LONG:
      return "long";
      break;
    case ITK_FLOAT:
      return "float";
      break;
    case ITK_DOUBLE:
      return "double";
      break;
    default:
      return "unknown";
      break;
    }
}

unsigned int IOCommon
::ComputeSizeOfAtomicPixelType(const AtomicPixelType pixelType)
{
  switch (pixelType)
    {
    case ITK_CHAR:
      return sizeof(char);
      break;
    case ITK_UCHAR:
      return sizeof(unsigned char);
      break;
    case ITK_SHORT:
      return sizeof(short);
      break;
    case ITK_USHORT:
      return sizeof(unsigned short);
      break;
    case ITK_INT:
      return sizeof(int);
      break;
    case ITK_UINT:
      return sizeof(unsigned int);
      break;
    case ITK_LONG:
      return sizeof(long);
      break;
    case ITK_ULONG:
      return sizeof(unsigned long);
      break;
    case ITK_FLOAT:
      return sizeof(float);
      break;
    case ITK_DOUBLE:
      return sizeof(double);
      break;
    default:
      return sizeof(char);
      break;
    }
}

int IOCommon
::Strucmp(const char *s1, const char *s2)
{
  char* s1_up = new char[strlen(s1)+1];
  char* s2_up = new char[strlen(s2)+1];
  int i;

  strcpy(s1_up, s1);
  strcpy(s2_up, s2);

  for (i = 0; s1_up[i]; i++)
    {
    s1_up[i] = islower(s1_up[i]) ? toupper(s1_up[i]) : s1_up[i];
    }
  for (i = 0; s2_up[i]; i++)
    {
    s2_up[i] = islower(s2_up[i]) ? toupper(s2_up[i]) : s2_up[i];
    }
  int rc = strcmp(s1_up, s2_up);
  delete [] s1_up;
  delete [] s2_up;
  return rc;
}

char* IOCommon
::ExtractFileName (const char* fileName)
{
  const char* dot;
  const char* slash;
  char* fName = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      slash = (const char*) fileName;
      }
    else
      {
      slash++;
      }
    dot = strrchr(fileName, '.');
    if (dot == NULL)
      {
      dot = (const char*) fileName + strlen(fileName);
      }
    fName = new char[strlen(slash) - strlen(dot) + 1];
    strncpy(fName, slash, strlen(slash) - strlen(dot));
    fName[strlen(slash) - strlen(dot)] = '\0';
  }

  return fName;
}

char* IOCommon
::ExtractFileExtension (const char* fileName)
{
  const char* dot;
  char* fExtension = NULL;

  dot = strrchr(fileName, '.');
  if (dot != NULL)
    {
    dot++;
    fExtension = new char[strlen(dot)+1];
    strcpy(fExtension, dot);
    fExtension[strlen(dot)] = '\0';
    }

  return fExtension;
}

char* IOCommon
::ExtractFilePath (const char* fileName)
{
  const char* slash;
  char* fPath = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      fPath = NULL;
      }
    else
      {
      slash++;
      fPath = new char[strlen(fileName) - strlen(slash) + 1];
      strncpy(fPath, fileName, strlen(fileName) - strlen(slash));
      fPath[strlen(fileName) - strlen(slash)] = '\0';
      }
    }

  return fPath;
}

// return true if the file exists
bool IOCommon
::FileExists(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
    return false;
    }
  else
    {
    return true;
    }
}
// return size of file; also returns zero if no file exists
unsigned long IOCommon
::FileLength(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
      return 0;
    }
  else
    {
      return fs.st_size;
    }
}

char *IOCommon
::RealPath(const char *path, char *resolved_path)
{
#if defined(_WIN32)
<<<<<<< itkIOCommon.cxx
  char pathpart[itk::IOCommon::ITK_MAXPATHLEN];
  std::strcpy(pathpart,path);
  char fnamepart[itk::IOCommon::ITK_MAXPATHLEN];
=======
  char pathpart[MAXPATHLEN];
  strcpy(pathpart,path);
  char fnamepart[MAXPATHLEN];
>>>>>>> 1.5
  char *slash;

  if((slash = strrchr(pathpart,'/')) == NULL)
    {
      slash = strrchr(pathpart,'\\');
    }

  if(slash == NULL) // no path part, so just use current dir.
    {
      Getcwd(pathpart,sizeof(pathpart));
      strcpy(fnamepart,path);
    }
  else // change directory to path part, getcwd to find OS resolved path
    {
      *slash = '\0';
      strcpy(fnamepart,slash+1);

      char savedir[itk::IOCommon::ITK_MAXPATHLEN];
      Getcwd(savedir,sizeof(savedir));
      Chdir(pathpart);
      Getcwd(pathpart,sizeof(pathpart));
      Chdir(savedir);
    }
  strcpy(resolved_path,pathpart);
  strcat(resolved_path,"/");
  strcat(resolved_path,fnamepart);
  return resolved_path;
#else
  return realpath(path,resolved_path);
#endif
}

} // namespace itk
<commit_msg>ERR: removed conflict.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkIOCommon.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkIOCommon.h"
#include <sys/stat.h>

#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
#include <string.h>
#include <windows.h>
#include <direct.h>
#define _unlink unlink
#else
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#endif

namespace itk
{
  // CODE STOLEN STRAIGHT FROM CMAKE
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
inline int Mkdir(const char* dir)
{
  return _mkdir(dir);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return _getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  #if defined(__BORLANDC__)
  return chdir(dir);
  #else
  return _chdir(dir);
  #endif
}
#else
inline int Mkdir(const char* dir)
{
  return mkdir(dir, 00777);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  return chdir(dir);
}
#endif

std::string IOCommon
::AtomicPixelTypeToString(const AtomicPixelType pixelType)
{
  switch(pixelType)
    {
    case ITK_UCHAR:
      return "unsigned char";
      break;
    case ITK_CHAR:
      return "char";
      break;
    case ITK_USHORT:
      return "unsigned short";
      break;
    case ITK_SHORT:
      return "short";
      break;
    case ITK_UINT:
      return "unsigned int";
      break;
    case ITK_INT:
      return "int";
      break;
    case ITK_ULONG:
      return "unsigned long";
      break;
    case ITK_LONG:
      return "long";
      break;
    case ITK_FLOAT:
      return "float";
      break;
    case ITK_DOUBLE:
      return "double";
      break;
    default:
      return "unknown";
      break;
    }
}

unsigned int IOCommon
::ComputeSizeOfAtomicPixelType(const AtomicPixelType pixelType)
{
  switch (pixelType)
    {
    case ITK_CHAR:
      return sizeof(char);
      break;
    case ITK_UCHAR:
      return sizeof(unsigned char);
      break;
    case ITK_SHORT:
      return sizeof(short);
      break;
    case ITK_USHORT:
      return sizeof(unsigned short);
      break;
    case ITK_INT:
      return sizeof(int);
      break;
    case ITK_UINT:
      return sizeof(unsigned int);
      break;
    case ITK_LONG:
      return sizeof(long);
      break;
    case ITK_ULONG:
      return sizeof(unsigned long);
      break;
    case ITK_FLOAT:
      return sizeof(float);
      break;
    case ITK_DOUBLE:
      return sizeof(double);
      break;
    default:
      return sizeof(char);
      break;
    }
}

int IOCommon
::Strucmp(const char *s1, const char *s2)
{
  char* s1_up = new char[strlen(s1)+1];
  char* s2_up = new char[strlen(s2)+1];
  int i;

  strcpy(s1_up, s1);
  strcpy(s2_up, s2);

  for (i = 0; s1_up[i]; i++)
    {
    s1_up[i] = islower(s1_up[i]) ? toupper(s1_up[i]) : s1_up[i];
    }
  for (i = 0; s2_up[i]; i++)
    {
    s2_up[i] = islower(s2_up[i]) ? toupper(s2_up[i]) : s2_up[i];
    }
  int rc = strcmp(s1_up, s2_up);
  delete [] s1_up;
  delete [] s2_up;
  return rc;
}

char* IOCommon
::ExtractFileName (const char* fileName)
{
  const char* dot;
  const char* slash;
  char* fName = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      slash = (const char*) fileName;
      }
    else
      {
      slash++;
      }
    dot = strrchr(fileName, '.');
    if (dot == NULL)
      {
      dot = (const char*) fileName + strlen(fileName);
      }
    fName = new char[strlen(slash) - strlen(dot) + 1];
    strncpy(fName, slash, strlen(slash) - strlen(dot));
    fName[strlen(slash) - strlen(dot)] = '\0';
  }

  return fName;
}

char* IOCommon
::ExtractFileExtension (const char* fileName)
{
  const char* dot;
  char* fExtension = NULL;

  dot = strrchr(fileName, '.');
  if (dot != NULL)
    {
    dot++;
    fExtension = new char[strlen(dot)+1];
    strcpy(fExtension, dot);
    fExtension[strlen(dot)] = '\0';
    }

  return fExtension;
}

char* IOCommon
::ExtractFilePath (const char* fileName)
{
  const char* slash;
  char* fPath = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      fPath = NULL;
      }
    else
      {
      slash++;
      fPath = new char[strlen(fileName) - strlen(slash) + 1];
      strncpy(fPath, fileName, strlen(fileName) - strlen(slash));
      fPath[strlen(fileName) - strlen(slash)] = '\0';
      }
    }

  return fPath;
}

// return true if the file exists
bool IOCommon
::FileExists(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
    return false;
    }
  else
    {
    return true;
    }
}
// return size of file; also returns zero if no file exists
unsigned long IOCommon
::FileLength(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
      return 0;
    }
  else
    {
      return fs.st_size;
    }
}

char *IOCommon
::RealPath(const char *path, char *resolved_path)
{
#if defined(_WIN32)
  char pathpart[itk::IOCommon::ITK_MAXPATHLEN];
  strcpy(pathpart,path);
  char fnamepart[itk::IOCommon::ITK_MAXPATHLEN];
  char *slash;

  if((slash = strrchr(pathpart,'/')) == NULL)
    {
      slash = strrchr(pathpart,'\\');
    }

  if(slash == NULL) // no path part, so just use current dir.
    {
      Getcwd(pathpart,sizeof(pathpart));
      strcpy(fnamepart,path);
    }
  else // change directory to path part, getcwd to find OS resolved path
    {
      *slash = '\0';
      strcpy(fnamepart,slash+1);

      char savedir[itk::IOCommon::ITK_MAXPATHLEN];
      Getcwd(savedir,sizeof(savedir));
      Chdir(pathpart);
      Getcwd(pathpart,sizeof(pathpart));
      Chdir(savedir);
    }
  strcpy(resolved_path,pathpart);
  strcat(resolved_path,"/");
  strcat(resolved_path,fnamepart);
  return resolved_path;
#else
  return realpath(path,resolved_path);
#endif
}

} // namespace itk
<|endoftext|>


<commit_before>#include "keyboard_reader/Key.h"
#include "map"
#include "ros/ros.h"
#include "std_msgs/String.h"

class fake_voice_commander
{
public:
    ros::NodeHandle n;
    ros::Publisher voiceCommandPublisher;
    ros::Subscriber sub_kb_event;
    std_msgs::String voiceCommand;
    bool publish = false;

    fake_voice_commander()
    {
        // Setup ROS publishers
        voiceCommandPublisher = n.advertise<std_msgs::String>("stt/spoken_text", 2);

        // Setup ROS subscribers
        sub_kb_event = n.subscribe<keyboard_reader::Key>("keyboard", 1, &fake_voice_commander::keyboardCallback, this);
    }

    // Process keypresses
    void keyboardCallback(keyboard_reader::Key kbCommand)
    {
        if (kbCommand.key_pressed == true)
        {

            // Run xmodmap -pk to display these

            // Plan trajecory: "l" key
            if (kbCommand.key_code == 0x0026 )
            {
                voiceCommand.data = "robot please plan";
                publish = true;
            }

            // Execute trajectory: "e" key
            else if (kbCommand.key_code == 0x0012)
            {
                voiceCommand.data = "robot please execute";
                publish = true;
            }

            // Manipulation: "m" key
            else if (kbCommand.key_code == 0x0032)
            {
                voiceCommand.data = "manipulation";
                publish = true;
            }

            // Navigation: "n" key
            else if (kbCommand.key_code == 0x0031)
            {
                voiceCommand.data = "navigation";
                publish = true;
            }

            // Robot please go: "g" key
            else if (kbCommand.key_code == 0x0067)
            {
                voiceCommand.data = "robot please go";
                publish = true;
            }

            // Open gripper: "o" key
            else if (kbCommand.key_code == 0x0018)
            {
                voiceCommand.data = "open gripper";
                publish = true;
            }

            // Open gripper: "c" key
            else if (kbCommand.key_code == 0x002e)
            {
                voiceCommand.data = "close gripper";
                publish = true;
            }

            // Start joggign: "j" key
            else if (kbCommand.key_code == 0x0024)
            {
                voiceCommand.data = "jog mode";
                publish = true;
            }

            // Stop joggign: "s" key
            else if (kbCommand.key_code == 0x001f)
            {
                voiceCommand.data = "stop jogging";
                publish = true;
            }

            if (publish)
            {
                ROS_INFO("[fake voice commander] Publishing: %s", voiceCommand.data.c_str());
                voiceCommandPublisher.publish(voiceCommand);
                publish = false;
            }
        }
    }
};

int main(int argc, char **argv)
{
    ros::init(argc, argv, "fake_voice_commander");

    std::cout << std::endl << "* * * List of commands: * * *" << std::endl;
    std::cout << "* l - robot please plan" << std::endl;
    std::cout << "* e - robot please execute" << std::endl;
    //std::cout << "* l - limit directions" << std::endl;
    std::cout << "* f - free directions" << std::endl;
    std::cout << "* x - ignore rotation" << std::endl;
    std::cout << "* r - consider rotation" << std::endl;
    std::cout << "* m - manipulation" << std::endl;
    std::cout << "* n - navigation" << std::endl;
    std::cout << "* o - open gripper" << std::endl;
    std::cout << "* c - close gripper" << std::endl;
    std::cout << "* * * * * * *" << std::endl << std::endl;

    ROS_INFO("Fake voice commander up and running");
    fake_voice_commander fakeVoiceCommander;

    ros::spin();

    return 0;
} // end main
<commit_msg>Eliminating a bunch of junk from kb_fake_voice_commander.cpp<commit_after>#include "keyboard_reader/Key.h"
#include "map"
#include "ros/ros.h"
#include "std_msgs/String.h"

class fake_voice_commander
{
public:
    ros::NodeHandle n;
    ros::Publisher voiceCommandPublisher;
    ros::Subscriber sub_kb_event;
    std_msgs::String voiceCommand;
    bool publish = false;

    fake_voice_commander()
    {
        // Setup ROS publishers
        voiceCommandPublisher = n.advertise<std_msgs::String>("stt/spoken_text", 2);

        // Setup ROS subscribers
        sub_kb_event = n.subscribe<keyboard_reader::Key>("keyboard", 1, &fake_voice_commander::keyboardCallback, this);
    }

    // Process keypresses
    void keyboardCallback(keyboard_reader::Key kbCommand)
    {
        if (kbCommand.key_pressed == true)
        {

            // Run xmodmap -pk to display these

            // Plan trajecory: "l" key
            if (kbCommand.key_code == 0x0026 )
                voiceCommand.data = "robot please plan";

            // Execute trajectory: "e" key
            else if (kbCommand.key_code == 0x0012)
                voiceCommand.data = "robot please execute";

            // Manipulation: "m" key
            else if (kbCommand.key_code == 0x0032)
                voiceCommand.data = "manipulation";

            // Navigation: "n" key
            else if (kbCommand.key_code == 0x0031)
                voiceCommand.data = "navigation";

            // Robot please go: "g" key
            else if (kbCommand.key_code == 0x0067)
                voiceCommand.data = "robot please go";

            // Open gripper: "o" key
            else if (kbCommand.key_code == 0x0018)
                voiceCommand.data = "open gripper";

            // Open gripper: "c" key
            else if (kbCommand.key_code == 0x002e)
                voiceCommand.data = "close gripper";

            // Start jogging: "j" key
            else if (kbCommand.key_code == 0x0024)
                voiceCommand.data = "jog mode";

            // Stop joggign: "s" key
            else if (kbCommand.key_code == 0x001f)
                voiceCommand.data = "stop jogging";

            else
                voiceCommand.data = "unrecognized command";

            ROS_INFO("[fake voice commander] Publishing: %s", voiceCommand.data.c_str());
            voiceCommandPublisher.publish(voiceCommand);
        }
    }
};

int main(int argc, char **argv)
{
    ros::init(argc, argv, "fake_voice_commander");

    std::cout << std::endl << "* * * List of commands: * * *" << std::endl;
    std::cout << "* l - robot please plan" << std::endl;
    std::cout << "* e - robot please execute" << std::endl;
    //std::cout << "* l - limit directions" << std::endl;
    std::cout << "* f - free directions" << std::endl;
    std::cout << "* x - ignore rotation" << std::endl;
    std::cout << "* r - consider rotation" << std::endl;
    std::cout << "* m - manipulation" << std::endl;
    std::cout << "* n - navigation" << std::endl;
    std::cout << "* o - open gripper" << std::endl;
    std::cout << "* c - close gripper" << std::endl;
    std::cout << "* * * * * * *" << std::endl << std::endl;

    ROS_INFO("Fake voice commander up and running");
    fake_voice_commander fakeVoiceCommander;

    ros::spin();

    return 0;
} // end main
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>

#include "w5100.h"

// W5100 controller instance
W5100Class W5100;

#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)

#define TXBUF_BASE 0x4000
#define RXBUF_BASE 0x6000

void W5100Class::init(void)
{
  writeMR(1<<RST);
  writeTMSR(0x55);
  writeRMSR(0x55);

  for (int i=0; i<MAX_SOCK_NUM; i++) {
    SBASE[i] = TXBUF_BASE + SSIZE * i;
    RBASE[i] = RXBUF_BASE + RSIZE * i;
  }
}

uint16_t W5100Class::getTXFreeSize(SOCKET s)
{
  uint16_t val=0, val1=0;
  do {
    val1 = readSnTX_FSR(s);
    if (val1 != 0)
      val = readSnTX_FSR(s);
  }
  while (val != val1);
  return val;
}

uint16_t W5100Class::getRXReceivedSize(SOCKET s)
{
  uint16_t val=0,val1=0;
  do {
    val1 = readSnRX_RSR(s);
    if (val1 != 0)
      val = readSnRX_RSR(s);
  }
  while (val != val1);
  return val;
}

void W5100Class::send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
  uint16_t ptr = readSnTX_WR(s);

  uint16_t offset = ptr & SMASK;
  uint16_t dstAddr = offset + SBASE[s];

  if (offset + len > SSIZE)
  {
    // Wrap around circular buffer
    uint16_t size = SSIZE - offset;
    write(dstAddr, data, size);
    write(SBASE[s], data + size, len - size);
  }
  else {
    write(dstAddr, data, len);
  }

  ptr += len;
  writeSnTX_WR(s, ptr);
}

void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
  uint16_t ptr;
  ptr = readSnRX_RD(s);
  read_data(s, (uint8_t *)ptr, data, len);
  ptr += len;
  writeSnRX_RD(s, ptr);
}

void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
  uint16_t size;
  uint16_t src_mask;
  uint16_t src_ptr;

  src_mask = (uint16_t)src & RMASK;
  src_ptr = RBASE[s] + src_mask;

  if( (src_mask + len) > RSIZE )
  {
    size = RSIZE - src_mask;
    read(src_ptr, (uint8_t *)dst, size);
    dst += size;
    read(RBASE[s], (uint8_t *) dst, len - size);
  }
  else
    read(src_ptr, (uint8_t *) dst, len);
}

uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
  setSS();
  SPI.send(0xF0);
  SPI.send(_addr >> 8);
  SPI.send(_addr & 0xFF);
  SPI.send(_data);
  resetSS();
  return 1;
}

uint16_t W5100Class::write(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
  for (int i=0; i<_len; i++)
  {
    setSS();
    SPI.send(0xF0);
    SPI.send(_addr >> 8);
    SPI.send(_addr & 0xFF);
    _addr++;
    SPI.send(_buf[i]);
    resetSS();
  }
  return _len;
}

uint8_t W5100Class::read(uint16_t _addr)
{
  setSS();
  SPI.send(0x0F);
  SPI.send(_addr >> 8);
  SPI.send(_addr & 0xFF);
  uint8_t _data = SPI.send(0);
  resetSS();
  return _data;
}

uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
  for (int i=0; i<_len; i++)
  {
    setSS();
    SPI.send(0x0F);
    SPI.send(_addr >> 8);
    SPI.send(_addr & 0xFF);
    _addr++;
    _buf[i] = SPI.send(0);
    resetSS();
  }
  return _len;
}

void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
  // Send command to socket
  writeSnCR(s, _cmd);
  // Wait for command to complete
  while (readSnCR(s))
    ;
}
<commit_msg>Fixing ethernet library on Mega.<commit_after>/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>

#include "w5100.h"

// W5100 controller instance
W5100Class W5100;

#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)

#define TXBUF_BASE 0x4000
#define RXBUF_BASE 0x6000

void W5100Class::init(void)
{
  initSS();

  writeMR(1<<RST);
  writeTMSR(0x55);
  writeRMSR(0x55);

  for (int i=0; i<MAX_SOCK_NUM; i++) {
    SBASE[i] = TXBUF_BASE + SSIZE * i;
    RBASE[i] = RXBUF_BASE + RSIZE * i;
  }
}

uint16_t W5100Class::getTXFreeSize(SOCKET s)
{
  uint16_t val=0, val1=0;
  do {
    val1 = readSnTX_FSR(s);
    if (val1 != 0)
      val = readSnTX_FSR(s);
  }
  while (val != val1);
  return val;
}

uint16_t W5100Class::getRXReceivedSize(SOCKET s)
{
  uint16_t val=0,val1=0;
  do {
    val1 = readSnRX_RSR(s);
    if (val1 != 0)
      val = readSnRX_RSR(s);
  }
  while (val != val1);
  return val;
}

void W5100Class::send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
  uint16_t ptr = readSnTX_WR(s);

  uint16_t offset = ptr & SMASK;
  uint16_t dstAddr = offset + SBASE[s];

  if (offset + len > SSIZE)
  {
    // Wrap around circular buffer
    uint16_t size = SSIZE - offset;
    write(dstAddr, data, size);
    write(SBASE[s], data + size, len - size);
  }
  else {
    write(dstAddr, data, len);
  }

  ptr += len;
  writeSnTX_WR(s, ptr);
}

void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
  uint16_t ptr;
  ptr = readSnRX_RD(s);
  read_data(s, (uint8_t *)ptr, data, len);
  ptr += len;
  writeSnRX_RD(s, ptr);
}

void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
  uint16_t size;
  uint16_t src_mask;
  uint16_t src_ptr;

  src_mask = (uint16_t)src & RMASK;
  src_ptr = RBASE[s] + src_mask;

  if( (src_mask + len) > RSIZE )
  {
    size = RSIZE - src_mask;
    read(src_ptr, (uint8_t *)dst, size);
    dst += size;
    read(RBASE[s], (uint8_t *) dst, len - size);
  }
  else
    read(src_ptr, (uint8_t *) dst, len);
}

uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
  setSS();
  SPI.send(0xF0);
  SPI.send(_addr >> 8);
  SPI.send(_addr & 0xFF);
  SPI.send(_data);
  resetSS();
  return 1;
}

uint16_t W5100Class::write(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
  for (int i=0; i<_len; i++)
  {
    setSS();
    SPI.send(0xF0);
    SPI.send(_addr >> 8);
    SPI.send(_addr & 0xFF);
    _addr++;
    SPI.send(_buf[i]);
    resetSS();
  }
  return _len;
}

uint8_t W5100Class::read(uint16_t _addr)
{
  setSS();
  SPI.send(0x0F);
  SPI.send(_addr >> 8);
  SPI.send(_addr & 0xFF);
  uint8_t _data = SPI.send(0);
  resetSS();
  return _data;
}

uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
  for (int i=0; i<_len; i++)
  {
    setSS();
    SPI.send(0x0F);
    SPI.send(_addr >> 8);
    SPI.send(_addr & 0xFF);
    _addr++;
    _buf[i] = SPI.send(0);
    resetSS();
  }
  return _len;
}

void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
  // Send command to socket
  writeSnCR(s, _cmd);
  // Wait for command to complete
  while (readSnCR(s))
    ;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2011  Lasath Fernando <kde@lasath.org>
    Copyright (C) 2016  Martin Klapetek <mklapetek@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "conversation.h"
#include "messages-model.h"

#include <TelepathyQt/TextChannel>
#include <TelepathyQt/Account>
#include <TelepathyQt/PendingChannelRequest>
#include <TelepathyQt/PendingChannel>

#include "debug.h"

#include "channel-delegator.h"

class Conversation::ConversationPrivate
{
  public:
      ConversationPrivate()
      {
          messages = 0;
          delegated = false;
          valid = false;
          isGroupChat = false;
      }

    MessagesModel *messages;
    //stores if the conversation has been delegated to another client and we are only observing the channel
    //and not handling it.
    bool delegated;
    bool valid;
    Tp::AccountPtr account;
    QTimer *pausedStateTimer;
    // May be null for group chats.
    KTp::ContactPtr targetContact;
    bool isGroupChat;
};

Conversation::Conversation(const Tp::TextChannelPtr &channel,
                           const Tp::AccountPtr &account,
                           QObject *parent) :
        QObject(parent),
        d (new ConversationPrivate)
{
    qCDebug(KTP_DECLARATIVE);

    d->account = account;
    connect(d->account.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onAccountConnectionChanged(Tp::ConnectionPtr)));

    d->messages = new MessagesModel(account, this);
    connect(d->messages, &MessagesModel::unreadCountChanged, this, &Conversation::unreadMessagesChanged);
    setTextChannel(channel);

    d->delegated = false;

    d->pausedStateTimer = new QTimer(this);
    d->pausedStateTimer->setSingleShot(true);
    connect(d->pausedStateTimer, SIGNAL(timeout()), this, SLOT(onChatPausedTimerExpired()));
}

Conversation::Conversation(QObject *parent) : QObject(parent)
{
    qCCritical(KTP_DECLARATIVE) << "Conversation should not be created directly. Use ConversationWatcher instead.";
}

void Conversation::setTextChannel(const Tp::TextChannelPtr& channel)
{
    if (!d->messages) {
        d->messages = new MessagesModel(d->account, this);
        connect(d->messages, &MessagesModel::unreadCountChanged, this, &Conversation::unreadMessagesChanged);
    }
    if (d->messages->textChannel() != channel) {
        d->messages->setTextChannel(channel);
        d->valid = channel->isValid();
        connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
                SLOT(onChannelInvalidated(Tp::DBusProxy*,QString,QString)));

        if (channel->targetContact().isNull()) {
            d->isGroupChat = true;
        } else {
            d->isGroupChat = false;
            d->targetContact = KTp::ContactPtr::qObjectCast(channel->targetContact());

            connect(d->targetContact.constData(), SIGNAL(aliasChanged(QString)), SIGNAL(titleChanged()));
            connect(d->targetContact.constData(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(presenceIconChanged()));
            connect(d->targetContact.constData(), SIGNAL(avatarDataChanged(Tp::AvatarData)), SIGNAL(avatarChanged()));
        }

        Q_EMIT avatarChanged();
        Q_EMIT titleChanged();
        Q_EMIT presenceIconChanged();
        Q_EMIT validityChanged(d->valid);
    }
}

Tp::TextChannelPtr Conversation::textChannel() const
{
    return d->messages->textChannel();
}

MessagesModel* Conversation::messages() const
{
    return d->messages;
}

QString Conversation::title() const
{
    if (d->isGroupChat) {
        QString roomName = textChannel()->targetId();
        return roomName.left(roomName.indexOf(QLatin1Char('@')));
    } else if (!d->targetContact.isNull()) {
        return d->targetContact->alias();
    }

    return QString();
}

QIcon Conversation::presenceIcon() const
{
    if (d->isGroupChat) {
        return KTp::Presence(Tp::Presence::available()).icon();
    } else if (!d->targetContact.isNull()) {
        return KTp::Presence(d->targetContact->presence()).icon();
    }

    return QIcon();
}

QIcon Conversation::avatar() const
{
    if (d->isGroupChat) {
        return QIcon();
    } else {
        const QString path = d->targetContact->avatarData().fileName;
        QIcon icon;
        if (!path.isEmpty()) {
            icon = QIcon(path);
        }
        if (icon.availableSizes().isEmpty()) {
            icon = QIcon::fromTheme(QStringLiteral("im-user"));
        }
        return icon;
    }
}

KTp::ContactPtr Conversation::targetContact() const {
    if (d->isGroupChat) {
        return KTp::ContactPtr();
    } else {
        return d->targetContact;
    }
}

Tp::AccountPtr Conversation::account() const {
    return d->account;
}

bool Conversation::isValid() const
{
    return d->valid;
}

void Conversation::onChannelInvalidated(Tp::DBusProxy *proxy, const QString &errorName, const QString &errorMessage)
{
    qCDebug(KTP_DECLARATIVE) << proxy << errorName << ":" << errorMessage;

    d->valid = false;

    Q_EMIT validityChanged(d->valid);
}

void Conversation::onAccountConnectionChanged(const Tp::ConnectionPtr& connection)
{
    //if we have reconnected and we were handling the channel
    if (connection && ! d->delegated) {

        //general convention is to never use ensureAndHandle when we already have a client registrar
        //ensureAndHandle will implicity create a new temporary client registrar which is a waste
        //it's also more code to get the new channel

        //However, we cannot use use ensureChannel as normal because without being able to pass a preferredHandler
        //we need a preferredHandler so that this handler is the one that ends up with the channel if multi handlers are active
        //we do not know the name that this handler is currently registered with
        Tp::PendingChannel *pendingChannel = d->account->ensureAndHandleTextChat(textChannel()->targetId());
        connect(pendingChannel, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onCreateChannelFinished(Tp::PendingOperation*)));
    }
}

void Conversation::onCreateChannelFinished(Tp::PendingOperation* op)
{
    Tp::PendingChannel *pendingChannelOp = qobject_cast<Tp::PendingChannel*>(op);
    Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(pendingChannelOp->channel());
    if (textChannel) {
        setTextChannel(textChannel);
    }
}

void Conversation::delegateToProperClient()
{
    ChannelDelegator::delegateChannel(d->account, d->messages->textChannel());
    d->delegated = true;
    Q_EMIT conversationCloseRequested();
}

void Conversation::requestClose()
{
    qCDebug(KTP_DECLARATIVE);

    //removing from the model will delete this object closing the channel
    Q_EMIT conversationCloseRequested();
}

void Conversation::updateTextChanged(const QString &message)
{
    if (!message.isEmpty()) {
        //if the timer is active, it means the user is continuously typing
        if (d->pausedStateTimer->isActive()) {
            //just restart the timer and don't spam with chat state changes
            d->pausedStateTimer->start(5000);
        } else {
            //if the user has just typed some text, set state to Composing and start the timer
            d->messages->textChannel()->requestChatState(Tp::ChannelChatStateComposing);
            d->pausedStateTimer->start(5000);
        }
    } else {
        //if the user typed no text/cleared the input field, set Active and stop the timer
        d->messages->textChannel()->requestChatState(Tp::ChannelChatStateActive);
        d->pausedStateTimer->stop();
    }
}

void Conversation::onChatPausedTimerExpired()
{
    d->messages->textChannel()->requestChatState(Tp::ChannelChatStatePaused);
}

Conversation::~Conversation()
{
    qCDebug(KTP_DECLARATIVE);
    //if we are not handling the channel do nothing.
    if (!d->delegated) {
        d->messages->textChannel()->requestClose();
    }
    delete d;
}

bool Conversation::hasUnreadMessages() const
{
    if (d->messages) {
        return d->messages->unreadCount() > 0;
    }

    return false;
}
<commit_msg>[declarative] Make sure the Private is constructed with 2nd ctor too<commit_after>/*
    Copyright (C) 2011  Lasath Fernando <kde@lasath.org>
    Copyright (C) 2016  Martin Klapetek <mklapetek@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "conversation.h"
#include "messages-model.h"

#include <TelepathyQt/TextChannel>
#include <TelepathyQt/Account>
#include <TelepathyQt/PendingChannelRequest>
#include <TelepathyQt/PendingChannel>

#include "debug.h"

#include "channel-delegator.h"

class Conversation::ConversationPrivate
{
  public:
      ConversationPrivate()
      {
          messages = 0;
          delegated = false;
          valid = false;
          isGroupChat = false;
      }

    MessagesModel *messages;
    //stores if the conversation has been delegated to another client and we are only observing the channel
    //and not handling it.
    bool delegated;
    bool valid;
    Tp::AccountPtr account;
    QTimer *pausedStateTimer;
    // May be null for group chats.
    KTp::ContactPtr targetContact;
    bool isGroupChat;
};

Conversation::Conversation(const Tp::TextChannelPtr &channel,
                           const Tp::AccountPtr &account,
                           QObject *parent) :
        QObject(parent),
        d (new ConversationPrivate)
{
    qCDebug(KTP_DECLARATIVE);

    d->account = account;
    connect(d->account.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onAccountConnectionChanged(Tp::ConnectionPtr)));

    d->messages = new MessagesModel(account, this);
    connect(d->messages, &MessagesModel::unreadCountChanged, this, &Conversation::unreadMessagesChanged);
    setTextChannel(channel);

    d->delegated = false;

    d->pausedStateTimer = new QTimer(this);
    d->pausedStateTimer->setSingleShot(true);
    connect(d->pausedStateTimer, SIGNAL(timeout()), this, SLOT(onChatPausedTimerExpired()));
}

Conversation::Conversation(QObject *parent)
    : QObject(parent),
      d(new ConversationPrivate)
{
    qCCritical(KTP_DECLARATIVE) << "Conversation should not be created directly. Use ConversationWatcher instead.";
}

void Conversation::setTextChannel(const Tp::TextChannelPtr& channel)
{
    if (!d->messages) {
        d->messages = new MessagesModel(d->account, this);
        connect(d->messages, &MessagesModel::unreadCountChanged, this, &Conversation::unreadMessagesChanged);
    }
    if (d->messages->textChannel() != channel) {
        d->messages->setTextChannel(channel);
        d->valid = channel->isValid();
        connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
                SLOT(onChannelInvalidated(Tp::DBusProxy*,QString,QString)));

        if (channel->targetContact().isNull()) {
            d->isGroupChat = true;
        } else {
            d->isGroupChat = false;
            d->targetContact = KTp::ContactPtr::qObjectCast(channel->targetContact());

            connect(d->targetContact.constData(), SIGNAL(aliasChanged(QString)), SIGNAL(titleChanged()));
            connect(d->targetContact.constData(), SIGNAL(presenceChanged(Tp::Presence)), SIGNAL(presenceIconChanged()));
            connect(d->targetContact.constData(), SIGNAL(avatarDataChanged(Tp::AvatarData)), SIGNAL(avatarChanged()));
        }

        Q_EMIT avatarChanged();
        Q_EMIT titleChanged();
        Q_EMIT presenceIconChanged();
        Q_EMIT validityChanged(d->valid);
    }
}

Tp::TextChannelPtr Conversation::textChannel() const
{
    return d->messages->textChannel();
}

MessagesModel* Conversation::messages() const
{
    return d->messages;
}

QString Conversation::title() const
{
    if (d->isGroupChat) {
        QString roomName = textChannel()->targetId();
        return roomName.left(roomName.indexOf(QLatin1Char('@')));
    } else if (!d->targetContact.isNull()) {
        return d->targetContact->alias();
    }

    return QString();
}

QIcon Conversation::presenceIcon() const
{
    if (d->isGroupChat) {
        return KTp::Presence(Tp::Presence::available()).icon();
    } else if (!d->targetContact.isNull()) {
        return KTp::Presence(d->targetContact->presence()).icon();
    }

    return QIcon();
}

QIcon Conversation::avatar() const
{
    if (d->isGroupChat) {
        return QIcon();
    } else {
        const QString path = d->targetContact->avatarData().fileName;
        QIcon icon;
        if (!path.isEmpty()) {
            icon = QIcon(path);
        }
        if (icon.availableSizes().isEmpty()) {
            icon = QIcon::fromTheme(QStringLiteral("im-user"));
        }
        return icon;
    }
}

KTp::ContactPtr Conversation::targetContact() const {
    if (d->isGroupChat) {
        return KTp::ContactPtr();
    } else {
        return d->targetContact;
    }
}

Tp::AccountPtr Conversation::account() const {
    return d->account;
}

bool Conversation::isValid() const
{
    return d->valid;
}

void Conversation::onChannelInvalidated(Tp::DBusProxy *proxy, const QString &errorName, const QString &errorMessage)
{
    qCDebug(KTP_DECLARATIVE) << proxy << errorName << ":" << errorMessage;

    d->valid = false;

    Q_EMIT validityChanged(d->valid);
}

void Conversation::onAccountConnectionChanged(const Tp::ConnectionPtr& connection)
{
    //if we have reconnected and we were handling the channel
    if (connection && ! d->delegated) {

        //general convention is to never use ensureAndHandle when we already have a client registrar
        //ensureAndHandle will implicity create a new temporary client registrar which is a waste
        //it's also more code to get the new channel

        //However, we cannot use use ensureChannel as normal because without being able to pass a preferredHandler
        //we need a preferredHandler so that this handler is the one that ends up with the channel if multi handlers are active
        //we do not know the name that this handler is currently registered with
        Tp::PendingChannel *pendingChannel = d->account->ensureAndHandleTextChat(textChannel()->targetId());
        connect(pendingChannel, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onCreateChannelFinished(Tp::PendingOperation*)));
    }
}

void Conversation::onCreateChannelFinished(Tp::PendingOperation* op)
{
    Tp::PendingChannel *pendingChannelOp = qobject_cast<Tp::PendingChannel*>(op);
    Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(pendingChannelOp->channel());
    if (textChannel) {
        setTextChannel(textChannel);
    }
}

void Conversation::delegateToProperClient()
{
    ChannelDelegator::delegateChannel(d->account, d->messages->textChannel());
    d->delegated = true;
    Q_EMIT conversationCloseRequested();
}

void Conversation::requestClose()
{
    qCDebug(KTP_DECLARATIVE);

    //removing from the model will delete this object closing the channel
    Q_EMIT conversationCloseRequested();
}

void Conversation::updateTextChanged(const QString &message)
{
    if (!message.isEmpty()) {
        //if the timer is active, it means the user is continuously typing
        if (d->pausedStateTimer->isActive()) {
            //just restart the timer and don't spam with chat state changes
            d->pausedStateTimer->start(5000);
        } else {
            //if the user has just typed some text, set state to Composing and start the timer
            d->messages->textChannel()->requestChatState(Tp::ChannelChatStateComposing);
            d->pausedStateTimer->start(5000);
        }
    } else {
        //if the user typed no text/cleared the input field, set Active and stop the timer
        d->messages->textChannel()->requestChatState(Tp::ChannelChatStateActive);
        d->pausedStateTimer->stop();
    }
}

void Conversation::onChatPausedTimerExpired()
{
    d->messages->textChannel()->requestChatState(Tp::ChannelChatStatePaused);
}

Conversation::~Conversation()
{
    qCDebug(KTP_DECLARATIVE);
    //if we are not handling the channel do nothing.
    if (!d->delegated) {
        d->messages->textChannel()->requestClose();
    }
    delete d;
}

bool Conversation::hasUnreadMessages() const
{
    if (d->messages) {
        return d->messages->unreadCount() > 0;
    }

    return false;
}
<|endoftext|>


<commit_before>#include "Lifter.h"
#include "../RobotMap.h"
#include "../Commands/ControlLifter.h"

Lifter::Lifter()
	: Subsystem("Lifter")
{
	m_cLiftMotor = new CANTalon(LIFTER);
	m_cLiftMotor->ConfigLimitMode(CANTalon::kLimitMode_SwitchInputsOnly);
	m_cLiftMotor->ConfigNeutralMode(CANTalon::kNeutralMode_Brake);
	m_cLiftMotor->SetFeedbackDevice(CANTalon::QuadEncoder);
	m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
	m_cLiftMotor->SetSensorDirection(false);
	m_cLiftMotor->SetPID(0.05,0,0);
}

Lifter::~Lifter(){
	delete m_cLiftMotor;
}

void Lifter::InitDefaultCommand()
{
	// Set the default command for a subsystem here.
	SetDefaultCommand(new ControlLifter());
}

void Lifter::toSetpoint(int goal)
{
	double termP = Preferences::GetInstance()->GetInt("LifterPIDtermP", 5);
	m_cLiftMotor->SetControlMode(CANSpeedController::kPosition);
	m_cLiftMotor->SetPID(termP,0,0);
	m_cLiftMotor->Set(goal);
	m_cLiftMotor->EnableControl();
}

void Lifter::moveLifter(float goal)
{
	if(goal > 0 and GetLimitSwitchTop()){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(goal);
	}else if(goal < 0 and GetLimitSwitchBot()){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(goal);
	}else if(goal < 0 and GetPosition() < Preferences::GetInstance()->GetInt("LifterSlowZone", 200)){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(0.5*goal);
	}else if(m_cLiftMotor->GetControlMode() == CANSpeedController::kPercentVbus){
		toSetpoint(GetPosition());
	}
	if(!GetLimitSwitchBot()){
		m_cLiftMotor->SetPosition(0);
	}
}

<commit_msg>Slow Zone at Top of Lifter Added<commit_after>#include "Lifter.h"
#include "../RobotMap.h"
#include "../Commands/ControlLifter.h"

Lifter::Lifter()
	: Subsystem("Lifter")
{
	m_cLiftMotor = new CANTalon(LIFTER);
	m_cLiftMotor->ConfigLimitMode(CANTalon::kLimitMode_SwitchInputsOnly);
	m_cLiftMotor->ConfigNeutralMode(CANTalon::kNeutralMode_Brake);
	m_cLiftMotor->SetFeedbackDevice(CANTalon::QuadEncoder);
	m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
	m_cLiftMotor->SetSensorDirection(false);
	m_cLiftMotor->SetPID(0.05,0,0);
}

Lifter::~Lifter(){
	delete m_cLiftMotor;
}

void Lifter::InitDefaultCommand()
{
	// Set the default command for a subsystem here.
	SetDefaultCommand(new ControlLifter());
}

void Lifter::toSetpoint(int goal)
{
	double termP = Preferences::GetInstance()->GetInt("LifterPIDtermP", 5);
	m_cLiftMotor->SetControlMode(CANSpeedController::kPosition);
	m_cLiftMotor->SetPID(termP,0,0);
	m_cLiftMotor->Set(goal);
	m_cLiftMotor->EnableControl();
}

void Lifter::moveLifter(float goal)
{
	if(goal > 0 and GetLimitSwitchTop()){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(goal);
	}else if(goal < 0 and GetLimitSwitchBot()){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(goal);
	}else if((goal < 0 and GetPosition() < Preferences::GetInstance()->GetInt("LifterSlowZoneBot", 200))
			or (goal > 0 and GetPosition() > Preferences::GetInstance()->GetInt("LifterSlowZoneTop", 6185))){
		m_cLiftMotor->SetControlMode(CANSpeedController::kPercentVbus);
		m_cLiftMotor->Set(0.5*goal);
	}else if(m_cLiftMotor->GetControlMode() == CANSpeedController::kPercentVbus){
		toSetpoint(GetPosition());
	}
	if(!GetLimitSwitchBot()){
		m_cLiftMotor->SetPosition(0);
	}
}

<|endoftext|>