<commit_before>#include "ProbeRenderTasks.h"

#include "ProbeCalls.h"
#include "ProbeGlCalls.h"
#include "mesh/MeshCalls.h"

#include "glm/glm.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "glm/gtx/transform.hpp"

megamol::probe_gl::ProbeRenderTasks::ProbeRenderTasks()
    : m_version(0)
    , m_probes_slot("GetProbes", "Slot for accessing a probe collection")
    , m_probe_manipulation_slot("GetProbeManipulation", "") {
    this->m_probes_slot.SetCompatibleCall<probe::CallProbesDescription>();
    this->MakeSlotAvailable(&this->m_probes_slot);

    this->m_probe_manipulation_slot.SetCompatibleCall<probe_gl::CallProbeInteractionDescription>();
    this->MakeSlotAvailable(&this->m_probe_manipulation_slot);
}

megamol::probe_gl::ProbeRenderTasks::~ProbeRenderTasks() {}

bool megamol::probe_gl::ProbeRenderTasks::getDataCallback(core::Call& caller) {

    mesh::CallGPURenderTaskData* lhs_rtc = dynamic_cast<mesh::CallGPURenderTaskData*>(&caller);
    if (lhs_rtc == NULL) return false;

    mesh::CallGPUMaterialData* mtlc = this->m_material_slot.CallAs<mesh::CallGPUMaterialData>();
    if (mtlc == NULL) return false;
    if (!(*mtlc)(0)) return false;

    mesh::CallGPUMeshData* mc = this->m_mesh_slot.CallAs<mesh::CallGPUMeshData>();
    if (mc == NULL) return false;
    if (!(*mc)(0)) return false; // TODO only call callback when hash is outdated?

    probe::CallProbes* pc = this->m_probes_slot.CallAs<probe::CallProbes>();
    if (pc == NULL) return false;
    if (!(*pc)(0)) return false;

    // something has changed in the neath
    bool something_has_changed = mtlc->hasUpdate() || mc->hasUpdate() || pc->hasUpdate();

    // no incoming render task collection -> use your own collection
    std::shared_ptr<mesh::GPURenderTaskCollection> rt_collection;
    if (lhs_rtc->getData() == nullptr) rt_collection = this->m_gpu_render_tasks;
    else rt_collection = lhs_rtc->getData();

    // if there is a render task connection to the right, pass on the render task collection
    mesh::CallGPURenderTaskData* rhs_rtc = this->m_renderTask_rhs_slot.CallAs<mesh::CallGPURenderTaskData>();
    if (rhs_rtc != NULL) {
        rhs_rtc->setData(rt_collection,0);
        if (!(*rhs_rtc)(0)) return false;
    }

    struct PerObjData {
        glm::mat4x4 object_transform;
        int highlighted;
        float pad0;
        float pad1;
        float pad2;
    };

    if (something_has_changed) {
        ++m_version;

        auto gpu_mtl_storage = mtlc->getData();
        auto gpu_mesh_storage = mc->getData();
        auto probes = pc->getData();

        auto probe_cnt = probes->getProbeCount();

        m_probe_draw_data.clear();
        m_probe_draw_data.resize(probe_cnt);

        std::vector<glowl::DrawElementsCommand> draw_commands(probe_cnt);

        for (int probe_idx = 0; probe_idx < probe_cnt; ++probe_idx) {
            try {
                //auto probe = probes->getProbe<probe::FloatProbe>(probe_idx);

                auto generic_probe = probes->getGenericProbe(probe_idx);

                std::array<float, 3> direction;
                std::array<float, 3> position;
                float begin;
                float end;

                auto visitor = [&direction, &position, &begin, &end](auto&& arg) {
                    using T = std::decay_t<decltype(arg)>;
                    if constexpr (std::is_same_v<T, probe::FloatProbe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else if constexpr (std::is_same_v<T, probe::IntProbe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else if constexpr (std::is_same_v<T, probe::Vec4Probe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else {
                        // unknown probe type, throw error? do nothing?
                    }
                };

                std::visit(visitor, generic_probe);

                // TODO create and add new render task for probe

                assert(gpu_mesh_storage->getSubMeshData().size() > 0);

                auto const& gpu_sub_mesh = gpu_mesh_storage->getSubMeshData().front();
                auto const& gpu_batch_mesh = gpu_mesh_storage->getMeshes().front().mesh;

                draw_commands[probe_idx] = gpu_sub_mesh.sub_mesh_draw_command;

                const glm::vec3 from(0.0f, 0.0f, 1.0f);
                const glm::vec3 to(direction[0], direction[1], direction[2]);
                glm::vec3 v = glm::cross(to, from);
                float angle = -acos(glm::dot(to, from) / (glm::length(to) * glm::length(from)));
                m_probe_draw_data[probe_idx].object_transform = glm::rotate(angle, v);

                auto scaling = glm::scale(glm::vec3(0.5f, 0.5f, end - begin));

                auto probe_start_point = glm::vec3(
                    position[0] + direction[0] * begin,
                    position[1] + direction[1] * begin,
                    position[2] + direction[2] * begin);
                auto translation = glm::translate(glm::mat4(), probe_start_point);
                m_probe_draw_data[probe_idx].object_transform =
                    translation * m_probe_draw_data[probe_idx].object_transform * scaling;

            } catch (std::bad_variant_access&) {
                // TODO log error, dont add new render task
            }
        }

        auto const& gpu_sub_mesh = gpu_mesh_storage->getSubMeshData().front();
        auto const& gpu_batch_mesh = gpu_mesh_storage->getMeshes().front().mesh;
        auto const& shader = gpu_mtl_storage->getMaterials().front().shader_program;
        rt_collection->addRenderTasks(shader, gpu_batch_mesh, draw_commands, m_probe_draw_data);
    }

    lhs_rtc->setData(rt_collection, m_version);

    // check for pending probe manipulations
    CallProbeInteraction* pic = this->m_probe_manipulation_slot.CallAs<CallProbeInteraction>();
    if (pic != NULL) {
        if (!(*pic)(0)) return false;

        if (pic->hasUpdate()) {
            auto interaction_collection = pic->getData();

            auto& pending_manips = interaction_collection->accessPendingManipulations();

            if (pc->hasUpdate())
            {
                if (!(*pc)(0)) return false;
            }
            auto probes = pc->getData();

            for (auto itr = pending_manips.begin(); itr != pending_manips.end(); ++itr) {
                if (itr->type == HIGHLIGHT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    std::array<PerProbeDrawData, 1> per_probe_data = {m_probe_draw_data[manipulation.obj_id]};
                    per_probe_data[0].highlighted = 1;

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else if (itr->type == DEHIGHLIGHT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    std::array<PerProbeDrawData,1> per_probe_data = { m_probe_draw_data[manipulation.obj_id] };

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else if (itr->type == SELECT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    m_probe_draw_data[manipulation.obj_id].highlighted = 2;
                    std::array<PerProbeDrawData, 1> per_probe_data = {m_probe_draw_data[manipulation.obj_id]};

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else {
                    ++itr;
                }
            }
        }
    }

    return true;
}

bool megamol::probe_gl::ProbeRenderTasks::getMetaDataCallback(core::Call& caller) {

    if (!AbstractGPURenderTaskDataSource::getMetaDataCallback(caller)) return false;

    mesh::CallGPURenderTaskData* lhs_rt_call = dynamic_cast<mesh::CallGPURenderTaskData*>(&caller);
    auto probe_call = m_probes_slot.CallAs<probe::CallProbes>();
    if (probe_call == NULL) return false;

    auto lhs_meta_data = lhs_rt_call->getMetaData();

    auto probe_meta_data = probe_call->getMetaData();
    probe_meta_data.m_frame_ID = lhs_meta_data.m_frame_ID;
    probe_call->setMetaData(probe_meta_data);
    if (!(*probe_call)(1)) return false;
    probe_meta_data = probe_call->getMetaData();

    lhs_meta_data.m_frame_cnt = std::min(lhs_meta_data.m_frame_cnt, probe_meta_data.m_frame_cnt);

    auto bbox = lhs_meta_data.m_bboxs.BoundingBox();
    bbox.Union(probe_meta_data.m_bboxs.BoundingBox());
    lhs_meta_data.m_bboxs.SetBoundingBox(bbox);

    auto cbbox = lhs_meta_data.m_bboxs.ClipBox();
    cbbox.Union(probe_meta_data.m_bboxs.ClipBox());
    lhs_meta_data.m_bboxs.SetClipBox(cbbox);

    lhs_rt_call->setMetaData(lhs_meta_data);

    return true;
}
<commit_msg>Fix bug for ProbeNeedle rendering<commit_after>#include "ProbeRenderTasks.h"

#include "ProbeCalls.h"
#include "ProbeGlCalls.h"
#include "mesh/MeshCalls.h"

#include "glm/glm.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "glm/gtx/transform.hpp"

megamol::probe_gl::ProbeRenderTasks::ProbeRenderTasks()
    : m_version(0)
    , m_probes_slot("GetProbes", "Slot for accessing a probe collection")
    , m_probe_manipulation_slot("GetProbeManipulation", "") {
    this->m_probes_slot.SetCompatibleCall<probe::CallProbesDescription>();
    this->MakeSlotAvailable(&this->m_probes_slot);

    this->m_probe_manipulation_slot.SetCompatibleCall<probe_gl::CallProbeInteractionDescription>();
    this->MakeSlotAvailable(&this->m_probe_manipulation_slot);
}

megamol::probe_gl::ProbeRenderTasks::~ProbeRenderTasks() {}

bool megamol::probe_gl::ProbeRenderTasks::getDataCallback(core::Call& caller) {

    mesh::CallGPURenderTaskData* lhs_rtc = dynamic_cast<mesh::CallGPURenderTaskData*>(&caller);
    if (lhs_rtc == NULL) return false;

    mesh::CallGPUMaterialData* mtlc = this->m_material_slot.CallAs<mesh::CallGPUMaterialData>();
    if (mtlc == NULL) return false;
    if (!(*mtlc)(0)) return false;

    mesh::CallGPUMeshData* mc = this->m_mesh_slot.CallAs<mesh::CallGPUMeshData>();
    if (mc == NULL) return false;
    if (!(*mc)(0)) return false; // TODO only call callback when hash is outdated?

    probe::CallProbes* pc = this->m_probes_slot.CallAs<probe::CallProbes>();
    if (pc == NULL) return false;
    if (!(*pc)(0)) return false;

    // something has changed in the neath
    bool something_has_changed = mtlc->hasUpdate() || mc->hasUpdate() || pc->hasUpdate();

    // no incoming render task collection -> use your own collection
    std::shared_ptr<mesh::GPURenderTaskCollection> rt_collection;
    if (lhs_rtc->getData() == nullptr) rt_collection = this->m_gpu_render_tasks;
    else rt_collection = lhs_rtc->getData();

    // if there is a render task connection to the right, pass on the render task collection
    mesh::CallGPURenderTaskData* rhs_rtc = this->m_renderTask_rhs_slot.CallAs<mesh::CallGPURenderTaskData>();
    if (rhs_rtc != NULL) {
        rhs_rtc->setData(rt_collection,0);
        if (!(*rhs_rtc)(0)) return false;
    }

    struct PerObjData {
        glm::mat4x4 object_transform;
        int highlighted;
        float pad0;
        float pad1;
        float pad2;
    };

    if (something_has_changed) {
        ++m_version;

        //TODO this breaks chaining...
        rt_collection->clear();

        auto gpu_mtl_storage = mtlc->getData();
        auto gpu_mesh_storage = mc->getData();
        auto probes = pc->getData();

        auto probe_cnt = probes->getProbeCount();

        m_probe_draw_data.clear();
        m_probe_draw_data.resize(probe_cnt);

        std::vector<glowl::DrawElementsCommand> draw_commands(probe_cnt);

        for (int probe_idx = 0; probe_idx < probe_cnt; ++probe_idx) {
            try {
                //auto probe = probes->getProbe<probe::FloatProbe>(probe_idx);

                auto generic_probe = probes->getGenericProbe(probe_idx);

                std::array<float, 3> direction;
                std::array<float, 3> position;
                float begin;
                float end;

                auto visitor = [&direction, &position, &begin, &end](auto&& arg) {
                    using T = std::decay_t<decltype(arg)>;
                    if constexpr (std::is_same_v<T, probe::FloatProbe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else if constexpr (std::is_same_v<T, probe::IntProbe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else if constexpr (std::is_same_v<T, probe::Vec4Probe>) {
                        direction = arg.m_direction;
                        position = arg.m_position;
                        begin = arg.m_begin;
                        end = arg.m_end;
                    } else {
                        // unknown probe type, throw error? do nothing?
                    }
                };

                std::visit(visitor, generic_probe);

                // TODO create and add new render task for probe

                assert(gpu_mesh_storage->getSubMeshData().size() > 0);

                auto const& gpu_sub_mesh = gpu_mesh_storage->getSubMeshData().front();
                auto const& gpu_batch_mesh = gpu_mesh_storage->getMeshes().front().mesh;

                draw_commands[probe_idx] = gpu_sub_mesh.sub_mesh_draw_command;

                const glm::vec3 from(0.0f, 0.0f, 1.0f);
                const glm::vec3 to(direction[0], direction[1], direction[2]);
                glm::vec3 v = glm::cross(to, from);
                float angle = -acos(glm::dot(to, from) / (glm::length(to) * glm::length(from)));
                m_probe_draw_data[probe_idx].object_transform = glm::rotate(angle, v);

                auto scaling = glm::scale(glm::vec3(0.5f, 0.5f, end - begin));

                auto probe_start_point = glm::vec3(
                    position[0] + direction[0] * begin,
                    position[1] + direction[1] * begin,
                    position[2] + direction[2] * begin);
                auto translation = glm::translate(glm::mat4(), probe_start_point);
                m_probe_draw_data[probe_idx].object_transform =
                    translation * m_probe_draw_data[probe_idx].object_transform * scaling;

            } catch (std::bad_variant_access&) {
                // TODO log error, dont add new render task
            }
        }

        auto const& gpu_sub_mesh = gpu_mesh_storage->getSubMeshData().front();
        auto const& gpu_batch_mesh = gpu_mesh_storage->getMeshes().front().mesh;
        auto const& shader = gpu_mtl_storage->getMaterials().front().shader_program;
        rt_collection->addRenderTasks(shader, gpu_batch_mesh, draw_commands, m_probe_draw_data);
    }

    lhs_rtc->setData(rt_collection, m_version);

    // check for pending probe manipulations
    CallProbeInteraction* pic = this->m_probe_manipulation_slot.CallAs<CallProbeInteraction>();
    if (pic != NULL) {
        if (!(*pic)(0)) return false;

        if (pic->hasUpdate()) {
            auto interaction_collection = pic->getData();

            auto& pending_manips = interaction_collection->accessPendingManipulations();

            if (pc->hasUpdate())
            {
                if (!(*pc)(0)) return false;
            }
            auto probes = pc->getData();

            for (auto itr = pending_manips.begin(); itr != pending_manips.end(); ++itr) {
                if (itr->type == HIGHLIGHT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    std::array<PerProbeDrawData, 1> per_probe_data = {m_probe_draw_data[manipulation.obj_id]};
                    per_probe_data[0].highlighted = 1;

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else if (itr->type == DEHIGHLIGHT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    std::array<PerProbeDrawData,1> per_probe_data = { m_probe_draw_data[manipulation.obj_id] };

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else if (itr->type == SELECT)
                {
                    // TODO remove from list and apply hightlight to render task
                    auto manipulation = *itr;
                    //itr = pending_manips.erase(itr);

                    m_probe_draw_data[manipulation.obj_id].highlighted = 2;
                    std::array<PerProbeDrawData, 1> per_probe_data = {m_probe_draw_data[manipulation.obj_id]};

                    rt_collection->updatePerDrawData(manipulation.obj_id, per_probe_data);
                }
                else {
                    ++itr;
                }
            }
        }
    }

    return true;
}

bool megamol::probe_gl::ProbeRenderTasks::getMetaDataCallback(core::Call& caller) {

    if (!AbstractGPURenderTaskDataSource::getMetaDataCallback(caller)) return false;

    mesh::CallGPURenderTaskData* lhs_rt_call = dynamic_cast<mesh::CallGPURenderTaskData*>(&caller);
    auto probe_call = m_probes_slot.CallAs<probe::CallProbes>();
    if (probe_call == NULL) return false;

    auto lhs_meta_data = lhs_rt_call->getMetaData();

    auto probe_meta_data = probe_call->getMetaData();
    probe_meta_data.m_frame_ID = lhs_meta_data.m_frame_ID;
    probe_call->setMetaData(probe_meta_data);
    if (!(*probe_call)(1)) return false;
    probe_meta_data = probe_call->getMetaData();

    lhs_meta_data.m_frame_cnt = std::min(lhs_meta_data.m_frame_cnt, probe_meta_data.m_frame_cnt);

    auto bbox = lhs_meta_data.m_bboxs.BoundingBox();
    bbox.Union(probe_meta_data.m_bboxs.BoundingBox());
    lhs_meta_data.m_bboxs.SetBoundingBox(bbox);

    auto cbbox = lhs_meta_data.m_bboxs.ClipBox();
    cbbox.Union(probe_meta_data.m_bboxs.ClipBox());
    lhs_meta_data.m_bboxs.SetClipBox(cbbox);

    lhs_rt_call->setMetaData(lhs_meta_data);

    return true;
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>

#include "log.hpp"
#include "hlt_in.hpp"
#include "hlt_out.hpp"

namespace hlt {
    struct Metadata {
        const PlayerId player_id;
        const int map_width;
        const int map_height;
    };

    /// Initialize our bot with the given name, getting back some metadata.
    static Metadata initialize(const std::string& bot_name) {
        std::cout.sync_with_stdio(false);

        std::stringstream iss1(in::get_string());
        int player_id;
        iss1 >> player_id;

        std::stringstream iss2(in::get_string());
        int map_width;
        int map_height;
        iss2 >> map_width >> map_height;

        Log::open(std::to_string(player_id) + "_" + bot_name + ".log");

        out::send_string(bot_name);

        return { static_cast<PlayerId>(player_id), map_width, map_height };
    }
}
<commit_msg>cpp-client: fix issue with bot seeing map from previous turn<commit_after>#pragma once

#include <iostream>

#include "log.hpp"
#include "hlt_in.hpp"
#include "hlt_out.hpp"

namespace hlt {
    struct Metadata {
        const PlayerId player_id;
        const int map_width;
        const int map_height;
    };

    /// Initialize our bot with the given name, getting back some metadata.
    static Metadata initialize(const std::string& bot_name) {
        std::cout.sync_with_stdio(false);

        std::stringstream iss1(in::get_string());
        int player_id;
        iss1 >> player_id;

        std::stringstream iss2(in::get_string());
        int map_width;
        int map_height;
        iss2 >> map_width >> map_height;

        Log::open(std::to_string(player_id) + "_" + bot_name + ".log");

        out::send_string(bot_name);

        // halite sends full map as part of initialization, we can discard it since
        // we'll get it as first map update anyway, but if you want, you can parse
        // it using hlt::in::get_map
        in::get_string();

        return { static_cast<PlayerId>(player_id), map_width, map_height };
    }
}
<|endoftext|>


<commit_before>#pragma once

#include "trajectory.hpp"

#include <list>
#include <map>

#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "physics/oblate_body.hpp"

using principia::geometry::Instant;

namespace principia {
namespace physics {

template<typename Frame>
Trajectory<Frame>::Trajectory(Body const& body)
    : body_(body),
      parent_(nullptr) {
  CHECK(body.is_compatible_with<Frame>())
      << "Oblate body not in the same frame as the trajectory";
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::first() const {
  NativeIterator it;
  it.InitializeFirst(this);
  return it;
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::on_or_after(
    Instant const& time) const {
  NativeIterator it;
  it.InitializeOnOrAfter(time, this);
  return it;
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::last() const {
  NativeIterator it;
  it.InitializeLast(this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::first_with_transform(
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeFirst(this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::on_or_after_with_transform(
    Instant const& time,
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeOnOrAfter(time, this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::last_with_transform(
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeLast(this);
  return it;
}

template<typename Frame>
std::map<Instant, Position<Frame>> Trajectory<Frame>::Positions() const {
  std::map<Instant, Position<Frame>> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    Instant const& time = it.time();
    result.emplace_hint(result.end(), time, it.degrees_of_freedom().position);
  }
  return result;
}

template<typename Frame>
std::map<Instant, Velocity<Frame>> Trajectory<Frame>::Velocities() const {
  std::map<Instant, Velocity<Frame>> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    Instant const& time = it.time();
    result.emplace_hint(result.end(), time, it.degrees_of_freedom().velocity);
  }
  return result;
}

template<typename Frame>
std::list<Instant> Trajectory<Frame>::Times() const {
  std::list<Instant> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    result.push_back(it.time());
  }
  return result;
}

template<typename Frame>
void Trajectory<Frame>::Append(
    Instant const& time,
    DegreesOfFreedom<Frame> const& degrees_of_freedom) {
  auto inserted = timeline_.emplace(time, degrees_of_freedom);
  CHECK(timeline_.end() == ++inserted.first) << "Append out of order";
  CHECK(inserted.second) << "Append at existing time";
}

template<typename Frame>
void Trajectory<Frame>::ForgetAfter(Instant const& time) {
  // Check that |time| is the time of one of our Timeline or the time of fork.
  auto const it = timeline_.find(time);
  if (it == timeline_.end()) {
    CHECK(fork_ != nullptr)
        << "ForgetAfter a nonexistent time for a root trajectory";
    CHECK_EQ((*fork_)->first, time)
        << "ForgetAfter a nonexistent time for a nonroot trajectory";
  }

  // Each of these blocks gets an iterator denoting the first entry with
  // time > |time|.  It then removes that entry and all the entries that follow
  // it.  This preserve any entry with time == |time|.
  {
    auto const it = timeline_.upper_bound(time);
    timeline_.erase(it, timeline_.end());
  }
  {
    auto const it = children_.upper_bound(time);
    children_.erase(it, children_.end());
  }
}

template<typename Frame>
void Trajectory<Frame>::ForgetBefore(Instant const& time) {
  // Check that this is a root.
  CHECK(is_root()) << "ForgetBefore on a nonroot trajectory";
  // Check that |time| is the time of one of our Timeline or the time of fork.
  CHECK(timeline_.find(time) != timeline_.end())
      << "ForgetBefore a nonexistent time";
  {
    auto it = timeline_.upper_bound(time);
    timeline_.erase(timeline_.begin(), it);
  }
  {
    auto it = children_.upper_bound(time);
    children_.erase(children_.begin(), it);
  }
}

template<typename Frame>
Trajectory<Frame>* Trajectory<Frame>::Fork(Instant const& time) {
  auto fork_it = timeline_.find(time);
  CHECK(fork_it != timeline_.end()) << "Fork at nonexistent time";
  std::unique_ptr<Trajectory<Frame>> child(
      new Trajectory(body_, this /*parent*/, fork_it));
  child->timeline_.emplace(++fork_it, timeline_.end());
  auto const child_it = children_.emplace(time, std::move(child));
  return child_it->second.get();
}

template<typename Frame>
void Trajectory<Frame>::DeleteFork(Trajectory** const fork) {
  CHECK_NOTNULL(fork);
  CHECK_NOTNULL(*fork);
  Instant const* const fork_time = (*fork)->fork_time();
  CHECK_NOTNULL(fork_time);
  // Find the position of |*fork| among our children and remove it.
  auto const range = children_.equal_range(*fork_time);
  for (auto it = range.first; it != range.second; ++it) {
    if (it->second.get() == *fork) {
      children_.erase(it);
      *fork = nullptr;
      return;
    }
  }
  LOG(FATAL) << "fork is not a child of this trajectory";
}

template<typename Frame>
bool Trajectory<Frame>::is_root() const {
  return parent_ == nullptr;
}

template<typename Frame>
Trajectory<Frame> const* Trajectory<Frame>::root() const {
  Trajectory const* ancestor = this;
  while (ancestor->parent_ != nullptr) {
    ancestor = ancestor->parent_;
  }
  return ancestor;
}

template<typename Frame>
Trajectory<Frame>* Trajectory<Frame>::root() {
  Trajectory* ancestor = this;
  while (ancestor->parent_ != nullptr) {
    ancestor = ancestor->parent_;
  }
  return ancestor;
}

template<typename Frame>
Instant const* Trajectory<Frame>::fork_time() const {
  if (parent_ == nullptr) {
    return nullptr;
  } else {
    return &((*fork_)->first);
  }
}

template<typename Frame>
template<typename B>
std::enable_if_t<std::is_base_of<Body, B>::value, B> const&
Trajectory<Frame>::body() const {
// Dynamic casting is expensive, as in 3x slower for the benchmarks.  Do that in
// debug mode to catch bugs, but not in optimized mode where we want all the
// performance we can get.
#ifdef _DEBUG
  return *CHECK_NOTNULL(dynamic_cast<B const*>(&body_));
#else
  return *static_cast<B const*>(&body_);
#endif
}

template<typename Frame>
void Trajectory<Frame>::set_intrinsic_acceleration(
    IntrinsicAcceleration const acceleration) {
  CHECK(body_.is_massless()) << "Trajectory is for a massive body";
  CHECK(intrinsic_acceleration_ == nullptr)
      << "Trajectory already has an intrinsic acceleration";
  intrinsic_acceleration_.reset(new IntrinsicAcceleration(acceleration));
}

template<typename Frame>
void Trajectory<Frame>::clear_intrinsic_acceleration() {
  intrinsic_acceleration_.reset();
}

template<typename Frame>
bool Trajectory<Frame>::has_intrinsic_acceleration() const {
  return intrinsic_acceleration_ != nullptr;
}

template<typename Frame>
Vector<Acceleration, Frame> Trajectory<Frame>::evaluate_intrinsic_acceleration(
    Instant const& time) const {
  if (intrinsic_acceleration_ != nullptr &&
      (fork_ == nullptr || time > (*fork_)->first)) {
    return (*intrinsic_acceleration_)(time);
  } else {
    return Vector<Acceleration, Frame>({0 * SIUnit<Acceleration>(),
                                        0 * SIUnit<Acceleration>(),
                                        0 * SIUnit<Acceleration>()});
  }
}

template<typename Frame>
typename Trajectory<Frame>::Iterator&
Trajectory<Frame>::Iterator::operator++() {
  if (!forks_.empty() && current_ == forks_.front()) {
    ancestry_.pop_front();
    forks_.pop_front();
    current_ = ancestry_.front()->timeline_.begin();
  } else {
    CHECK(current_ != ancestry_.front()->timeline_.end())
        << "Incrementing beyond end of trajectory";
    ++current_;
  }
  return *this;
}

template<typename Frame>
bool Trajectory<Frame>::Iterator::at_end() const {
  return forks_.empty() && current_ == ancestry_.front()->timeline_.end();
}

template<typename Frame>
Instant const& Trajectory<Frame>::Iterator::time() const {
  return current_->first;
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeFirst(
    Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  Trajectory const* ancestor = trajectory;
  while (ancestor->parent_ != nullptr) {
    ancestry_.push_front(ancestor);
    forks_.push_front(*ancestor->fork_);
    ancestor = ancestor->parent_;
  }
  ancestry_.push_front(ancestor);
  current_ = ancestor->timeline_.begin();
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeOnOrAfter(
  Instant const& time, Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  Trajectory const* ancestor = trajectory;
  while (ancestor->fork_ != nullptr && time <= (*ancestor->fork_)->first) {
    ancestry_.push_front(ancestor);
    forks_.push_front(*ancestor->fork_);
    ancestor = ancestor->parent_;
  }
  ancestry_.push_front(ancestor);
  current_ = ancestor->timeline_.lower_bound(time);
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeLast(
    Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  // We don't need to really keep track of the forks or of the ancestry.
  if (trajectory->timeline_.empty()) {
    CHECK(trajectory->fork_ != nullptr) << "Empty trajectory";
    ancestry_.push_front(trajectory->parent_);
    current_ = *trajectory->fork_;
  } else {
    ancestry_.push_front(trajectory);
    current_ = --trajectory->timeline_.end();
  }
}

template<typename Frame>
typename Trajectory<Frame>::Timeline::const_iterator
Trajectory<Frame>::Iterator::current() const {
  return current_;
}

template<typename Frame>
Trajectory<Frame> const* Trajectory<Frame>::Iterator::trajectory() const {
  return ancestry_.back();
}

template<typename Frame>
DegreesOfFreedom<Frame> const&
Trajectory<Frame>::NativeIterator::degrees_of_freedom() const {
  return this->current()->second;
}

template<typename Frame>
template<typename ToFrame>
DegreesOfFreedom<ToFrame>
Trajectory<Frame>::TransformingIterator<ToFrame>::degrees_of_freedom() const {
  auto it = current();
  return transform_(it->first, it->second, trajectory());
}

template<typename Frame>
template<typename ToFrame>
Trajectory<Frame>::TransformingIterator<ToFrame>::TransformingIterator(
    Transform<ToFrame> const& transform)
    : Iterator(),
      transform_(transform) {}

template<typename Frame>
Trajectory<Frame>::Trajectory(Body const& body,
                              Trajectory* const parent,
                              typename Timeline::iterator const& fork)
    : body_(body),
      parent_(CHECK_NOTNULL(parent)),
      fork_(new typename Timeline::iterator(fork)) {}

}  // namespace physics
}  // namespace principia
<commit_msg>Fixes.<commit_after>#pragma once

#include "trajectory.hpp"

#include <list>
#include <map>

#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "physics/oblate_body.hpp"

using principia::geometry::Instant;

namespace principia {
namespace physics {

template<typename Frame>
Trajectory<Frame>::Trajectory(Body const& body)
    : body_(body),
      parent_(nullptr) {
  CHECK(body.is_compatible_with<Frame>())
      << "Oblate body not in the same frame as the trajectory";
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::first() const {
  NativeIterator it;
  it.InitializeFirst(this);
  return it;
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::on_or_after(
    Instant const& time) const {
  NativeIterator it;
  it.InitializeOnOrAfter(time, this);
  return it;
}

template<typename Frame>
typename Trajectory<Frame>::NativeIterator Trajectory<Frame>::last() const {
  NativeIterator it;
  it.InitializeLast(this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::first_with_transform(
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeFirst(this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::on_or_after_with_transform(
    Instant const& time,
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeOnOrAfter(time, this);
  return it;
}

template<typename Frame>
template<typename ToFrame>
typename Trajectory<Frame>::TransformingIterator<ToFrame>
Trajectory<Frame>::last_with_transform(
    Transform<ToFrame> const& transform) const {
  TransformingIterator<ToFrame> it(transform);
  it.InitializeLast(this);
  return it;
}

template<typename Frame>
std::map<Instant, Position<Frame>> Trajectory<Frame>::Positions() const {
  std::map<Instant, Position<Frame>> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    Instant const& time = it.time();
    result.emplace_hint(result.end(), time, it.degrees_of_freedom().position);
  }
  return result;
}

template<typename Frame>
std::map<Instant, Velocity<Frame>> Trajectory<Frame>::Velocities() const {
  std::map<Instant, Velocity<Frame>> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    Instant const& time = it.time();
    result.emplace_hint(result.end(), time, it.degrees_of_freedom().velocity);
  }
  return result;
}

template<typename Frame>
std::list<Instant> Trajectory<Frame>::Times() const {
  std::list<Instant> result;
  for (NativeIterator it = first(); !it.at_end(); ++it) {
    result.push_back(it.time());
  }
  return result;
}

template<typename Frame>
void Trajectory<Frame>::Append(
    Instant const& time,
    DegreesOfFreedom<Frame> const& degrees_of_freedom) {
  auto inserted = timeline_.emplace(time, degrees_of_freedom);
  CHECK(timeline_.end() == ++inserted.first) << "Append out of order";
  CHECK(inserted.second) << "Append at existing time";
}

template<typename Frame>
void Trajectory<Frame>::ForgetAfter(Instant const& time) {
  // Check that |time| is the time of one of our Timeline or the time of fork.
  auto const it = timeline_.find(time);
  if (it == timeline_.end()) {
    CHECK(fork_ != nullptr)
        << "ForgetAfter a nonexistent time for a root trajectory";
    CHECK_EQ((*fork_)->first, time)
        << "ForgetAfter a nonexistent time for a nonroot trajectory";
  }

  // Each of these blocks gets an iterator denoting the first entry with
  // time > |time|.  It then removes that entry and all the entries that follow
  // it.  This preserve any entry with time == |time|.
  {
    auto const it = timeline_.upper_bound(time);
    timeline_.erase(it, timeline_.end());
  }
  {
    auto const it = children_.upper_bound(time);
    children_.erase(it, children_.end());
  }
}

template<typename Frame>
void Trajectory<Frame>::ForgetBefore(Instant const& time) {
  // Check that this is a root.
  CHECK(is_root()) << "ForgetBefore on a nonroot trajectory";
  // Check that |time| is the time of one of our Timeline or the time of fork.
  CHECK(timeline_.find(time) != timeline_.end())
      << "ForgetBefore a nonexistent time";
  {
    auto it = timeline_.upper_bound(time);
    timeline_.erase(timeline_.begin(), it);
  }
  {
    auto it = children_.upper_bound(time);
    children_.erase(children_.begin(), it);
  }
}

template<typename Frame>
Trajectory<Frame>* Trajectory<Frame>::Fork(Instant const& time) {
  auto fork_it = timeline_.find(time);
  CHECK(fork_it != timeline_.end()) << "Fork at nonexistent time";
  std::unique_ptr<Trajectory<Frame>> child(
      new Trajectory(body_, this /*parent*/, fork_it));
  child->timeline_.insert(++fork_it, timeline_.end());
  auto const child_it = children_.emplace(time, std::move(child));
  return child_it->second.get();
}

template<typename Frame>
void Trajectory<Frame>::DeleteFork(Trajectory** const fork) {
  CHECK_NOTNULL(fork);
  CHECK_NOTNULL(*fork);
  Instant const* const fork_time = (*fork)->fork_time();
  CHECK_NOTNULL(fork_time);
  // Find the position of |*fork| among our children and remove it.
  auto const range = children_.equal_range(*fork_time);
  for (auto it = range.first; it != range.second; ++it) {
    if (it->second.get() == *fork) {
      children_.erase(it);
      *fork = nullptr;
      return;
    }
  }
  LOG(FATAL) << "fork is not a child of this trajectory";
}

template<typename Frame>
bool Trajectory<Frame>::is_root() const {
  return parent_ == nullptr;
}

template<typename Frame>
Trajectory<Frame> const* Trajectory<Frame>::root() const {
  Trajectory const* ancestor = this;
  while (ancestor->parent_ != nullptr) {
    ancestor = ancestor->parent_;
  }
  return ancestor;
}

template<typename Frame>
Trajectory<Frame>* Trajectory<Frame>::root() {
  Trajectory* ancestor = this;
  while (ancestor->parent_ != nullptr) {
    ancestor = ancestor->parent_;
  }
  return ancestor;
}

template<typename Frame>
Instant const* Trajectory<Frame>::fork_time() const {
  if (parent_ == nullptr) {
    return nullptr;
  } else {
    return &((*fork_)->first);
  }
}

template<typename Frame>
template<typename B>
std::enable_if_t<std::is_base_of<Body, B>::value, B> const&
Trajectory<Frame>::body() const {
// Dynamic casting is expensive, as in 3x slower for the benchmarks.  Do that in
// debug mode to catch bugs, but not in optimized mode where we want all the
// performance we can get.
#ifdef _DEBUG
  return *CHECK_NOTNULL(dynamic_cast<B const*>(&body_));
#else
  return *static_cast<B const*>(&body_);
#endif
}

template<typename Frame>
void Trajectory<Frame>::set_intrinsic_acceleration(
    IntrinsicAcceleration const acceleration) {
  CHECK(body_.is_massless()) << "Trajectory is for a massive body";
  CHECK(intrinsic_acceleration_ == nullptr)
      << "Trajectory already has an intrinsic acceleration";
  intrinsic_acceleration_.reset(new IntrinsicAcceleration(acceleration));
}

template<typename Frame>
void Trajectory<Frame>::clear_intrinsic_acceleration() {
  intrinsic_acceleration_.reset();
}

template<typename Frame>
bool Trajectory<Frame>::has_intrinsic_acceleration() const {
  return intrinsic_acceleration_ != nullptr;
}

template<typename Frame>
Vector<Acceleration, Frame> Trajectory<Frame>::evaluate_intrinsic_acceleration(
    Instant const& time) const {
  if (intrinsic_acceleration_ != nullptr &&
      (fork_ == nullptr || time > (*fork_)->first)) {
    return (*intrinsic_acceleration_)(time);
  } else {
    return Vector<Acceleration, Frame>({0 * SIUnit<Acceleration>(),
                                        0 * SIUnit<Acceleration>(),
                                        0 * SIUnit<Acceleration>()});
  }
}

template<typename Frame>
typename Trajectory<Frame>::Iterator&
Trajectory<Frame>::Iterator::operator++() {
  if (!forks_.empty() && current_ == forks_.front()) {
    ancestry_.pop_front();
    forks_.pop_front();
    current_ = ancestry_.front()->timeline_.begin();
  } else {
    CHECK(current_ != ancestry_.front()->timeline_.end())
        << "Incrementing beyond end of trajectory";
    ++current_;
  }
  return *this;
}

template<typename Frame>
bool Trajectory<Frame>::Iterator::at_end() const {
  return forks_.empty() && current_ == ancestry_.front()->timeline_.end();
}

template<typename Frame>
Instant const& Trajectory<Frame>::Iterator::time() const {
  return current_->first;
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeFirst(
    Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  Trajectory const* ancestor = trajectory;
  while (ancestor->parent_ != nullptr) {
    ancestry_.push_front(ancestor);
    forks_.push_front(*ancestor->fork_);
    ancestor = ancestor->parent_;
  }
  ancestry_.push_front(ancestor);
  current_ = ancestor->timeline_.begin();
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeOnOrAfter(
  Instant const& time, Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  Trajectory const* ancestor = trajectory;
  while (ancestor->fork_ != nullptr && time <= (*ancestor->fork_)->first) {
    ancestry_.push_front(ancestor);
    forks_.push_front(*ancestor->fork_);
    ancestor = ancestor->parent_;
  }
  ancestry_.push_front(ancestor);
  current_ = ancestor->timeline_.lower_bound(time);
}

template<typename Frame>
void Trajectory<Frame>::Iterator::InitializeLast(
    Trajectory const* trajectory) {
  CHECK_NOTNULL(trajectory);
  // We don't need to really keep track of the forks or of the ancestry.
  if (trajectory->timeline_.empty()) {
    CHECK(trajectory->fork_ != nullptr) << "Empty trajectory";
    ancestry_.push_front(trajectory->parent_);
    current_ = *trajectory->fork_;
  } else {
    ancestry_.push_front(trajectory);
    current_ = --trajectory->timeline_.end();
  }
}

template<typename Frame>
typename Trajectory<Frame>::Timeline::const_iterator
Trajectory<Frame>::Iterator::current() const {
  return current_;
}

template<typename Frame>
Trajectory<Frame> const* Trajectory<Frame>::Iterator::trajectory() const {
  return ancestry_.back();
}

template<typename Frame>
DegreesOfFreedom<Frame> const&
Trajectory<Frame>::NativeIterator::degrees_of_freedom() const {
  return this->current()->second;
}

template<typename Frame>
template<typename ToFrame>
DegreesOfFreedom<ToFrame>
Trajectory<Frame>::TransformingIterator<ToFrame>::degrees_of_freedom() const {
  auto it = current();
  return transform_(it->first, it->second, trajectory());
}

template<typename Frame>
template<typename ToFrame>
Trajectory<Frame>::TransformingIterator<ToFrame>::TransformingIterator(
    Transform<ToFrame> const& transform)
    : Iterator(),
      transform_(transform) {}

template<typename Frame>
Trajectory<Frame>::Trajectory(Body const& body,
                              Trajectory* const parent,
                              typename Timeline::iterator const& fork)
    : body_(body),
      parent_(CHECK_NOTNULL(parent)),
      fork_(new typename Timeline::iterator(fork)) {}

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>/*!
 * \file GraspCollector.cpp
 * \brief The main grasp collector node object.
 *
 * The grasp collector is responsible for capturing and storing grasps. An action server is started is the main
 * entry point to grasp collecting.
 *
 * \author Russell Toris, WPI - rctoris@wpi.edu
 * \author David Kent, WPI - davidkent@wpi.edu
 * \date March 3, 2015
 */

#include <rail_grasp_collection/GraspCollector.h>
#include <tf2_sensor_msgs/tf2_sensor_msgs.h>

using namespace std;
using namespace rail::pick_and_place;

GraspCollector::GraspCollector()
    : private_node_("~"), ac_wait_time_(AC_WAIT_TIME), tf_listener_(tf_buffer_),
      robot_fixed_frame_id_("base_footprint"), eef_frame_id_("eef_link"),
      as_(private_node_, "grasp_and_store", boost::bind(&GraspCollector::graspAndStore, this, _1), false)
{
  // set defaults
  debug_ = DEFAULT_DEBUG;
  int port = graspdb::Client::DEFAULT_PORT;
  string segmented_objects_topic("/segmentation/segmented_objects");
  string gripper_action_server("/manipulation/gripper");
  string lift_action_server("/manipulation/lift");
  string verify_grasp_action_server("/manipulation/verify_grasp");
  string host("127.0.0.1");
  string user("ros");
  string password("");
  string db("graspdb");

  // grab any parameters we need
  private_node_.getParam("debug", debug_);
  private_node_.getParam("robot_fixed_frame_id", robot_fixed_frame_id_);
  private_node_.getParam("eef_frame_id", eef_frame_id_);
  private_node_.getParam("segmented_objects_topic", segmented_objects_topic);
  private_node_.getParam("gripper_action_server", gripper_action_server);
  private_node_.getParam("lift_action_server", lift_action_server);
  private_node_.getParam("verify_grasp_action_server", verify_grasp_action_server);
  node_.getParam("/graspdb/host", host);
  node_.getParam("/graspdb/port", port);
  node_.getParam("/graspdb/user", user);
  node_.getParam("/graspdb/password", password);
  node_.getParam("/graspdb/db", db);

  // set up a connection to the grasp database
  graspdb_ = new graspdb::Client(host, port, user, password, db);
  okay_ = graspdb_->connect();

  // setup a debug publisher if we need it
  if (debug_)
  {
    debug_pub_ = private_node_.advertise<sensor_msgs::PointCloud2>("debug", 1);
  }

  // subscribe to the list of segmented objects
  segmented_objects_sub_ = node_.subscribe(segmented_objects_topic, 1, &GraspCollector::segmentedObjectsCallback,
      this);

  // setup action clients
  gripper_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::GripperAction>(gripper_action_server, true);
  lift_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::LiftAction>(lift_action_server, true);
  verify_grasp_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::VerifyGraspAction>(
      verify_grasp_action_server, true
  );

  // start the action server
  as_.start();

  if (okay_)
  {
    ROS_INFO("Grasp Collector Successfully Initialized");
  }
}

GraspCollector::~GraspCollector()
{
  // cleanup
  as_.shutdown();
  graspdb_->disconnect();
  delete gripper_ac_;
  delete lift_ac_;
  delete verify_grasp_ac_;
  delete graspdb_;
}

bool GraspCollector::okay() const
{
  return okay_;
}

void GraspCollector::graspAndStore(const rail_pick_and_place_msgs::GraspAndStoreGoalConstPtr &goal)
{
  ROS_INFO("Store grasp requset received.");

  rail_pick_and_place_msgs::GraspAndStoreFeedback feedback;
  rail_pick_and_place_msgs::GraspAndStoreResult result;
  // default to false
  result.success = false;
  result.id = 0;

  // used for action server checks
  bool completed, succeeded, success;

  // request a grasp from the arm
  feedback.message = "Requesting a close gripper action...";
  as_.publishFeedback(feedback);
  rail_manipulation_msgs::GripperGoal gripper_goal;
  gripper_goal.close = true;
  gripper_ac_->sendGoal(gripper_goal);
  completed = gripper_ac_->waitForResult(ac_wait_time_);
  succeeded = (gripper_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
  success = gripper_ac_->getResult()->success;
  if (!completed || !succeeded || !success)
  {
    as_.setSucceeded(result, "Could not close the gripper.");
    return;
  }

  // get the grasp position information
  feedback.message = "Determinging grasp position...";
  as_.publishFeedback(feedback);
  // get the TF from the buffer
  geometry_msgs::TransformStamped grasp;
  try
  {
    grasp = tf_buffer_.lookupTransform(robot_fixed_frame_id_, eef_frame_id_, ros::Time(0));
  } catch (tf2::TransformException &ex)
  {
    ROS_WARN("%s", ex.what());
    as_.setSucceeded(result, "Could not transform from the grasp frame to the robot fixed frame.");
    return;
  }

  // check if we are doing a lift
  if (goal->lift)
  {
    // request a lift from the arm
    feedback.message = "Requesting lift...";
    as_.publishFeedback(feedback);
    rail_manipulation_msgs::LiftGoal lift_goal;
    lift_ac_->sendGoal(lift_goal);
    completed = lift_ac_->waitForResult(ac_wait_time_);
    succeeded = (lift_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
    success = lift_ac_->getResult()->success;
    if (!completed || !succeeded || !success)
    {
      as_.setSucceeded(result, "Could not execute lift.");
      return;
    }
  }

  // check if we are doing a grasp verification check
  if (goal->verify)
  {
    // request a grasp verification from the arm
    feedback.message = "Requesting grasp verification...";
    as_.publishFeedback(feedback);
    rail_manipulation_msgs::VerifyGraspGoal verify_grasp_goal;
    verify_grasp_ac_->sendGoal(verify_grasp_goal);
    completed = verify_grasp_ac_->waitForResult(ac_wait_time_);
    succeeded = (verify_grasp_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
    rail_manipulation_msgs::VerifyGraspResultConstPtr verify_result = verify_grasp_ac_->getResult();
    success = verify_result->success;
    if (!completed || !succeeded || !success)
    {
      as_.setSucceeded(result, "Could not verify grasp.");
      return;
    } else if (!verify_result->grasping)
    {
      as_.setSucceeded(result, "Grasp is not verified.");
      return;
    }
  }

  // check for the closest object
  feedback.message = "Searching for the closest segmented object...";
  as_.publishFeedback(feedback);
  // lock for the vector
  {
    boost::mutex::scoped_lock lock(mutex_);
    // check if we actually have some objects
    int closest = 0;
    if (object_list_.objects.size() == 0)
    {
      as_.setSucceeded(result, "No segmented objects found.");
      return;
    } else if (object_list_.objects.size() > 1)
    {
      // find the closest point
      float min = numeric_limits<float>::infinity();
      //geometry_msgs::Vector3 &v = grasp.transform.translation;
      // check each segmented object
      for (size_t i = 0; i < object_list_.objects.size(); i++)
      {
        geometry_msgs::TransformStamped eef_transform = tf_buffer_.lookupTransform(object_list_.objects[i].point_cloud.header.frame_id, eef_frame_id_, ros::Time(0));
        geometry_msgs::Vector3 &v = eef_transform.transform.translation;
        //convert PointCloud2 to PointCloud to access the data easily
        sensor_msgs::PointCloud cloud;
        sensor_msgs::convertPointCloud2ToPointCloud(object_list_.objects[i].point_cloud, cloud);
        // check each point in the cloud
        for (size_t j = 0; j < cloud.points.size(); j++)
        {
          // euclidean distance to the point
          float dist = sqrt(
              pow(cloud.points[j].x - v.x, 2) + pow(cloud.points[j].y - v.y, 2) + pow(cloud.points[j].z - v.z, 2)
          );
          if (dist < min)
          {
            min = dist;
            closest = i;
          }
        }
      }
    }
    // check if we need to transform the point cloud
    rail_manipulation_msgs::SegmentedObject &object = object_list_.objects[closest];
    if (object.point_cloud.header.frame_id != robot_fixed_frame_id_)
    {
      try
      {
        //sensor_msgs::PointCloud2 transformed_cloud = tf_buffer_.transform(object.point_cloud, robot_fixed_frame_id_);
        sensor_msgs::PointCloud2 transformed_cloud = tf_buffer_.transform(object.point_cloud, robot_fixed_frame_id_, ros::Time(0), object.point_cloud.header.frame_id);
        object.point_cloud = transformed_cloud;
        object.point_cloud.header.frame_id = robot_fixed_frame_id_;
      } catch (tf2::TransformException &ex)
      {
        ROS_WARN("%s", ex.what());
        as_.setSucceeded(result, "Could not transform the segemented object to the robot fixed frame.");
        return;
      }
    }
    // check if we are going to publish some debug info
    if (debug_)
    {
      debug_pub_.publish(object.point_cloud);
    }

    // store the data
    feedback.message = "Storing grasp data...";
    as_.publishFeedback(feedback);
    graspdb::GraspDemonstration gd(goal->object_name, graspdb::Pose(grasp), eef_frame_id_, object.point_cloud);
    if (graspdb_->addGraspDemonstration(gd))
    {
      // store the ID
      result.id = gd.getID();
    } else
    {
      as_.setSucceeded(result, "Could not insert into database.");
      return;
    }
  }

  // success
  result.success = true;
  as_.setSucceeded(result, "Success!");
}

void GraspCollector::segmentedObjectsCallback(const rail_manipulation_msgs::SegmentedObjectList &object_list)
{
  ROS_INFO("Updated segmented object list received.");
  // lock for the vector
  boost::mutex::scoped_lock lock(mutex_);
  object_list_ = object_list;
}
<commit_msg>small fix<commit_after>/*!
 * \file GraspCollector.cpp
 * \brief The main grasp collector node object.
 *
 * The grasp collector is responsible for capturing and storing grasps. An action server is started is the main
 * entry point to grasp collecting.
 *
 * \author Russell Toris, WPI - rctoris@wpi.edu
 * \author David Kent, WPI - davidkent@wpi.edu
 * \date March 3, 2015
 */

#include <rail_grasp_collection/GraspCollector.h>
#include <tf2_sensor_msgs/tf2_sensor_msgs.h>

using namespace std;
using namespace rail::pick_and_place;

GraspCollector::GraspCollector()
    : private_node_("~"), ac_wait_time_(AC_WAIT_TIME), tf_listener_(tf_buffer_),
      robot_fixed_frame_id_("base_footprint"), eef_frame_id_("eef_link"),
      as_(private_node_, "grasp_and_store", boost::bind(&GraspCollector::graspAndStore, this, _1), false)
{
  // set defaults
  debug_ = DEFAULT_DEBUG;
  int port = graspdb::Client::DEFAULT_PORT;
  string segmented_objects_topic("/segmentation/segmented_objects");
  string gripper_action_server("/manipulation/gripper");
  string lift_action_server("/manipulation/lift");
  string verify_grasp_action_server("/manipulation/verify_grasp");
  string host("127.0.0.1");
  string user("ros");
  string password("");
  string db("graspdb");

  // grab any parameters we need
  private_node_.getParam("debug", debug_);
  private_node_.getParam("robot_fixed_frame_id", robot_fixed_frame_id_);
  private_node_.getParam("eef_frame_id", eef_frame_id_);
  private_node_.getParam("segmented_objects_topic", segmented_objects_topic);
  private_node_.getParam("gripper_action_server", gripper_action_server);
  private_node_.getParam("lift_action_server", lift_action_server);
  private_node_.getParam("verify_grasp_action_server", verify_grasp_action_server);
  node_.getParam("/graspdb/host", host);
  node_.getParam("/graspdb/port", port);
  node_.getParam("/graspdb/user", user);
  node_.getParam("/graspdb/password", password);
  node_.getParam("/graspdb/db", db);

  // set up a connection to the grasp database
  graspdb_ = new graspdb::Client(host, port, user, password, db);
  okay_ = graspdb_->connect();

  // setup a debug publisher if we need it
  if (debug_)
  {
    debug_pub_ = private_node_.advertise<sensor_msgs::PointCloud2>("debug", 1);
  }

  // subscribe to the list of segmented objects
  segmented_objects_sub_ = node_.subscribe(segmented_objects_topic, 1, &GraspCollector::segmentedObjectsCallback,
      this);

  // setup action clients
  gripper_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::GripperAction>(gripper_action_server, true);
  lift_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::LiftAction>(lift_action_server, true);
  verify_grasp_ac_ = new actionlib::SimpleActionClient<rail_manipulation_msgs::VerifyGraspAction>(
      verify_grasp_action_server, true
  );

  // start the action server
  as_.start();

  if (okay_)
  {
    ROS_INFO("Grasp Collector Successfully Initialized");
  }
}

GraspCollector::~GraspCollector()
{
  // cleanup
  as_.shutdown();
  graspdb_->disconnect();
  delete gripper_ac_;
  delete lift_ac_;
  delete verify_grasp_ac_;
  delete graspdb_;
}

bool GraspCollector::okay() const
{
  return okay_;
}

void GraspCollector::graspAndStore(const rail_pick_and_place_msgs::GraspAndStoreGoalConstPtr &goal)
{
  ROS_INFO("Store grasp requset received.");

  rail_pick_and_place_msgs::GraspAndStoreFeedback feedback;
  rail_pick_and_place_msgs::GraspAndStoreResult result;
  // default to false
  result.success = false;
  result.id = 0;

  // used for action server checks
  bool completed, succeeded, success;

  // request a grasp from the arm
  feedback.message = "Requesting a close gripper action...";
  as_.publishFeedback(feedback);
  rail_manipulation_msgs::GripperGoal gripper_goal;
  gripper_goal.close = true;
  gripper_ac_->sendGoal(gripper_goal);
  completed = gripper_ac_->waitForResult(ac_wait_time_);
  succeeded = (gripper_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
  success = gripper_ac_->getResult()->success;
  if (!completed || !succeeded || !success)
  {
    as_.setSucceeded(result, "Could not close the gripper.");
    return;
  }

  // get the grasp position information
  feedback.message = "Determinging grasp position...";
  as_.publishFeedback(feedback);
  // get the TF from the buffer
  geometry_msgs::TransformStamped grasp;
  try
  {
    grasp = tf_buffer_.lookupTransform(robot_fixed_frame_id_, eef_frame_id_, ros::Time(0));
  } catch (tf2::TransformException &ex)
  {
    ROS_WARN("%s", ex.what());
    as_.setSucceeded(result, "Could not transform from the grasp frame to the robot fixed frame.");
    return;
  }

  // check if we are doing a lift
  if (goal->lift)
  {
    // request a lift from the arm
    feedback.message = "Requesting lift...";
    as_.publishFeedback(feedback);
    rail_manipulation_msgs::LiftGoal lift_goal;
    lift_ac_->sendGoal(lift_goal);
    completed = lift_ac_->waitForResult(ac_wait_time_);
    succeeded = (lift_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
    success = lift_ac_->getResult()->success;
    if (!completed || !succeeded || !success)
    {
      as_.setSucceeded(result, "Could not execute lift.");
      return;
    }
  }

  // check if we are doing a grasp verification check
  if (goal->verify)
  {
    // request a grasp verification from the arm
    feedback.message = "Requesting grasp verification...";
    as_.publishFeedback(feedback);
    rail_manipulation_msgs::VerifyGraspGoal verify_grasp_goal;
    verify_grasp_ac_->sendGoal(verify_grasp_goal);
    completed = verify_grasp_ac_->waitForResult(ac_wait_time_);
    succeeded = (verify_grasp_ac_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
    rail_manipulation_msgs::VerifyGraspResultConstPtr verify_result = verify_grasp_ac_->getResult();
    success = verify_result->success;
    if (!completed || !succeeded || !success)
    {
      as_.setSucceeded(result, "Could not verify grasp.");
      return;
    } else if (!verify_result->grasping)
    {
      as_.setSucceeded(result, "Grasp is not verified.");
      return;
    }
  }

  // check for the closest object
  feedback.message = "Searching for the closest segmented object...";
  as_.publishFeedback(feedback);
  // lock for the vector
  {
    boost::mutex::scoped_lock lock(mutex_);
    // check if we actually have some objects
    int closest = 0;
    if (object_list_.objects.size() == 0)
    {
      as_.setSucceeded(result, "No segmented objects found.");
      return;
    } else if (object_list_.objects.size() > 1)
    {
      // find the closest point
      float min = numeric_limits<float>::infinity();
      //geometry_msgs::Vector3 &v = grasp.transform.translation;
      // check each segmented object
      for (size_t i = 0; i < object_list_.objects.size(); i++)
      {
        geometry_msgs::TransformStamped eef_transform = tf_buffer_.lookupTransform(
            object_list_.objects[i].point_cloud.header.frame_id, eef_frame_id_, ros::Time(0)
        );
        geometry_msgs::Vector3 &v = eef_transform.transform.translation;
        //convert PointCloud2 to PointCloud to access the data easily
        sensor_msgs::PointCloud cloud;
        sensor_msgs::convertPointCloud2ToPointCloud(object_list_.objects[i].point_cloud, cloud);
        // check each point in the cloud
        for (size_t j = 0; j < cloud.points.size(); j++)
        {
          // euclidean distance to the point
          float dist = sqrt(
              pow(cloud.points[j].x - v.x, 2) + pow(cloud.points[j].y - v.y, 2) + pow(cloud.points[j].z - v.z, 2)
          );
          if (dist < min)
          {
            min = dist;
            closest = i;
          }
        }
      }
    }
    // check if we need to transform the point cloud
    rail_manipulation_msgs::SegmentedObject &object = object_list_.objects[closest];
    if (object.point_cloud.header.frame_id != robot_fixed_frame_id_)
    {
      try
      {
        sensor_msgs::PointCloud2 transformed_cloud = tf_buffer_.transform(object.point_cloud, robot_fixed_frame_id_,
            ros::Time(0), object.point_cloud.header.frame_id);
        object.point_cloud = transformed_cloud;
        object.point_cloud.header.frame_id = robot_fixed_frame_id_;
      } catch (tf2::TransformException &ex)
      {
        ROS_WARN("%s", ex.what());
        as_.setSucceeded(result, "Could not transform the segemented object to the robot fixed frame.");
        return;
      }
    }
    // check if we are going to publish some debug info
    if (debug_)
    {
      debug_pub_.publish(object.point_cloud);
    }

    // store the data
    feedback.message = "Storing grasp data...";
    as_.publishFeedback(feedback);
    graspdb::GraspDemonstration gd(goal->object_name, graspdb::Pose(grasp), eef_frame_id_, object.point_cloud);
    if (graspdb_->addGraspDemonstration(gd))
    {
      // store the ID
      result.id = gd.getID();
    } else
    {
      as_.setSucceeded(result, "Could not insert into database.");
      return;
    }
  }

  // success
  result.success = true;
  as_.setSucceeded(result, "Success!");
}

void GraspCollector::segmentedObjectsCallback(const rail_manipulation_msgs::SegmentedObjectList &object_list)
{
  ROS_INFO("Updated segmented object list received.");
  // lock for the vector
  boost::mutex::scoped_lock lock(mutex_);
  object_list_ = object_list;
}
<|endoftext|>


<commit_before><commit_msg>Fixed wrong height in zero axis when negative values are shown using Fused lines mode.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fusnapln.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-12-14 17:04:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "fusnapln.hxx"

#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#pragma hdrstop

#include "strings.hrc"

#include "sdattr.hxx"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_WINDOW_SHELL_HXX
#include "Window.hxx"
#endif
//CHINA001 #include "dlgsnap.hxx"
#include "sdenumdef.hxx" //CHINA001
#include "sdresid.hxx"
#include "sdabstdlg.hxx" //CHINA001
#include "dlgsnap.hrc" //CHINA001
#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif

namespace sd {

TYPEINIT1( FuSnapLine, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuSnapLine::FuSnapLine(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
                       SdDrawDocument* pDoc, SfxRequest& rReq) :
    FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuSnapLine::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    FunctionReference xFunc( new FuSnapLine( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

void FuSnapLine::DoExecute( SfxRequest& rReq )
{
    const SfxItemSet* pArgs = rReq.GetArgs();
    SdrPageView* pPV;
    USHORT  nHelpLine;
    BOOL    bCreateNew = TRUE;

    if ( !pArgs )
    {
        SfxItemSet aNewAttr(pViewShell->GetPool(), ATTR_SNAPLINE_START,
                                                ATTR_SNAPLINE_END);
        Point aLinePos = static_cast<DrawViewShell*>(pViewShell)->GetMousePos();
        static_cast<DrawViewShell*>(pViewShell)->SetMousePosFreezed( FALSE );
        BOOL bLineExist = FALSE;

        pPV = pView->GetPageViewPvNum(0);

        if ( aLinePos.X() >= 0 )
        {
            aLinePos = pWindow->PixelToLogic(aLinePos);
            USHORT nHitLog = (USHORT) pWindow->PixelToLogic(Size(HITPIX,0)).Width();
            bLineExist = pView->PickHelpLine(aLinePos, nHitLog, *pWindow,
                                             nHelpLine, pPV);
            if ( bLineExist )
                aLinePos = (pPV->GetHelpLines())[nHelpLine].GetPos();
            else
                pPV = pView->GetPageViewPvNum(0);

            pPV->LogicToPagePos(aLinePos);
        }
        else
            aLinePos = Point(0,0);

        aNewAttr.Put(SfxUInt32Item(ATTR_SNAPLINE_X, aLinePos.X()));
        aNewAttr.Put(SfxUInt32Item(ATTR_SNAPLINE_Y, aLinePos.Y()));

        //CHINA001 SdSnapLineDlg* pDlg = new SdSnapLineDlg( NULL, aNewAttr, pView );
        SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();//CHINA001
        DBG_ASSERT(pFact, "SdAbstractDialogFactory fail!");//CHINA001
        AbstractSdSnapLineDlg* pDlg = pFact->CreateSdSnapLineDlg(ResId( DLG_SNAPLINE ), NULL, aNewAttr, pView );
        DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
        if ( bLineExist )
        {
            pDlg->HideRadioGroup();

            const SdrHelpLine& rHelpLine = (pPV->GetHelpLines())[nHelpLine];

            if ( rHelpLine.GetKind() == SDRHELPLINE_POINT )
            {
                pDlg->SetText(String(SdResId(STR_SNAPDLG_SETPOINT)));
                pDlg->SetInputFields(TRUE, TRUE);
            }
            else
            {
                pDlg->SetText(String(SdResId(STR_SNAPDLG_SETLINE)));

                if ( rHelpLine.GetKind() == SDRHELPLINE_VERTICAL )
                    pDlg->SetInputFields(TRUE, FALSE);
                else
                    pDlg->SetInputFields(FALSE, TRUE);
            }
            bCreateNew = FALSE;
        }
        else
            pDlg->HideDeleteBtn();

        USHORT nResult = pDlg->Execute();

        pDlg->GetAttr(aNewAttr);
        delete pDlg;

        switch( nResult )
        {
            case RET_OK:
                rReq.Done(aNewAttr);
                pArgs = rReq.GetArgs();
                break;

            case RET_SNAP_DELETE:
                // Fangobjekt loeschen
                if ( !bCreateNew )
                    pPV->DeleteHelpLine(nHelpLine);
                // und weiter wie bei default
            default:
                return;
        }
    }
    Point aHlpPos;

    aHlpPos.X() = ((const SfxUInt32Item&) pArgs->Get(ATTR_SNAPLINE_X)).GetValue();
    aHlpPos.Y() = ((const SfxUInt32Item&) pArgs->Get(ATTR_SNAPLINE_Y)).GetValue();
    pPV->PagePosToLogic(aHlpPos);

    if ( bCreateNew )
    {
        SdrHelpLineKind eKind;

        pPV = pView->GetPageViewPvNum(0);

        switch ( (SnapKind) ((const SfxAllEnumItem&)
                 pArgs->Get(ATTR_SNAPLINE_KIND)).GetValue() )
        {
            case SK_HORIZONTAL  : eKind = SDRHELPLINE_HORIZONTAL;   break;
            case SK_VERTICAL    : eKind = SDRHELPLINE_VERTICAL;     break;
            default             : eKind = SDRHELPLINE_POINT;        break;
        }
        pPV->InsertHelpLine(SdrHelpLine(eKind, aHlpPos));
    }
    else
    {
        const SdrHelpLine& rHelpLine = (pPV->GetHelpLines())[nHelpLine];
        pPV->SetHelpLine(nHelpLine, SdrHelpLine(rHelpLine.GetKind(), aHlpPos));
    }
}

void FuSnapLine::Activate()
{
}

void FuSnapLine::Deactivate()
{
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS pchfix02 (1.5.212); FILE MERGED 2006/09/01 17:37:10 kaib 1.5.212.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fusnapln.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 18:56:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "fusnapln.hxx"

#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#include "strings.hrc"

#include "sdattr.hxx"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_WINDOW_SHELL_HXX
#include "Window.hxx"
#endif
//CHINA001 #include "dlgsnap.hxx"
#include "sdenumdef.hxx" //CHINA001
#include "sdresid.hxx"
#include "sdabstdlg.hxx" //CHINA001
#include "dlgsnap.hrc" //CHINA001
#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif

namespace sd {

TYPEINIT1( FuSnapLine, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuSnapLine::FuSnapLine(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
                       SdDrawDocument* pDoc, SfxRequest& rReq) :
    FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuSnapLine::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    FunctionReference xFunc( new FuSnapLine( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

void FuSnapLine::DoExecute( SfxRequest& rReq )
{
    const SfxItemSet* pArgs = rReq.GetArgs();
    SdrPageView* pPV;
    USHORT  nHelpLine;
    BOOL    bCreateNew = TRUE;

    if ( !pArgs )
    {
        SfxItemSet aNewAttr(pViewShell->GetPool(), ATTR_SNAPLINE_START,
                                                ATTR_SNAPLINE_END);
        Point aLinePos = static_cast<DrawViewShell*>(pViewShell)->GetMousePos();
        static_cast<DrawViewShell*>(pViewShell)->SetMousePosFreezed( FALSE );
        BOOL bLineExist = FALSE;

        pPV = pView->GetPageViewPvNum(0);

        if ( aLinePos.X() >= 0 )
        {
            aLinePos = pWindow->PixelToLogic(aLinePos);
            USHORT nHitLog = (USHORT) pWindow->PixelToLogic(Size(HITPIX,0)).Width();
            bLineExist = pView->PickHelpLine(aLinePos, nHitLog, *pWindow,
                                             nHelpLine, pPV);
            if ( bLineExist )
                aLinePos = (pPV->GetHelpLines())[nHelpLine].GetPos();
            else
                pPV = pView->GetPageViewPvNum(0);

            pPV->LogicToPagePos(aLinePos);
        }
        else
            aLinePos = Point(0,0);

        aNewAttr.Put(SfxUInt32Item(ATTR_SNAPLINE_X, aLinePos.X()));
        aNewAttr.Put(SfxUInt32Item(ATTR_SNAPLINE_Y, aLinePos.Y()));

        //CHINA001 SdSnapLineDlg* pDlg = new SdSnapLineDlg( NULL, aNewAttr, pView );
        SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();//CHINA001
        DBG_ASSERT(pFact, "SdAbstractDialogFactory fail!");//CHINA001
        AbstractSdSnapLineDlg* pDlg = pFact->CreateSdSnapLineDlg(ResId( DLG_SNAPLINE ), NULL, aNewAttr, pView );
        DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
        if ( bLineExist )
        {
            pDlg->HideRadioGroup();

            const SdrHelpLine& rHelpLine = (pPV->GetHelpLines())[nHelpLine];

            if ( rHelpLine.GetKind() == SDRHELPLINE_POINT )
            {
                pDlg->SetText(String(SdResId(STR_SNAPDLG_SETPOINT)));
                pDlg->SetInputFields(TRUE, TRUE);
            }
            else
            {
                pDlg->SetText(String(SdResId(STR_SNAPDLG_SETLINE)));

                if ( rHelpLine.GetKind() == SDRHELPLINE_VERTICAL )
                    pDlg->SetInputFields(TRUE, FALSE);
                else
                    pDlg->SetInputFields(FALSE, TRUE);
            }
            bCreateNew = FALSE;
        }
        else
            pDlg->HideDeleteBtn();

        USHORT nResult = pDlg->Execute();

        pDlg->GetAttr(aNewAttr);
        delete pDlg;

        switch( nResult )
        {
            case RET_OK:
                rReq.Done(aNewAttr);
                pArgs = rReq.GetArgs();
                break;

            case RET_SNAP_DELETE:
                // Fangobjekt loeschen
                if ( !bCreateNew )
                    pPV->DeleteHelpLine(nHelpLine);
                // und weiter wie bei default
            default:
                return;
        }
    }
    Point aHlpPos;

    aHlpPos.X() = ((const SfxUInt32Item&) pArgs->Get(ATTR_SNAPLINE_X)).GetValue();
    aHlpPos.Y() = ((const SfxUInt32Item&) pArgs->Get(ATTR_SNAPLINE_Y)).GetValue();
    pPV->PagePosToLogic(aHlpPos);

    if ( bCreateNew )
    {
        SdrHelpLineKind eKind;

        pPV = pView->GetPageViewPvNum(0);

        switch ( (SnapKind) ((const SfxAllEnumItem&)
                 pArgs->Get(ATTR_SNAPLINE_KIND)).GetValue() )
        {
            case SK_HORIZONTAL  : eKind = SDRHELPLINE_HORIZONTAL;   break;
            case SK_VERTICAL    : eKind = SDRHELPLINE_VERTICAL;     break;
            default             : eKind = SDRHELPLINE_POINT;        break;
        }
        pPV->InsertHelpLine(SdrHelpLine(eKind, aHlpPos));
    }
    else
    {
        const SdrHelpLine& rHelpLine = (pPV->GetHelpLines())[nHelpLine];
        pPV->SetHelpLine(nHelpLine, SdrHelpLine(rHelpLine.GetKind(), aHlpPos));
    }
}

void FuSnapLine::Activate()
{
}

void FuSnapLine::Deactivate()
{
}

} // end of namespace sd
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drviewsd.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 19:15:31 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "DrawViewShell.hxx"

#ifndef _SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXDOCFILE_HXX //autogen
#include <sfx2/docfile.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif

#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#include <sfx2/viewfrm.hxx>

#include "app.hrc"

#include "sdpage.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#ifndef _SD_SLIDESHOW_HXX
#include "slideshow.hxx"
#endif
#include "pgjump.hxx"
#ifndef SD_NAVIGATOR_CHILD_WINDOW_HXX
#include "NavigatorChildWindow.hxx"
#endif
#ifndef SD_NAVIGATION_HXX
#include "navigatr.hxx"
#endif
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#ifndef _SD_SLIDESHOW_HXX
#include "slideshow.hxx"
#endif

namespace sd {

/*************************************************************************
|*
|* SfxRequests fuer Navigator bearbeiten
|*
\************************************************************************/

void DrawViewShell::ExecNavigatorWin( SfxRequest& rReq )
{
    CheckLineTo (rReq);

    USHORT nSId = rReq.GetSlot();

    switch( nSId )
    {
        case SID_NAVIGATOR_INIT:
        {
            USHORT nId = SID_NAVIGATOR;
            SfxChildWindow* pWindow = GetViewFrame()->GetChildWindow( nId );
            if( pWindow )
            {
                SdNavigatorWin* pNavWin = (SdNavigatorWin*)( pWindow->GetContextWindow( SD_MOD() ) );
                if( pNavWin )
                    pNavWin->InitTreeLB( GetDoc() );
            }
        }
        break;

        case SID_NAVIGATOR_PEN:
        case SID_NAVIGATOR_PAGE:
        case SID_NAVIGATOR_OBJECT:
        {
            if (mpSlideShow)
            {
                mpSlideShow->receiveRequest( rReq );
            }
            else if (nSId == SID_NAVIGATOR_PAGE)
            {
                if ( mpDrawView->IsTextEdit() )
                    mpDrawView->SdrEndTextEdit();

                const SfxItemSet* pArgs = rReq.GetArgs();
                PageJump eJump = (PageJump)((SfxAllEnumItem&) pArgs->
                                  Get(SID_NAVIGATOR_PAGE)).GetValue();

                switch (eJump)
                {
                    case PAGE_FIRST:
                    {
                        // Sprung zu erster Seite
                        SwitchPage(0);
                    }
                    break;

                    case PAGE_LAST:
                    {
                        // Sprung zu letzter Seite
                        SwitchPage(GetDoc()->GetSdPageCount(mpActualPage->GetPageKind()) - 1);
                    }
                    break;

                    case PAGE_NEXT:
                    {
                        // Sprung zu naechster Seite
                        USHORT nSdPage = (mpActualPage->GetPageNum() - 1) / 2;

                        if (nSdPage < GetDoc()->GetSdPageCount(mpActualPage->GetPageKind()) - 1)
                        {
                            SwitchPage(nSdPage + 1);
                        }
                    }
                    break;

                    case PAGE_PREVIOUS:
                    {
                        // Sprung zu vorheriger Seite
                        USHORT nSdPage = (mpActualPage->GetPageNum() - 1) / 2;

                        if (nSdPage > 0)
                        {
                            SwitchPage(nSdPage - 1);
                        }
                    }
                    break;

                    case PAGE_NONE:
                        break;
                }
            }
            else if (nSId == SID_NAVIGATOR_OBJECT)
            {
                String aBookmarkStr;
                aBookmarkStr += sal_Unicode( '#' );
                const SfxItemSet* pArgs = rReq.GetArgs();
                String aTarget = ((SfxStringItem&) pArgs->
                                 Get(SID_NAVIGATOR_OBJECT)).GetValue();
                aBookmarkStr += aTarget;
                SfxStringItem aStrItem(SID_FILE_NAME, aBookmarkStr);
                SfxStringItem aReferer(SID_REFERER, GetDocSh()->GetMedium()->GetName());
                SfxViewFrame* pFrame = GetViewFrame();
                SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
                SfxBoolItem aBrowseItem(SID_BROWSE, TRUE);
                pFrame->GetDispatcher()->
                Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
                            &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L);
            }

            SfxBindings& rBindings = GetViewFrame()->GetBindings();
            rBindings.Invalidate( SID_NAVIGATOR_STATE );
            rBindings.Invalidate( SID_NAVIGATOR_PAGENAME );
        }
        break;

        default:
        break;
    }
}

/*************************************************************************
|*
|* Statuswerte fuer Navigator zurueckgeben
|*
\************************************************************************/

void DrawViewShell::GetNavigatorWinState( SfxItemSet& rSet )
{
    UINT32 nState = NAVSTATE_NONE;
    USHORT nCurrentPage = 0;
    USHORT nFirstPage = 0;
    USHORT nLastPage;
    BOOL   bEndless = FALSE;
    String aPageName;

    if( mpSlideShow )
    {
        // pen activated?
        nState |= mpSlideShow->isDrawingPossible() ? NAVBTN_PEN_CHECKED : NAVBTN_PEN_UNCHECKED;

        nCurrentPage = (USHORT)mpSlideShow->getCurrentPageNumber();
        nFirstPage = (USHORT)mpSlideShow->getFirstPageNumber();
        nLastPage = (USHORT)mpSlideShow->getLastPageNumber();
        bEndless = mpSlideShow->isEndless();

        // Get the page for the current page number.
        SdPage* pPage = 0;
        if( nCurrentPage < GetDoc()->GetSdPageCount( PK_STANDARD ) )
            pPage = GetDoc()->GetSdPage (nCurrentPage, PK_STANDARD);

        if(pPage)
            aPageName = pPage->GetName();
    }
    else
    {
        nState |= NAVBTN_PEN_DISABLED | NAVTLB_UPDATE;

        if (mpActualPage != NULL)
        {
            nCurrentPage = ( mpActualPage->GetPageNum() - 1 ) / 2;
            aPageName = mpActualPage->GetName();
        }
        nLastPage = GetDoc()->GetSdPageCount( mePageKind ) - 1;
    }

    // erste Seite / vorherige Seite
    if( nCurrentPage == nFirstPage )
    {
        nState |= NAVBTN_FIRST_DISABLED;
        if( !bEndless )
            nState |= NAVBTN_PREV_DISABLED;
        else
            nState |= NAVBTN_PREV_ENABLED;
    }
    else
    {
        nState |= NAVBTN_FIRST_ENABLED | NAVBTN_PREV_ENABLED;
    }

    // letzte Seite / naechste Seite
    if( nCurrentPage == nLastPage )
    {
        nState |= NAVBTN_LAST_DISABLED;
        if( !bEndless )
            nState |= NAVBTN_NEXT_DISABLED;
        else
            nState |= NAVBTN_NEXT_ENABLED;
    }
    else
    {
        nState |= NAVBTN_LAST_ENABLED | NAVBTN_NEXT_ENABLED;
    }

    rSet.Put( SfxUInt32Item( SID_NAVIGATOR_STATE, nState ) );
    rSet.Put( SfxStringItem( SID_NAVIGATOR_PAGENAME, aPageName ) );
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS presenterview (1.11.54); FILE MERGED 2008/01/09 18:28:26 cl 1.11.54.1: #i15900# slideshow api consolidation<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drviewsd.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-03 15:18:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "DrawViewShell.hxx"

#ifndef _SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXDOCFILE_HXX //autogen
#include <sfx2/docfile.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif

#ifndef _SFX_BINDINGS_HXX //autogen
#include <sfx2/bindings.hxx>
#endif

#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif

#include <sfx2/viewfrm.hxx>

#include "app.hrc"

#include "sdpage.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#ifndef _SD_SLIDESHOW_HXX
#include "slideshow.hxx"
#endif
#include "pgjump.hxx"
#ifndef SD_NAVIGATOR_CHILD_WINDOW_HXX
#include "NavigatorChildWindow.hxx"
#endif
#ifndef SD_NAVIGATION_HXX
#include "navigatr.hxx"
#endif
#ifndef SD_DRAW_VIEW_HXX
#include "drawview.hxx"
#endif
#ifndef _SD_SLIDESHOW_HXX
#include "slideshow.hxx"
#endif

namespace sd {

/*************************************************************************
|*
|* SfxRequests fuer Navigator bearbeiten
|*
\************************************************************************/

void DrawViewShell::ExecNavigatorWin( SfxRequest& rReq )
{
    CheckLineTo (rReq);

    USHORT nSId = rReq.GetSlot();

    switch( nSId )
    {
        case SID_NAVIGATOR_INIT:
        {
            USHORT nId = SID_NAVIGATOR;
            SfxChildWindow* pWindow = GetViewFrame()->GetChildWindow( nId );
            if( pWindow )
            {
                SdNavigatorWin* pNavWin = (SdNavigatorWin*)( pWindow->GetContextWindow( SD_MOD() ) );
                if( pNavWin )
                    pNavWin->InitTreeLB( GetDoc() );
            }
        }
        break;

        case SID_NAVIGATOR_PEN:
        case SID_NAVIGATOR_PAGE:
        case SID_NAVIGATOR_OBJECT:
        {
            rtl::Reference< SlideShow > xSlideshow( SlideShow::GetSlideShow( GetViewShellBase() ) );
            if (xSlideshow.is() && xSlideshow->isRunning() )
            {
                xSlideshow->receiveRequest( rReq );
            }
            else if (nSId == SID_NAVIGATOR_PAGE)
            {
                if ( mpDrawView->IsTextEdit() )
                    mpDrawView->SdrEndTextEdit();

                const SfxItemSet* pArgs = rReq.GetArgs();
                PageJump eJump = (PageJump)((SfxAllEnumItem&) pArgs->
                                  Get(SID_NAVIGATOR_PAGE)).GetValue();

                switch (eJump)
                {
                    case PAGE_FIRST:
                    {
                        // Sprung zu erster Seite
                        SwitchPage(0);
                    }
                    break;

                    case PAGE_LAST:
                    {
                        // Sprung zu letzter Seite
                        SwitchPage(GetDoc()->GetSdPageCount(mpActualPage->GetPageKind()) - 1);
                    }
                    break;

                    case PAGE_NEXT:
                    {
                        // Sprung zu naechster Seite
                        USHORT nSdPage = (mpActualPage->GetPageNum() - 1) / 2;

                        if (nSdPage < GetDoc()->GetSdPageCount(mpActualPage->GetPageKind()) - 1)
                        {
                            SwitchPage(nSdPage + 1);
                        }
                    }
                    break;

                    case PAGE_PREVIOUS:
                    {
                        // Sprung zu vorheriger Seite
                        USHORT nSdPage = (mpActualPage->GetPageNum() - 1) / 2;

                        if (nSdPage > 0)
                        {
                            SwitchPage(nSdPage - 1);
                        }
                    }
                    break;

                    case PAGE_NONE:
                        break;
                }
            }
            else if (nSId == SID_NAVIGATOR_OBJECT)
            {
                String aBookmarkStr;
                aBookmarkStr += sal_Unicode( '#' );
                const SfxItemSet* pArgs = rReq.GetArgs();
                String aTarget = ((SfxStringItem&) pArgs->
                                 Get(SID_NAVIGATOR_OBJECT)).GetValue();
                aBookmarkStr += aTarget;
                SfxStringItem aStrItem(SID_FILE_NAME, aBookmarkStr);
                SfxStringItem aReferer(SID_REFERER, GetDocSh()->GetMedium()->GetName());
                SfxViewFrame* pFrame = GetViewFrame();
                SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
                SfxBoolItem aBrowseItem(SID_BROWSE, TRUE);
                pFrame->GetDispatcher()->
                Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
                            &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L);
            }

            SfxBindings& rBindings = GetViewFrame()->GetBindings();
            rBindings.Invalidate( SID_NAVIGATOR_STATE );
            rBindings.Invalidate( SID_NAVIGATOR_PAGENAME );
        }
        break;

        default:
        break;
    }
}

/*************************************************************************
|*
|* Statuswerte fuer Navigator zurueckgeben
|*
\************************************************************************/

void DrawViewShell::GetNavigatorWinState( SfxItemSet& rSet )
{
    UINT32 nState = NAVSTATE_NONE;
    USHORT nCurrentPage = 0;
    USHORT nFirstPage = 0;
    USHORT nLastPage;
    BOOL   bEndless = FALSE;
    String aPageName;

    rtl::Reference< SlideShow > xSlideshow( SlideShow::GetSlideShow( GetViewShellBase() ) );
    if( xSlideshow.is() && xSlideshow->isRunning() )
    {
        // pen activated?
        nState |= xSlideshow->isDrawingPossible() ? NAVBTN_PEN_CHECKED : NAVBTN_PEN_UNCHECKED;

        nCurrentPage = (USHORT)xSlideshow->getCurrentPageNumber();
        nFirstPage = (USHORT)xSlideshow->getFirstPageNumber();
        nLastPage = (USHORT)xSlideshow->getLastPageNumber();
        bEndless = xSlideshow->isEndless();

        // Get the page for the current page number.
        SdPage* pPage = 0;
        if( nCurrentPage < GetDoc()->GetSdPageCount( PK_STANDARD ) )
            pPage = GetDoc()->GetSdPage (nCurrentPage, PK_STANDARD);

        if(pPage)
            aPageName = pPage->GetName();
    }
    else
    {
        nState |= NAVBTN_PEN_DISABLED | NAVTLB_UPDATE;

        if (mpActualPage != NULL)
        {
            nCurrentPage = ( mpActualPage->GetPageNum() - 1 ) / 2;
            aPageName = mpActualPage->GetName();
        }
        nLastPage = GetDoc()->GetSdPageCount( mePageKind ) - 1;
    }

    // erste Seite / vorherige Seite
    if( nCurrentPage == nFirstPage )
    {
        nState |= NAVBTN_FIRST_DISABLED;
        if( !bEndless )
            nState |= NAVBTN_PREV_DISABLED;
        else
            nState |= NAVBTN_PREV_ENABLED;
    }
    else
    {
        nState |= NAVBTN_FIRST_ENABLED | NAVBTN_PREV_ENABLED;
    }

    // letzte Seite / naechste Seite
    if( nCurrentPage == nLastPage )
    {
        nState |= NAVBTN_LAST_DISABLED;
        if( !bEndless )
            nState |= NAVBTN_NEXT_DISABLED;
        else
            nState |= NAVBTN_NEXT_ENABLED;
    }
    else
    {
        nState |= NAVBTN_LAST_ENABLED | NAVBTN_NEXT_ENABLED;
    }

    rSet.Put( SfxUInt32Item( SID_NAVIGATOR_STATE, nState ) );
    rSet.Put( SfxStringItem( SID_NAVIGATOR_PAGENAME, aPageName ) );
}

} // end of namespace sd
<|endoftext|>