<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/ime_adapter_android.h"

#include <android/input.h>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/common/view_messages.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "jni/ImeAdapter_jni.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"

using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;

namespace content {
namespace {

// Maps a java KeyEvent into a NativeWebKeyboardEvent.
// |java_key_event| is used to maintain a globalref for KeyEvent.
// |action| will help determine the WebInputEvent type.
// type, |modifiers|, |time_ms|, |key_code|, |unicode_char| is used to create
// WebKeyboardEvent. |key_code| is also needed ad need to treat the enter key
// as a key press of character \r.
NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent(
    JNIEnv* env,
    jobject java_key_event,
    int action,
    int modifiers,
    long time_ms,
    int key_code,
    bool is_system_key,
    int unicode_char) {
  WebKit::WebInputEvent::Type type = WebKit::WebInputEvent::Undefined;
  if (action == AKEY_EVENT_ACTION_DOWN)
    type = WebKit::WebInputEvent::RawKeyDown;
  else if (action == AKEY_EVENT_ACTION_UP)
    type = WebKit::WebInputEvent::KeyUp;
  return NativeWebKeyboardEvent(java_key_event, type, modifiers,
      time_ms, key_code, unicode_char, is_system_key);
}

}  // anonymous namespace

bool RegisterImeAdapter(JNIEnv* env) {
  if (!RegisterNativesImpl(env))
    return false;

  Java_ImeAdapter_initializeWebInputEvents(env,
                                           WebKit::WebInputEvent::RawKeyDown,
                                           WebKit::WebInputEvent::KeyUp,
                                           WebKit::WebInputEvent::Char,
                                           WebKit::WebInputEvent::ShiftKey,
                                           WebKit::WebInputEvent::AltKey,
                                           WebKit::WebInputEvent::ControlKey,
                                           WebKit::WebInputEvent::CapsLockOn,
                                           WebKit::WebInputEvent::NumLockOn);
  // TODO(miguelg): remove date time related enums after
  // https://bugs.webkit.org/show_bug.cgi?id=100935.
  Java_ImeAdapter_initializeTextInputTypes(
      env,
      ui::TEXT_INPUT_TYPE_NONE,
      ui::TEXT_INPUT_TYPE_TEXT,
      ui::TEXT_INPUT_TYPE_TEXT_AREA,
      ui::TEXT_INPUT_TYPE_PASSWORD,
      ui::TEXT_INPUT_TYPE_SEARCH,
      ui::TEXT_INPUT_TYPE_URL,
      ui::TEXT_INPUT_TYPE_EMAIL,
      ui::TEXT_INPUT_TYPE_TELEPHONE,
      ui::TEXT_INPUT_TYPE_NUMBER,
      ui::TEXT_INPUT_TYPE_DATE,
      ui::TEXT_INPUT_TYPE_DATE_TIME,
      ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL,
      ui::TEXT_INPUT_TYPE_MONTH,
      ui::TEXT_INPUT_TYPE_TIME,
      ui::TEXT_INPUT_TYPE_WEEK,
      ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE);
  return true;
}

ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva)
    : rwhva_(rwhva) {
}

ImeAdapterAndroid::~ImeAdapterAndroid() {
  JNIEnv* env = AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
  if (!obj.is_null())
    Java_ImeAdapter_detach(env, obj.obj());
}

bool ImeAdapterAndroid::SendSyntheticKeyEvent(JNIEnv*,
                                              jobject,
                                              int type,
                                              long time_ms,
                                              int key_code,
                                              int text) {
  NativeWebKeyboardEvent event(static_cast<WebKit::WebInputEvent::Type>(type),
                               0 /* modifiers */, time_ms / 1000.0, key_code,
                               text, false /* is_system_key */);
  rwhva_->SendKeyEvent(event);
  return true;
}

bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject,
                                     jobject original_key_event,
                                     int action, int modifiers,
                                     long time_ms, int key_code,
                                     bool is_system_key, int unicode_char) {
  NativeWebKeyboardEvent event = NativeWebKeyboardEventFromKeyEvent(
          env, original_key_event, action, modifiers,
          time_ms, key_code, is_system_key, unicode_char);
  rwhva_->SendKeyEvent(event);
  if (event.type == WebKit::WebInputEvent::RawKeyDown && event.text[0]) {
    // Send a Char event, but without an os_event since we don't want to
    // roundtrip back to java such synthetic event.
    NativeWebKeyboardEvent char_event(event);
    char_event.os_event = NULL;
    event.type = WebKit::WebInputEvent::Char;
    rwhva_->SendKeyEvent(event);
  }
  return true;
}

void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text,
                                         int new_cursor_pos) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  string16 text16 = ConvertJavaStringToUTF16(env, text);
  std::vector<WebKit::WebCompositionUnderline> underlines;
  underlines.push_back(
      WebKit::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK,
                                      false));
  // new_cursor_position is as described in the Android API for
  // InputConnection#setComposingText, whereas the parameters for
  // ImeSetComposition are relative to the start of the composition.
  if (new_cursor_pos > 0)
    new_cursor_pos = text16.length() + new_cursor_pos - 1;

  rwhi->ImeSetComposition(text16, underlines, new_cursor_pos, new_cursor_pos);
}

void ImeAdapterAndroid::ImeBatchStateChanged(JNIEnv* env,
                                             jobject,
                                             jboolean is_begin) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_ImeBatchStateChanged(rwhi->GetRoutingID(), is_begin));
}

void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  string16 text16 = ConvertJavaStringToUTF16(env, text);
  rwhi->ImeConfirmComposition(text16);
}

void ImeAdapterAndroid::AttachImeAdapter(JNIEnv* env, jobject java_object) {
  java_ime_adapter_ = JavaObjectWeakGlobalRef(env, java_object);
}

void ImeAdapterAndroid::CancelComposition() {
  base::android::ScopedJavaLocalRef<jobject> obj =
      java_ime_adapter_.get(AttachCurrentThread());
  if (!obj.is_null())
    Java_ImeAdapter_cancelComposition(AttachCurrentThread(), obj.obj());
}

void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject,
                                                    int start, int end) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_SetEditableSelectionOffsets(rwhi->GetRoutingID(),
                                                     start, end));
}

void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject,
                                           int start, int end) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  std::vector<WebKit::WebCompositionUnderline> underlines;
  underlines.push_back(
      WebKit::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false));

  rwhi->Send(new ViewMsg_SetCompositionFromExistingText(
      rwhi->GetRoutingID(), start, end, underlines));
}

void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, jobject,
                                              int before, int after) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_ExtendSelectionAndDelete(rwhi->GetRoutingID(),
                                                  before, after));
}

void ImeAdapterAndroid::Unselect(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Unselect();
}

void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->SelectAll();
}

void ImeAdapterAndroid::Cut(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Cut();
}

void ImeAdapterAndroid::Copy(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Copy();
}

void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Paste();
}

void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) {
  java_ime_adapter_.reset();
}

}  // namespace content
<commit_msg>[Android] Change "handling" of unhandled key events.          When we receive an IME Key Down event in Android, we forward it to     WebKit for processing as RawKeyDown, followed by a WebInputEvent::Char     if it had a character associated with it.          When typing into a text field or textarea, if the RawKeyDown  triggers     an editing event it will go unhandled by WebKit, and it's the subsequent     Char event that WebKit handles. The unhandled RawKeyDown is propogated     back down to the Browser and out to the embedder. In the Android WebView     where we then propogate the unhandled event to the WebView embedder.          However - as the Char event is going to be handled by the textarea     later, informing the embedder that the KeyDown wasn't handled isn't     what it expects and we shouldn't do so. We should only propogate an     unhandled Char event to the WebView embedder.          This CL fixes this by using the NativeWebKeyboardEvent.skip_in_browser     flag to prevent browser side handling of the RawKeyDown. It also     fixes a bug in the propogation of the synthetic Char event.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/ime_adapter_android.h"

#include <android/input.h>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/common/view_messages.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "jni/ImeAdapter_jni.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"

using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;

namespace content {
namespace {

// Maps a java KeyEvent into a NativeWebKeyboardEvent.
// |java_key_event| is used to maintain a globalref for KeyEvent.
// |action| will help determine the WebInputEvent type.
// type, |modifiers|, |time_ms|, |key_code|, |unicode_char| is used to create
// WebKeyboardEvent. |key_code| is also needed ad need to treat the enter key
// as a key press of character \r.
NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent(
    JNIEnv* env,
    jobject java_key_event,
    int action,
    int modifiers,
    long time_ms,
    int key_code,
    bool is_system_key,
    int unicode_char) {
  WebKit::WebInputEvent::Type type = WebKit::WebInputEvent::Undefined;
  if (action == AKEY_EVENT_ACTION_DOWN)
    type = WebKit::WebInputEvent::RawKeyDown;
  else if (action == AKEY_EVENT_ACTION_UP)
    type = WebKit::WebInputEvent::KeyUp;
  return NativeWebKeyboardEvent(java_key_event, type, modifiers,
      time_ms, key_code, unicode_char, is_system_key);
}

}  // anonymous namespace

bool RegisterImeAdapter(JNIEnv* env) {
  if (!RegisterNativesImpl(env))
    return false;

  Java_ImeAdapter_initializeWebInputEvents(env,
                                           WebKit::WebInputEvent::RawKeyDown,
                                           WebKit::WebInputEvent::KeyUp,
                                           WebKit::WebInputEvent::Char,
                                           WebKit::WebInputEvent::ShiftKey,
                                           WebKit::WebInputEvent::AltKey,
                                           WebKit::WebInputEvent::ControlKey,
                                           WebKit::WebInputEvent::CapsLockOn,
                                           WebKit::WebInputEvent::NumLockOn);
  // TODO(miguelg): remove date time related enums after
  // https://bugs.webkit.org/show_bug.cgi?id=100935.
  Java_ImeAdapter_initializeTextInputTypes(
      env,
      ui::TEXT_INPUT_TYPE_NONE,
      ui::TEXT_INPUT_TYPE_TEXT,
      ui::TEXT_INPUT_TYPE_TEXT_AREA,
      ui::TEXT_INPUT_TYPE_PASSWORD,
      ui::TEXT_INPUT_TYPE_SEARCH,
      ui::TEXT_INPUT_TYPE_URL,
      ui::TEXT_INPUT_TYPE_EMAIL,
      ui::TEXT_INPUT_TYPE_TELEPHONE,
      ui::TEXT_INPUT_TYPE_NUMBER,
      ui::TEXT_INPUT_TYPE_DATE,
      ui::TEXT_INPUT_TYPE_DATE_TIME,
      ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL,
      ui::TEXT_INPUT_TYPE_MONTH,
      ui::TEXT_INPUT_TYPE_TIME,
      ui::TEXT_INPUT_TYPE_WEEK,
      ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE);
  return true;
}

ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva)
    : rwhva_(rwhva) {
}

ImeAdapterAndroid::~ImeAdapterAndroid() {
  JNIEnv* env = AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
  if (!obj.is_null())
    Java_ImeAdapter_detach(env, obj.obj());
}

bool ImeAdapterAndroid::SendSyntheticKeyEvent(JNIEnv*,
                                              jobject,
                                              int type,
                                              long time_ms,
                                              int key_code,
                                              int text) {
  NativeWebKeyboardEvent event(static_cast<WebKit::WebInputEvent::Type>(type),
                               0 /* modifiers */, time_ms / 1000.0, key_code,
                               text, false /* is_system_key */);
  rwhva_->SendKeyEvent(event);
  return true;
}

bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject,
                                     jobject original_key_event,
                                     int action, int modifiers,
                                     long time_ms, int key_code,
                                     bool is_system_key, int unicode_char) {
  NativeWebKeyboardEvent event = NativeWebKeyboardEventFromKeyEvent(
          env, original_key_event, action, modifiers,
          time_ms, key_code, is_system_key, unicode_char);
  bool key_down_text_insertion =
      event.type == WebKit::WebInputEvent::RawKeyDown && event.text[0];
  // If we are going to follow up with a synthetic Char event, then that's the
  // one we expect to test if it's handled or unhandled, so skip handling the
  // "real" event in the browser.
  event.skip_in_browser = key_down_text_insertion;
  rwhva_->SendKeyEvent(event);
  if (key_down_text_insertion) {
    // Send a Char event, but without an os_event since we don't want to
    // roundtrip back to java such synthetic event.
    NativeWebKeyboardEvent char_event(event);
    char_event.os_event = NULL;
    char_event.type = WebKit::WebInputEvent::Char;
    rwhva_->SendKeyEvent(char_event);
  }
  return true;
}

void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text,
                                         int new_cursor_pos) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  string16 text16 = ConvertJavaStringToUTF16(env, text);
  std::vector<WebKit::WebCompositionUnderline> underlines;
  underlines.push_back(
      WebKit::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK,
                                      false));
  // new_cursor_position is as described in the Android API for
  // InputConnection#setComposingText, whereas the parameters for
  // ImeSetComposition are relative to the start of the composition.
  if (new_cursor_pos > 0)
    new_cursor_pos = text16.length() + new_cursor_pos - 1;

  rwhi->ImeSetComposition(text16, underlines, new_cursor_pos, new_cursor_pos);
}

void ImeAdapterAndroid::ImeBatchStateChanged(JNIEnv* env,
                                             jobject,
                                             jboolean is_begin) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_ImeBatchStateChanged(rwhi->GetRoutingID(), is_begin));
}

void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  string16 text16 = ConvertJavaStringToUTF16(env, text);
  rwhi->ImeConfirmComposition(text16);
}

void ImeAdapterAndroid::AttachImeAdapter(JNIEnv* env, jobject java_object) {
  java_ime_adapter_ = JavaObjectWeakGlobalRef(env, java_object);
}

void ImeAdapterAndroid::CancelComposition() {
  base::android::ScopedJavaLocalRef<jobject> obj =
      java_ime_adapter_.get(AttachCurrentThread());
  if (!obj.is_null())
    Java_ImeAdapter_cancelComposition(AttachCurrentThread(), obj.obj());
}

void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject,
                                                    int start, int end) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_SetEditableSelectionOffsets(rwhi->GetRoutingID(),
                                                     start, end));
}

void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject,
                                           int start, int end) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  std::vector<WebKit::WebCompositionUnderline> underlines;
  underlines.push_back(
      WebKit::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false));

  rwhi->Send(new ViewMsg_SetCompositionFromExistingText(
      rwhi->GetRoutingID(), start, end, underlines));
}

void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, jobject,
                                              int before, int after) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Send(new ViewMsg_ExtendSelectionAndDelete(rwhi->GetRoutingID(),
                                                  before, after));
}

void ImeAdapterAndroid::Unselect(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Unselect();
}

void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->SelectAll();
}

void ImeAdapterAndroid::Cut(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Cut();
}

void ImeAdapterAndroid::Copy(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Copy();
}

void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) {
  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(
      rwhva_->GetRenderWidgetHost());
  if (!rwhi)
    return;

  rwhi->Paste();
}

void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) {
  java_ime_adapter_.reset();
}

}  // namespace content
<|endoftext|>


<commit_before>#ifndef ITER_POWERSET_HPP_
#define ITER_POWERSET_HPP_

#include "combinations.hpp"
#include "internal/iterbase.hpp"

#include <cassert>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

namespace iter {
  namespace impl {
    template <typename Container>
    class Powersetter;

    using PowersetFn = IterToolFn<Powersetter>;
  }
  constexpr impl::PowersetFn powerset{};
}

template <typename Container>
class iter::impl::Powersetter {
 private:
  Container container_;
  using CombinatorType = decltype(combinations(std::declval<Container&>(), 0));

  friend PowersetFn;

  Powersetter(Container&& container)
      : container_(std::forward<Container>(container)) {}

 public:
  Powersetter(Powersetter&&) = default;

  class Iterator
      : public std::iterator<std::input_iterator_tag, CombinatorType> {
   private:
    std::remove_reference_t<Container>* container_p_;
    std::size_t set_size_{};
    std::shared_ptr<CombinatorType> comb_;
    iterator_type<CombinatorType> comb_iter_;
    iterator_type<CombinatorType> comb_end_;

   public:
    Iterator(Container& container, std::size_t sz)
        : container_p_{&container},
          set_size_{sz},
          comb_{std::make_shared<CombinatorType>(combinations(container, sz))},
          comb_iter_{get_begin(*comb_)},
          comb_end_{get_end(*comb_)} {}

    Iterator& operator++() {
      ++comb_iter_;
      if (comb_iter_ == comb_end_) {
        ++set_size_;
        comb_ = std::make_shared<CombinatorType>(
            combinations(*container_p_, set_size_));

        comb_iter_ = get_begin(*comb_);
        comb_end_ = get_end(*comb_);
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    iterator_deref<CombinatorType> operator*() {
      return *comb_iter_;
    }

    iterator_arrow<CombinatorType> operator->() {
      apply_arrow(comb_iter_);
    }

    bool operator!=(const Iterator& other) const {
      return !(*this == other);
    }

    bool operator==(const Iterator& other) const {
      return set_size_ == other.set_size_ && comb_iter_ == other.comb_iter_;
    }
  };

  Iterator begin() {
    return {container_, 0};
  }

  Iterator end() {
    return {container_, dumb_size(container_) + 1};
  }
};

#endif
<commit_msg>Adds support for const iteration to powerset<commit_after>#ifndef ITER_POWERSET_HPP_
#define ITER_POWERSET_HPP_

#include "combinations.hpp"
#include "internal/iterbase.hpp"

#include <cassert>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

namespace iter {
  namespace impl {
    template <typename Container>
    class Powersetter;

    using PowersetFn = IterToolFn<Powersetter>;
  }
  constexpr impl::PowersetFn powerset{};
}

template <typename Container>
class iter::impl::Powersetter {
 private:
  Container container_;
  template <typename T>
  using CombinatorType = decltype(combinations(std::declval<T&>(), 0));

  friend PowersetFn;

  Powersetter(Container&& container)
      : container_(std::forward<Container>(container)) {}

 public:
  Powersetter(Powersetter&&) = default;

  template <typename ContainerT>
  class Iterator : public std::iterator<std::input_iterator_tag,
                       CombinatorType<ContainerT>> {
   private:
#if 0
    template <typename> friend class Iterator;
#endif
    std::remove_reference_t<ContainerT>* container_p_;
    std::size_t set_size_{};
    std::shared_ptr<CombinatorType<ContainerT>> comb_;
    iterator_type<CombinatorType<ContainerT>> comb_iter_;
    iterator_type<CombinatorType<ContainerT>> comb_end_;

   public:
    Iterator(ContainerT& container, std::size_t sz)
        : container_p_{&container},
          set_size_{sz},
          comb_{std::make_shared<CombinatorType<ContainerT>>(
              combinations(container, sz))},
          comb_iter_{get_begin(*comb_)},
          comb_end_{get_end(*comb_)} {}

    Iterator& operator++() {
      ++comb_iter_;
      if (comb_iter_ == comb_end_) {
        ++set_size_;
        comb_ = std::make_shared<CombinatorType<ContainerT>>(
            combinations(*container_p_, set_size_));

        comb_iter_ = get_begin(*comb_);
        comb_end_ = get_end(*comb_);
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    iterator_deref<CombinatorType<ContainerT>> operator*() {
      return *comb_iter_;
    }

    iterator_arrow<CombinatorType<ContainerT>> operator->() {
      apply_arrow(comb_iter_);
    }

    bool operator!=(const Iterator& other) const {
      return !(*this == other);
    }

    bool operator==(const Iterator& other) const {
      return set_size_ == other.set_size_ && comb_iter_ == other.comb_iter_;
    }
#if 0
    template <typename T>
    bool operator!=(const Iterator<T>& other) const {
      return !(*this == other);
    }

    template <typename T>
    bool operator==(const Iterator<T>& other) const {
      return set_size_ == other.set_size_ && comb_iter_ == other.comb_iter_;
    }
#endif
  };

  Iterator<Container> begin() {
    return {container_, 0};
  }

  Iterator<Container> end() {
    return {container_, dumb_size(container_) + 1};
  }

  Iterator<AsConst<Container>> begin() const {
    return {as_const(container_), 0};
  }

  Iterator<AsConst<Container>> end() const {
    return {as_const(container_), dumb_size(as_const(container_)) + 1};
  }
};

#endif
<|endoftext|>


<commit_before>#include <xzero/raft/ServerUtil.h>
#include <xzero/Random.h>

namespace xzero {
namespace raft {

Duration ServerUtil::alleviatedDuration(Duration base) {
  static Random rng_;
  auto emin = base.milliseconds() / 2;
  auto emax = base.milliseconds();
  auto e = emin + rng_.random64() % (emax - emin);

  return Duration::fromMilliseconds(e);
}

Duration ServerUtil::cumulativeDuration(Duration base) {
  static Random rng_;
  auto emin = base.milliseconds();
  auto emax = base.milliseconds() / 2 + emin;
  auto e = emin + rng_.random64() % (emax - emin);

  return Duration::fromMilliseconds(e);
}

Index ServerUtil::majorityIndexOf(const ServerIndexMap& set) {
  const auto compFn = [](std::pair<Id, Index> a, std::pair<Id, Index> b) {
    return a.second < b.second;
  };
  const Index low = std::min_element(set.begin(),
                                     set.end(),
                                     compFn)->second;
  const Index high = std::max_element(set.begin(),
                                      set.end(),
                                      compFn)->second;
  const size_t quorum = set.size() / 2 + 1;
  Index result = low;

  // logDebug("raft.Server", "computeCommitIndex: min=$0, max=$1, quorum=$2",
  //          low, high, quorum);

  for (Index N = low; N <= high; N++) {
    size_t ok = 0;

    for (const auto& element: set) {
      if (element.second >= N) {
        ok++;
      }
    }

    if (ok >= quorum && N > result) {
      result = N;
    }
  }

  return result;
}

} // namespace raft
} // namespace xzero
<commit_msg>[xzero] raft: adds missing include<commit_after>#include <xzero/raft/ServerUtil.h>
#include <xzero/Random.h>
#include <algorithm>

namespace xzero {
namespace raft {

Duration ServerUtil::alleviatedDuration(Duration base) {
  static Random rng_;
  auto emin = base.milliseconds() / 2;
  auto emax = base.milliseconds();
  auto e = emin + rng_.random64() % (emax - emin);

  return Duration::fromMilliseconds(e);
}

Duration ServerUtil::cumulativeDuration(Duration base) {
  static Random rng_;
  auto emin = base.milliseconds();
  auto emax = base.milliseconds() / 2 + emin;
  auto e = emin + rng_.random64() % (emax - emin);

  return Duration::fromMilliseconds(e);
}

Index ServerUtil::majorityIndexOf(const ServerIndexMap& set) {
  const auto compFn = [](std::pair<Id, Index> a, std::pair<Id, Index> b) {
    return a.second < b.second;
  };
  const Index low = std::min_element(set.begin(),
                                     set.end(),
                                     compFn)->second;
  const Index high = std::max_element(set.begin(),
                                      set.end(),
                                      compFn)->second;
  const size_t quorum = set.size() / 2 + 1;
  Index result = low;

  // logDebug("raft.Server", "computeCommitIndex: min=$0, max=$1, quorum=$2",
  //          low, high, quorum);

  for (Index N = low; N <= high; N++) {
    size_t ok = 0;

    for (const auto& element: set) {
      if (element.second >= N) {
        ok++;
      }
    }

    if (ok >= quorum && N > result) {
      result = N;
    }
  }

  return result;
}

} // namespace raft
} // namespace xzero
<|endoftext|>


<commit_before>#include <QTimer>
#include <QDateTime>

#include "utils/utils.h"
#include "utils/translate-commit-desc.h"
#include "utils/json-utils.h"
#include "utils/file-utils.h"
#include "seafile-applet.h"
#include "daemon-mgr.h"
#include "settings-mgr.h"
#include "rpc/rpc-client.h"
#include "rpc/sync-error.h"
#include "ui/tray-icon.h"

#include "message-poller.h"
#include "seafile/seafile-error.h"

namespace {

const int kCheckNotificationIntervalMSecs = 1000;

} // namespace

struct SyncNotification {
    QString type;
    QString content;

    static SyncNotification fromJson(const json_t* json);
};

MessagePoller::MessagePoller(QObject *parent): QObject(parent)
{
    rpc_client_ = new SeafileRpcClient();
    check_notification_timer_ = new QTimer(this);
    connect(check_notification_timer_, SIGNAL(timeout()), this, SLOT(checkNotification()));
}

MessagePoller::~MessagePoller()
{
    delete check_notification_timer_;
    delete rpc_client_;
}

void MessagePoller::start()
{
    rpc_client_->tryConnectDaemon();
    check_notification_timer_->start(kCheckNotificationIntervalMSecs);
    connect(seafApplet->daemonManager(), SIGNAL(daemonDead()), this, SLOT(onDaemonDead()));
    connect(seafApplet->daemonManager(), SIGNAL(daemonRestarted()), this, SLOT(onDaemonRestarted()));
}

void MessagePoller::onDaemonDead()
{
    qDebug("pausing message poller when daemon is dead");
    check_notification_timer_->stop();
}

void MessagePoller::onDaemonRestarted()
{
    qDebug("reviving message poller when daemon is restarted");
    if (rpc_client_) {
        delete rpc_client_;
    }
    rpc_client_ = new SeafileRpcClient();
    rpc_client_->tryConnectDaemon();
    check_notification_timer_->start(kCheckNotificationIntervalMSecs);
}

void MessagePoller::checkNotification()
{
    json_t *ret;
    if (!rpc_client_->getSyncNotification(&ret)) {
        return;
    }
    SyncNotification notification = SyncNotification::fromJson(ret);
    json_decref(ret);

    processNotification(notification);
}

SyncNotification SyncNotification::fromJson(const json_t *root)
{
    SyncNotification notification;
    Json json(root);

    // char *s = json_dumps(root, 0);
    // printf ("[%s] %s\n", QDateTime::currentDateTime().toString().toUtf8().data(), s);
    // qWarning ("[%s] %s\n", QDateTime::currentDateTime().toString().toUtf8().data(), s);
    // free (s);

    notification.type = json.getString("type");
    notification.content = json.getString("content");
    return notification;
}

void MessagePoller::processNotification(const SyncNotification& notification)
{
    const QString& type = notification.type;
    const QString& content = notification.content;
    if (type == "transfer") {
        // empty
    } else if (type == "sync.done" ||
               type == "sync.multipart_upload") {
        /* format: a concatenation of (repo_name, repo_id, commmit_id,
         * previous_commit_id, description), separated by tabs */
        QStringList slist = content.split("\t");
        if (slist.count() != 5) {
            qWarning("Bad sync.done message format");
            return;
        }

        QString title;
        if (type == "sync.done")
            title = tr("\"%1\" is synchronized").arg(slist.at(0));
        else
            title = tr("Files uploaded to \"%1\"").arg(slist.at(0));
        QString repo_id = slist.at(1).trimmed();
        QString commit_id = slist.at(2).trimmed();
        QString previous_commit_id = slist.at(3).trimmed();
        QString desc = slist.at(4).trimmed();

        seafApplet->trayIcon()->showMessage(title, translateCommitDesc(desc), repo_id, commit_id, previous_commit_id);

    } else if (type == "sync.error") {
        json_error_t error;
        json_t *object = json_loads(toCStr(content), 0, &error);
        if (!object) {
            qWarning("Failed to parse json: %s", error.text);
            return;
        }

        QString repo_id = QString::fromUtf8(json_string_value(json_object_get(object, "repo_id")));
        QString title = QString::fromUtf8(json_string_value(json_object_get(object, "repo_name")));
        QString path = QString::fromUtf8(json_string_value(json_object_get(object, "path")));
        int err_id = json_integer_value(json_object_get(object, "err_id"));
        QString msg;
        switch (err_id) {
        case SYNC_ERROR_ID_FILE_LOCKED_BY_APP:
            msg = tr("Failed to sync file %1\nFile is locked by other application. This file will be updated when you close the application.").arg(path);
            break;
        case SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP:
            msg = tr("Failed to sync folder %1\nSome file in this folder is locked by other application. This folder will be updated when you close the application.").arg(path);
            break;
        case SYNC_ERROR_ID_FILE_LOCKED:
            msg = tr("Failed to sync file %1\nFile is locked by another user. Update to this file is not uploaded.").arg(path);
            break;
        case SYNC_ERROR_ID_INVALID_PATH:
            msg = tr("Failed to sync %1\nFile path contains invalid characters. It is not synced to this computer.").arg(path);
            break;
        case SYNC_ERROR_ID_INDEX_ERROR:
            msg = tr("Failed to index file %1\nPlease check file permission and disk space.").arg(path);
            break;
        case SYNC_ERROR_ID_PATH_END_SPACE_PERIOD:
            msg = tr("Failed to sync %1\nFile path is ended with space or period and cannot be created on Windows.").arg(path);
            break;
        case SYNC_ERROR_ID_PATH_INVALID_CHARACTER:
            msg = tr("Failed to sync %1\nFile path contains invalid characters. It is not synced to this computer.").arg(path);
            break;
        case SYNC_ERROR_ID_FOLDER_PERM_DENIED:
            msg = tr("Update to file %1 is denied by folder permission setting.").arg(path);
            break;
        case SYNC_ERROR_ID_PERM_NOT_SYNCABLE:
            msg = tr("No permission to sync folder %1.").arg(path);
            break;
        case SYNC_ERROR_ID_UPDATE_TO_READ_ONLY_REPO:
            msg = tr("Updates in read-only library %1 will not be uploaded.").arg(path);
            break;
        case SYNC_ERROR_ID_CONFLICT:
            msg = tr("Concurrent updates to file. File %1 is saved as conflict file").arg(path);
            break;
        default:
            qWarning("Unknown sync error id %d", err_id);
            json_decref(object);
            return;
        }

        seafApplet->trayIcon()->showMessage(title, msg, repo_id);

        json_decref(object);

    } else if (type == "repo.remove") {
        /* format : <repo_name> */
        QString repo_name = content;
        QString buf = tr("Folder for library %1 is removed or moved. The library is unsynced.").arg(repo_name);
        seafApplet->trayIcon()->showMessage(getBrand(), buf);
    }
}
<commit_msg>add error code for uncommited folder<commit_after>#include <QTimer>
#include <QDateTime>

#include "utils/utils.h"
#include "utils/translate-commit-desc.h"
#include "utils/json-utils.h"
#include "utils/file-utils.h"
#include "seafile-applet.h"
#include "daemon-mgr.h"
#include "settings-mgr.h"
#include "rpc/rpc-client.h"
#include "rpc/sync-error.h"
#include "ui/tray-icon.h"

#include "message-poller.h"
#include "seafile/seafile-error.h"

namespace {

const int kCheckNotificationIntervalMSecs = 1000;

} // namespace

struct SyncNotification {
    QString type;
    QString content;

    static SyncNotification fromJson(const json_t* json);
};

MessagePoller::MessagePoller(QObject *parent): QObject(parent)
{
    rpc_client_ = new SeafileRpcClient();
    check_notification_timer_ = new QTimer(this);
    connect(check_notification_timer_, SIGNAL(timeout()), this, SLOT(checkNotification()));
}

MessagePoller::~MessagePoller()
{
    delete check_notification_timer_;
    delete rpc_client_;
}

void MessagePoller::start()
{
    rpc_client_->tryConnectDaemon();
    check_notification_timer_->start(kCheckNotificationIntervalMSecs);
    connect(seafApplet->daemonManager(), SIGNAL(daemonDead()), this, SLOT(onDaemonDead()));
    connect(seafApplet->daemonManager(), SIGNAL(daemonRestarted()), this, SLOT(onDaemonRestarted()));
}

void MessagePoller::onDaemonDead()
{
    qDebug("pausing message poller when daemon is dead");
    check_notification_timer_->stop();
}

void MessagePoller::onDaemonRestarted()
{
    qDebug("reviving message poller when daemon is restarted");
    if (rpc_client_) {
        delete rpc_client_;
    }
    rpc_client_ = new SeafileRpcClient();
    rpc_client_->tryConnectDaemon();
    check_notification_timer_->start(kCheckNotificationIntervalMSecs);
}

void MessagePoller::checkNotification()
{
    json_t *ret;
    if (!rpc_client_->getSyncNotification(&ret)) {
        return;
    }
    SyncNotification notification = SyncNotification::fromJson(ret);
    json_decref(ret);

    processNotification(notification);
}

SyncNotification SyncNotification::fromJson(const json_t *root)
{
    SyncNotification notification;
    Json json(root);

    // char *s = json_dumps(root, 0);
    // printf ("[%s] %s\n", QDateTime::currentDateTime().toString().toUtf8().data(), s);
    // qWarning ("[%s] %s\n", QDateTime::currentDateTime().toString().toUtf8().data(), s);
    // free (s);

    notification.type = json.getString("type");
    notification.content = json.getString("content");
    return notification;
}

void MessagePoller::processNotification(const SyncNotification& notification)
{
    const QString& type = notification.type;
    const QString& content = notification.content;
    if (type == "transfer") {
        // empty
    } else if (type == "sync.done" ||
               type == "sync.multipart_upload") {
        /* format: a concatenation of (repo_name, repo_id, commmit_id,
         * previous_commit_id, description), separated by tabs */
        QStringList slist = content.split("\t");
        if (slist.count() != 5) {
            qWarning("Bad sync.done message format");
            return;
        }

        QString title;
        if (type == "sync.done")
            title = tr("\"%1\" is synchronized").arg(slist.at(0));
        else
            title = tr("Files uploaded to \"%1\"").arg(slist.at(0));
        QString repo_id = slist.at(1).trimmed();
        QString commit_id = slist.at(2).trimmed();
        QString previous_commit_id = slist.at(3).trimmed();
        QString desc = slist.at(4).trimmed();

        seafApplet->trayIcon()->showMessage(title, translateCommitDesc(desc), repo_id, commit_id, previous_commit_id);

    } else if (type == "sync.error") {
        json_error_t error;
        json_t *object = json_loads(toCStr(content), 0, &error);
        if (!object) {
            qWarning("Failed to parse json: %s", error.text);
            return;
        }

        QString repo_id = QString::fromUtf8(json_string_value(json_object_get(object, "repo_id")));
        QString title = QString::fromUtf8(json_string_value(json_object_get(object, "repo_name")));
        QString path = QString::fromUtf8(json_string_value(json_object_get(object, "path")));
        int err_id = json_integer_value(json_object_get(object, "err_id"));
        QString msg;
        switch (err_id) {
        case SYNC_ERROR_ID_FILE_LOCKED_BY_APP:
            msg = tr("Failed to sync file %1\nFile is locked by other application. This file will be updated when you close the application.").arg(path);
            break;
        case SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP:
            msg = tr("Failed to sync folder %1\nSome file in this folder is locked by other application. This folder will be updated when you close the application.").arg(path);
            break;
        case SYNC_ERROR_ID_FILE_LOCKED:
            msg = tr("Failed to sync file %1\nFile is locked by another user. Update to this file is not uploaded.").arg(path);
            break;
        case SYNC_ERROR_ID_INVALID_PATH:
            msg = tr("Failed to sync %1\nFile path contains invalid characters. It is not synced to this computer.").arg(path);
            break;
        case SYNC_ERROR_ID_INDEX_ERROR:
            msg = tr("Failed to index file %1\nPlease check file permission and disk space.").arg(path);
            break;
        case SYNC_ERROR_ID_PATH_END_SPACE_PERIOD:
            msg = tr("Failed to sync %1\nFile path is ended with space or period and cannot be created on Windows.").arg(path);
            break;
        case SYNC_ERROR_ID_PATH_INVALID_CHARACTER:
            msg = tr("Failed to sync %1\nFile path contains invalid characters. It is not synced to this computer.").arg(path);
            break;
        case SYNC_ERROR_ID_FOLDER_PERM_DENIED:
            msg = tr("Update to file %1 is denied by folder permission setting.").arg(path);
            break;
        case SYNC_ERROR_ID_PERM_NOT_SYNCABLE:
            msg = tr("No permission to sync folder %1.").arg(path);
            break;
        case SYNC_ERROR_ID_UPDATE_TO_READ_ONLY_REPO:
            msg = tr("Updates in read-only library %1 will not be uploaded.").arg(path);
            break;
        case SYNC_ERROR_ID_CONFLICT:
            msg = tr("Concurrent updates to file. File %1 is saved as conflict file").arg(path);
            break;
        case SYNC_ERROR_ID_REMOVE_UNCOMMITTED_FOLDER:
            msg = tr("Failed to remove uncommited folder %1.").arg(path);
            break;
        default:
            qWarning("Unknown sync error id %d", err_id);
            json_decref(object);
            return;
        }

        seafApplet->trayIcon()->showMessage(title, msg, repo_id);

        json_decref(object);

    } else if (type == "repo.remove") {
        /* format : <repo_name> */
        QString repo_name = content;
        QString buf = tr("Folder for library %1 is removed or moved. The library is unsynced.").arg(repo_name);
        seafApplet->trayIcon()->showMessage(getBrand(), buf);
    }
}
<|endoftext|>


<commit_before>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Willow Garage nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author Ioan Sucan */

#include "collision_detection_fcl/collision_world.h"
#include <fcl/geometric_shape_to_BVH_model.h>
#include <fcl/traversal_node_bvhs.h>
#include <fcl/simple_setup.h>
#include <fcl/collision_node.h>
#include <ros/console.h>

collision_detection::CollisionWorldFCL::CollisionWorldFCL(void) : CollisionWorld()
{
  fcl::DynamicAABBTreeCollisionManager* m = new fcl::DynamicAABBTreeCollisionManager();
  // m->tree_init_level = 2;
  manager_.reset(m);
}

collision_detection::CollisionWorldFCL::CollisionWorldFCL(const CollisionWorldFCL &other) : CollisionWorld(other)
{
  fcl::DynamicAABBTreeCollisionManager* m = new fcl::DynamicAABBTreeCollisionManager();
  // m->tree_init_level = 2;
  manager_.reset(m);

  fcl_objs_ = other.fcl_objs_;
  for (std::map<std::string, FCLObject>::iterator it = fcl_objs_.begin() ; it != fcl_objs_.end() ; ++it)
    it->second.registerTo(manager_.get());
  // manager_->update();
}

collision_detection::CollisionWorldFCL::~CollisionWorldFCL(void)
{
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state) const
{
  checkRobotCollisionHelper(req, res, robot, state, NULL);
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix &acm) const
{
  checkRobotCollisionHelper(req, res, robot, state, &acm);
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state1, const planning_models::KinematicState &state2) const
{
  ROS_ERROR("FCL continuous collision checking not yet implemented");
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state1, const planning_models::KinematicState &state2, const AllowedCollisionMatrix &acm) const
{
  ROS_ERROR("FCL continuous collision checking not yet implemented");
}

void collision_detection::CollisionWorldFCL::checkRobotCollisionHelper(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix *acm) const
{
  const CollisionRobotFCL &robot_fcl = dynamic_cast<const CollisionRobotFCL&>(robot);
  FCLObject fcl_obj;
  robot_fcl.constructFCLObject(state, fcl_obj);

  CollisionData cd(&req, &res, acm);
  cd.enableGroup(robot.getKinematicModel());
  for (std::size_t i = 0 ; !cd.done_ && i < fcl_obj.collision_objects_.size() ; ++i)
    manager_->collide(fcl_obj.collision_objects_[i].get(), &cd, &collisionCallback);

  if (req.distance)
    res.distance = distanceRobotHelper(robot, state, acm);
}

void collision_detection::CollisionWorldFCL::checkWorldCollision(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world) const
{
  checkWorldCollisionHelper(req, res, other_world, NULL);
}

void collision_detection::CollisionWorldFCL::checkWorldCollision(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world, const AllowedCollisionMatrix &acm) const
{
  checkWorldCollisionHelper(req, res, other_world, &acm);
}

void collision_detection::CollisionWorldFCL::checkWorldCollisionHelper(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world, const AllowedCollisionMatrix *acm) const
{
  const CollisionWorldFCL &other_fcl_world = dynamic_cast<const CollisionWorldFCL&>(other_world);
  CollisionData cd(&req, &res, acm);
  manager_->collide(other_fcl_world.manager_.get(), &cd, &collisionCallback);

  if (req.distance)
    res.distance = distanceWorldHelper(other_world, acm);
}

void collision_detection::CollisionWorldFCL::constructFCLObject(const Object *obj, FCLObject &fcl_obj) const
{
  for (std::size_t i = 0 ; i < obj->shapes_.size() ; ++i)
  {
    FCLGeometryConstPtr g = createCollisionGeometry(obj->shapes_[i], obj);
    if (g)
    {
      fcl::CollisionObject *co = new fcl::CollisionObject(g->collision_geometry_,  transform2fcl(obj->shape_poses_[i]));
      fcl_obj.collision_objects_.push_back(boost::shared_ptr<fcl::CollisionObject>(co));
      fcl_obj.collision_geometry_.push_back(g);
    }
  }
}

void collision_detection::CollisionWorldFCL::updateFCLObject(const std::string &id)
{
  // remove FCL objects that correspond to this object
  std::map<std::string, FCLObject>::iterator jt = fcl_objs_.find(id);
  if (jt != fcl_objs_.end())
  {
    jt->second.unregisterFrom(manager_.get());
    jt->second.clear();
  }

  // check to see if we have this object
  std::map<std::string, ObjectPtr>::iterator it = objects_.find(id);
  if (it != objects_.end())
  {
    // construct FCL objects that correspond to this object
    if (jt != fcl_objs_.end())
    {
      constructFCLObject(it->second.get(), jt->second);
      jt->second.registerTo(manager_.get());
    }
    else
    {
      constructFCLObject(it->second.get(), fcl_objs_[id]);
      fcl_objs_[id].registerTo(manager_.get());
    }
  }
  else
  {
    if (jt != fcl_objs_.end())
      fcl_objs_.erase(jt);
  }

  // manager_->update();
}

void collision_detection::CollisionWorldFCL::addToObject(const std::string &id, const std::vector<shapes::ShapeConstPtr> &shapes, const std::vector<Eigen::Affine3d> &poses)
{
  CollisionWorld::addToObject(id, shapes, poses);
  updateFCLObject(id);
}

void collision_detection::CollisionWorldFCL::addToObject(const std::string &id, const shapes::ShapeConstPtr &shape, const Eigen::Affine3d &pose)
{
  CollisionWorld::addToObject(id, shape, pose);
  updateFCLObject(id);
}

bool collision_detection::CollisionWorldFCL::moveShapeInObject(const std::string &id, const shapes::ShapeConstPtr &shape, const Eigen::Affine3d &pose)
{
  if (CollisionWorld::moveShapeInObject(id, shape, pose))
  {
    updateFCLObject(id);
    return true;
  }
  else
    return false;
}

bool collision_detection::CollisionWorldFCL::removeShapeFromObject(const std::string &id, const shapes::ShapeConstPtr &shape)
{
  if (CollisionWorld::removeShapeFromObject(id, shape))
  {
    updateFCLObject(id);
    return true;
  }
  else
    return false;
}

void collision_detection::CollisionWorldFCL::removeObject(const std::string &id)
{
  CollisionWorld::removeObject(id);
  std::map<std::string, FCLObject>::iterator it = fcl_objs_.find(id);
  if (it != fcl_objs_.end())
  {
    it->second.unregisterFrom(manager_.get());
    it->second.clear();
    fcl_objs_.erase(it);
    // manager_->update();
  }
}

void collision_detection::CollisionWorldFCL::clearObjects(void)
{
  CollisionWorld::clearObjects();
  manager_->clear();
  fcl_objs_.clear();
}

double collision_detection::CollisionWorldFCL::distanceRobotHelper(const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix *acm) const
{
  const CollisionRobotFCL& robot_fcl = dynamic_cast<const CollisionRobotFCL&>(robot);
  FCLObject fcl_obj;
  robot_fcl.constructFCLObject(state, fcl_obj);

  CollisionRequest req;
  CollisionResult res;
  CollisionData cd(&req, &res, acm);
  cd.enableGroup(robot.getKinematicModel());

  for(std::size_t i = 0; !cd.done_ && i < fcl_obj.collision_objects_.size(); ++i)
    manager_->distance(fcl_obj.collision_objects_[i].get(), &cd, &distanceCallback);

  return res.distance;
}

double collision_detection::CollisionWorldFCL::distanceRobot(const CollisionRobot &robot, const planning_models::KinematicState &state) const
{
  return distanceRobotHelper(robot, state, NULL);
}

double collision_detection::CollisionWorldFCL::distanceRobot(const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix &acm) const
{
  return distanceRobotHelper(robot, state, &acm);
}

double collision_detection::CollisionWorldFCL::distanceWorld(const CollisionWorld &world) const
{
  return distanceWorldHelper(world, NULL);
}

double collision_detection::CollisionWorldFCL::distanceWorld(const CollisionWorld &world, const AllowedCollisionMatrix &acm) const
{
  return distanceWorldHelper(world, &acm);
}

double collision_detection::CollisionWorldFCL::distanceWorldHelper(const CollisionWorld &other_world, const AllowedCollisionMatrix *acm) const
{
  const CollisionWorldFCL& other_fcl_world = dynamic_cast<const CollisionWorldFCL&>(other_world);
  CollisionRequest req;
  CollisionResult res;
  CollisionData cd(&req, &res, acm);
  manager_->distance(other_fcl_world.manager_.get(), &cd, &distanceCallback);

  return res.distance;
}
<commit_msg>change according to change in fcl's change of file name<commit_after>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Willow Garage nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author Ioan Sucan */

#include "collision_detection_fcl/collision_world.h"
#include <fcl/geometric_shape_to_BVH_model.h>
#include <fcl/traversal_node_bvhs.h>
#include <fcl/traversal_node_setup.h>
#include <fcl/collision_node.h>
#include <ros/console.h>

collision_detection::CollisionWorldFCL::CollisionWorldFCL(void) : CollisionWorld()
{
  fcl::DynamicAABBTreeCollisionManager* m = new fcl::DynamicAABBTreeCollisionManager();
  // m->tree_init_level = 2;
  manager_.reset(m);
}

collision_detection::CollisionWorldFCL::CollisionWorldFCL(const CollisionWorldFCL &other) : CollisionWorld(other)
{
  fcl::DynamicAABBTreeCollisionManager* m = new fcl::DynamicAABBTreeCollisionManager();
  // m->tree_init_level = 2;
  manager_.reset(m);

  fcl_objs_ = other.fcl_objs_;
  for (std::map<std::string, FCLObject>::iterator it = fcl_objs_.begin() ; it != fcl_objs_.end() ; ++it)
    it->second.registerTo(manager_.get());
  // manager_->update();
}

collision_detection::CollisionWorldFCL::~CollisionWorldFCL(void)
{
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state) const
{
  checkRobotCollisionHelper(req, res, robot, state, NULL);
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix &acm) const
{
  checkRobotCollisionHelper(req, res, robot, state, &acm);
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state1, const planning_models::KinematicState &state2) const
{
  ROS_ERROR("FCL continuous collision checking not yet implemented");
}

void collision_detection::CollisionWorldFCL::checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state1, const planning_models::KinematicState &state2, const AllowedCollisionMatrix &acm) const
{
  ROS_ERROR("FCL continuous collision checking not yet implemented");
}

void collision_detection::CollisionWorldFCL::checkRobotCollisionHelper(const CollisionRequest &req, CollisionResult &res, const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix *acm) const
{
  const CollisionRobotFCL &robot_fcl = dynamic_cast<const CollisionRobotFCL&>(robot);
  FCLObject fcl_obj;
  robot_fcl.constructFCLObject(state, fcl_obj);

  CollisionData cd(&req, &res, acm);
  cd.enableGroup(robot.getKinematicModel());
  for (std::size_t i = 0 ; !cd.done_ && i < fcl_obj.collision_objects_.size() ; ++i)
    manager_->collide(fcl_obj.collision_objects_[i].get(), &cd, &collisionCallback);

  if (req.distance)
    res.distance = distanceRobotHelper(robot, state, acm);
}

void collision_detection::CollisionWorldFCL::checkWorldCollision(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world) const
{
  checkWorldCollisionHelper(req, res, other_world, NULL);
}

void collision_detection::CollisionWorldFCL::checkWorldCollision(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world, const AllowedCollisionMatrix &acm) const
{
  checkWorldCollisionHelper(req, res, other_world, &acm);
}

void collision_detection::CollisionWorldFCL::checkWorldCollisionHelper(const CollisionRequest &req, CollisionResult &res, const CollisionWorld &other_world, const AllowedCollisionMatrix *acm) const
{
  const CollisionWorldFCL &other_fcl_world = dynamic_cast<const CollisionWorldFCL&>(other_world);
  CollisionData cd(&req, &res, acm);
  manager_->collide(other_fcl_world.manager_.get(), &cd, &collisionCallback);

  if (req.distance)
    res.distance = distanceWorldHelper(other_world, acm);
}

void collision_detection::CollisionWorldFCL::constructFCLObject(const Object *obj, FCLObject &fcl_obj) const
{
  for (std::size_t i = 0 ; i < obj->shapes_.size() ; ++i)
  {
    FCLGeometryConstPtr g = createCollisionGeometry(obj->shapes_[i], obj);
    if (g)
    {
      fcl::CollisionObject *co = new fcl::CollisionObject(g->collision_geometry_,  transform2fcl(obj->shape_poses_[i]));
      fcl_obj.collision_objects_.push_back(boost::shared_ptr<fcl::CollisionObject>(co));
      fcl_obj.collision_geometry_.push_back(g);
    }
  }
}

void collision_detection::CollisionWorldFCL::updateFCLObject(const std::string &id)
{
  // remove FCL objects that correspond to this object
  std::map<std::string, FCLObject>::iterator jt = fcl_objs_.find(id);
  if (jt != fcl_objs_.end())
  {
    jt->second.unregisterFrom(manager_.get());
    jt->second.clear();
  }

  // check to see if we have this object
  std::map<std::string, ObjectPtr>::iterator it = objects_.find(id);
  if (it != objects_.end())
  {
    // construct FCL objects that correspond to this object
    if (jt != fcl_objs_.end())
    {
      constructFCLObject(it->second.get(), jt->second);
      jt->second.registerTo(manager_.get());
    }
    else
    {
      constructFCLObject(it->second.get(), fcl_objs_[id]);
      fcl_objs_[id].registerTo(manager_.get());
    }
  }
  else
  {
    if (jt != fcl_objs_.end())
      fcl_objs_.erase(jt);
  }

  // manager_->update();
}

void collision_detection::CollisionWorldFCL::addToObject(const std::string &id, const std::vector<shapes::ShapeConstPtr> &shapes, const std::vector<Eigen::Affine3d> &poses)
{
  CollisionWorld::addToObject(id, shapes, poses);
  updateFCLObject(id);
}

void collision_detection::CollisionWorldFCL::addToObject(const std::string &id, const shapes::ShapeConstPtr &shape, const Eigen::Affine3d &pose)
{
  CollisionWorld::addToObject(id, shape, pose);
  updateFCLObject(id);
}

bool collision_detection::CollisionWorldFCL::moveShapeInObject(const std::string &id, const shapes::ShapeConstPtr &shape, const Eigen::Affine3d &pose)
{
  if (CollisionWorld::moveShapeInObject(id, shape, pose))
  {
    updateFCLObject(id);
    return true;
  }
  else
    return false;
}

bool collision_detection::CollisionWorldFCL::removeShapeFromObject(const std::string &id, const shapes::ShapeConstPtr &shape)
{
  if (CollisionWorld::removeShapeFromObject(id, shape))
  {
    updateFCLObject(id);
    return true;
  }
  else
    return false;
}

void collision_detection::CollisionWorldFCL::removeObject(const std::string &id)
{
  CollisionWorld::removeObject(id);
  std::map<std::string, FCLObject>::iterator it = fcl_objs_.find(id);
  if (it != fcl_objs_.end())
  {
    it->second.unregisterFrom(manager_.get());
    it->second.clear();
    fcl_objs_.erase(it);
    // manager_->update();
  }
}

void collision_detection::CollisionWorldFCL::clearObjects(void)
{
  CollisionWorld::clearObjects();
  manager_->clear();
  fcl_objs_.clear();
}

double collision_detection::CollisionWorldFCL::distanceRobotHelper(const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix *acm) const
{
  const CollisionRobotFCL& robot_fcl = dynamic_cast<const CollisionRobotFCL&>(robot);
  FCLObject fcl_obj;
  robot_fcl.constructFCLObject(state, fcl_obj);

  CollisionRequest req;
  CollisionResult res;
  CollisionData cd(&req, &res, acm);
  cd.enableGroup(robot.getKinematicModel());

  for(std::size_t i = 0; !cd.done_ && i < fcl_obj.collision_objects_.size(); ++i)
    manager_->distance(fcl_obj.collision_objects_[i].get(), &cd, &distanceCallback);

  return res.distance;
}

double collision_detection::CollisionWorldFCL::distanceRobot(const CollisionRobot &robot, const planning_models::KinematicState &state) const
{
  return distanceRobotHelper(robot, state, NULL);
}

double collision_detection::CollisionWorldFCL::distanceRobot(const CollisionRobot &robot, const planning_models::KinematicState &state, const AllowedCollisionMatrix &acm) const
{
  return distanceRobotHelper(robot, state, &acm);
}

double collision_detection::CollisionWorldFCL::distanceWorld(const CollisionWorld &world) const
{
  return distanceWorldHelper(world, NULL);
}

double collision_detection::CollisionWorldFCL::distanceWorld(const CollisionWorld &world, const AllowedCollisionMatrix &acm) const
{
  return distanceWorldHelper(world, &acm);
}

double collision_detection::CollisionWorldFCL::distanceWorldHelper(const CollisionWorld &other_world, const AllowedCollisionMatrix *acm) const
{
  const CollisionWorldFCL& other_fcl_world = dynamic_cast<const CollisionWorldFCL&>(other_world);
  CollisionRequest req;
  CollisionResult res;
  CollisionData cd(&req, &res, acm);
  manager_->distance(other_fcl_world.manager_.get(), &cd, &distanceCallback);

  return res.distance;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sjapplet.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2007-03-12 10:46:26 $
 *
 *  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 "sal/config.h"

#include "sjapplet.hxx"

#include "osl/diagnose.h"
#include "rtl/string.hxx"
#include "rtl/ustring.hxx"

#include "sjapplet_impl.hxx"

using namespace ::rtl;
using namespace ::com::sun::star::uno;

SjApplet2::SjApplet2()
  : _pImpl(new SjApplet2_Impl())
{
}

SjApplet2::~SjApplet2()
{
    delete _pImpl;
}

//=========================================================================
void SjApplet2::Init(
    com::sun::star::uno::Reference<
        com::sun::star::uno::XComponentContext > const & context,
    Window * pParentWin, const INetURLObject & rDocBase,
    const SvCommandList & rCmdList)
{
    try {
        if(_pImpl)
            _pImpl->init(pParentWin, context, rDocBase, rCmdList);
    }
    catch(RuntimeException & runtimeException) {
#if OSL_DEBUG_LEVEL > 1
        OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_TRACE("sjapplet.cxx: SjApplet2::Init - exception occurred: %s\n", message.getStr());
#else
        (void) runtimeException; // avoid warning
#endif

        delete _pImpl;
        _pImpl = 0;
    }
}

//=========================================================================
void SjApplet2::setSizePixel( const Size & rSize )
{
    if(_pImpl)
        _pImpl->setSize(rSize);
}

void SjApplet2::appletRestart()
{
    if(_pImpl)
        _pImpl->restart();
}

void SjApplet2::appletReload()
{
    if(_pImpl)
        _pImpl->reload();
}

void SjApplet2::appletStart()
{
    if(_pImpl)
        _pImpl->start();
}

void SjApplet2::appletStop()
{
    if(_pImpl)
        _pImpl->stop();
}

void SjApplet2::appletClose()
{
    if(_pImpl)
        _pImpl->close();
}

// Fuer SO3, Wrapper fuer Applet liefern
SjJScriptAppletObject * SjApplet2::GetJScriptApplet()
{
    OSL_TRACE("SjApplet2::GetJScriptApplet\n");

    return NULL;
}

// Settings are detected by the JavaVM service
// This function is not necessary anymore
void SjApplet2::settingsChanged(void)
{}
<commit_msg>INTEGRATION: CWS changefileheader (1.15.20); FILE MERGED 2008/03/31 15:27:22 rt 1.15.20.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sjapplet.cxx,v $
 * $Revision: 1.16 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "sal/config.h"

#include "sjapplet.hxx"

#include "osl/diagnose.h"
#include "rtl/string.hxx"
#include "rtl/ustring.hxx"

#include "sjapplet_impl.hxx"

using namespace ::rtl;
using namespace ::com::sun::star::uno;

SjApplet2::SjApplet2()
  : _pImpl(new SjApplet2_Impl())
{
}

SjApplet2::~SjApplet2()
{
    delete _pImpl;
}

//=========================================================================
void SjApplet2::Init(
    com::sun::star::uno::Reference<
        com::sun::star::uno::XComponentContext > const & context,
    Window * pParentWin, const INetURLObject & rDocBase,
    const SvCommandList & rCmdList)
{
    try {
        if(_pImpl)
            _pImpl->init(pParentWin, context, rDocBase, rCmdList);
    }
    catch(RuntimeException & runtimeException) {
#if OSL_DEBUG_LEVEL > 1
        OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_TRACE("sjapplet.cxx: SjApplet2::Init - exception occurred: %s\n", message.getStr());
#else
        (void) runtimeException; // avoid warning
#endif

        delete _pImpl;
        _pImpl = 0;
    }
}

//=========================================================================
void SjApplet2::setSizePixel( const Size & rSize )
{
    if(_pImpl)
        _pImpl->setSize(rSize);
}

void SjApplet2::appletRestart()
{
    if(_pImpl)
        _pImpl->restart();
}

void SjApplet2::appletReload()
{
    if(_pImpl)
        _pImpl->reload();
}

void SjApplet2::appletStart()
{
    if(_pImpl)
        _pImpl->start();
}

void SjApplet2::appletStop()
{
    if(_pImpl)
        _pImpl->stop();
}

void SjApplet2::appletClose()
{
    if(_pImpl)
        _pImpl->close();
}

// Fuer SO3, Wrapper fuer Applet liefern
SjJScriptAppletObject * SjApplet2::GetJScriptApplet()
{
    OSL_TRACE("SjApplet2::GetJScriptApplet\n");

    return NULL;
}

// Settings are detected by the JavaVM service
// This function is not necessary anymore
void SjApplet2::settingsChanged(void)
{}
<|endoftext|>


<commit_before>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace Detailed {

namespace Discretizations {

namespace LA {

namespace Backend {

namespace Container {

namespace Eigen {

template <class EntryImp>
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix<EntryType> ThisType;

  typedef ::Eigen::SparseMatrix<EntryType> StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class SparseMatrix

template <class EntryImp>
class DenseMatrix;

template <>
class DenseMatrix<double>
{
public:
  typedef double EntryType;

  typedef DenseMatrix<EntryType> ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseMatrix

template <class EntryImp>
class DenseVector;

template <>
class DenseVector<double>
{
public:
  typedef double EntryType;

  typedef DenseVector<EntryType> ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size)
    , storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr<StorageType> storage)
    : size_(storage->rows())
    , storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_    = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

  const EntryType& operator[](unsigned int i) const
  {
    return storage_->coeff(i);
  }

  EntryType& operator[](unsigned int i)
  {
    return storage_->coeffRef(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace Discretizations

} // namespace Detailed

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<commit_msg>[la.backend.container.eigen] minor change<commit_after>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace Detailed {

namespace Discretizations {

namespace LA {

namespace Backend {

namespace Container {

namespace Eigen {

template <class EntryImp>
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix<EntryType> ThisType;

  typedef ::Eigen::SparseMatrix<EntryType> StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows_)
    , cols_(other.cols_)
    , storage_(other.storage_)
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class SparseMatrix

template <class EntryImp>
class DenseMatrix;

template <>
class DenseMatrix<double>
{
public:
  typedef double EntryType;

  typedef DenseMatrix<EntryType> ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows)
    , cols_(cols)
    , storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr<StorageType> storage)
    : rows_(storage->rows())
    , cols_(storage->cols())
    , storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows())
    , cols_(other.cols())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_    = other.rows();
    cols_    = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseMatrix

template <class EntryImp>
class DenseVector;

template <>
class DenseVector<double>
{
public:
  typedef double EntryType;

  typedef DenseVector<EntryType> ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size)
    , storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr<StorageType> storage)
    : size_(storage->rows())
    , storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size())
    , storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_    = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr<StorageType> storage()
  {
    return storage_;
  }

  const Dune::shared_ptr<StorageType> storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

  const EntryType& operator[](unsigned int i) const
  {
    return storage_->coeff(i);
  }

  EntryType& operator[](unsigned int i)
  {
    return storage_->coeffRef(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr<StorageType> storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace Discretizations

} // namespace Detailed

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<|endoftext|>


<commit_before><commit_msg>update comment<commit_after><|endoftext|>


<commit_before>
#include <yafraycore/tiledintegrator.h>
#include <core_api/imagefilm.h>
#include <core_api/camera.h>
#include <yafraycore/timer.h>
#include <yafraycore/scr_halton.h>
#include <utilities/mcqmc.h>
#include <utilities/sample_utils.h>
#include <sstream>

__BEGIN_YAFRAY

#ifdef USING_THREADS

class renderWorker_t: public yafthreads::thread_t
{
	public:
		renderWorker_t(tiledIntegrator_t *it, scene_t *s, imageFilm_t *f, threadControl_t *c, int id, int smpls, int offs=0, bool adptv=false):
			integrator(it), scene(s), imageFilm(f), control(c), samples(smpls), offset(offs), threadID(id), adaptive(adptv)
		{ /* std::cout << "renderWorker_t::renderWorker_t(): *this="<<(void*)this<<std::endl; */ };
		virtual void body();
	protected:
		tiledIntegrator_t *integrator;
		scene_t *scene;
		imageFilm_t *imageFilm;
		threadControl_t *control;
		int samples, offset;
		int threadID;
		bool adaptive;
};

void renderWorker_t::body()
{
	renderArea_t a;
	while(imageFilm->nextArea(a))
	{
		if(scene->getSignals() & Y_SIG_ABORT) break;
		integrator->renderTile(a, samples, offset, adaptive, threadID);
//		imageFilm->finishArea(a);
		control->countCV.lock();
		control->areas.push_back(a);
		control->countCV.signal();
		control->countCV.unlock();
	}
	control->countCV.lock();
	++(control->finishedThreads);
	control->countCV.signal();
	control->countCV.unlock();
}
#endif

bool tiledIntegrator_t::render(imageFilm_t *image)
{
	std::stringstream passString;
	imageFilm = image;
	scene->getAAParameters(AA_samples, AA_passes, AA_inc_samples, AA_threshold);
	Y_INFO << integratorName << ": Rendering "<<AA_passes<<" passes\n";
	Y_INFO << integratorName << ": Min. " << AA_samples << " samples\n";
	Y_INFO << integratorName << ": "<< AA_inc_samples << " per additional pass\n";
	Y_INFO << integratorName << ": Max. "<<AA_samples + std::max(0,AA_passes-1)*AA_inc_samples<<" total samples\n";
	passString << "Rendering pass 1 of " << std::max(1, AA_passes) << "...";
	if(intpb) intpb->setTag(passString.str().c_str());

	gTimer.addEvent("rendert");
	gTimer.start("rendert");
	imageFilm->init(AA_passes);

	renderPass(AA_samples, 0, false);
	for(int i=1; i<AA_passes; ++i)
	{
		if(scene->getSignals() & Y_SIG_ABORT) break;
		imageFilm->setAAThreshold(AA_threshold);
		imageFilm->nextPass(true);
		renderPass(AA_inc_samples, AA_samples + (i-1)*AA_inc_samples, true);
	}

	gTimer.stop("rendert");
	Y_INFO << integratorName << ": Overall rendertime: "<< gTimer.getTime("rendert")<<"s\n";

	return true;
}

bool tiledIntegrator_t::renderPass(int samples, int offset, bool adaptive)
{
	int nthreads = scene->getNumThreads();
#ifdef USING_THREADS
	if(nthreads>1)
	{
		threadControl_t tc;
		std::vector<renderWorker_t *> workers;
		for(int i=0;i<nthreads;++i) workers.push_back(new renderWorker_t(this, scene, imageFilm, &tc, i, samples, offset, adaptive));
		for(int i=0;i<nthreads;++i)
		{
			workers[i]->run();
		}
		//update finished tiles
		tc.countCV.lock();
		while(tc.finishedThreads < nthreads)
		{
			tc.countCV.wait();
			for(size_t i=0; i<tc.areas.size(); ++i) imageFilm->finishArea(tc.areas[i]);
			tc.areas.clear();
		}
		tc.countCV.unlock();
		//join all threads (although they probably have exited already, but not necessarily):
		for(int i=0;i<nthreads;++i) delete workers[i];
	}
	else
	{
#endif
		renderArea_t a;
		while(imageFilm->nextArea(a))
		{
			if(scene->getSignals() & Y_SIG_ABORT) break;
			renderTile(a, samples, offset, adaptive,0);
			imageFilm->finishArea(a);
		}
#ifdef USING_THREADS
	}
#endif
	return true; //hm...quite useless the return value :)
}

bool tiledIntegrator_t::renderTile(renderArea_t &a, int n_samples, int offset, bool adaptive, int threadID)
{
	int x, y;
	const camera_t* camera = scene->getCamera();
	bool do_depth = scene->doDepth();
	x=camera->resX();
	y=camera->resY();
	diffRay_t c_ray;
	ray_t d_ray;
	PFLOAT dx=0.5, dy=0.5, d1=1.0/(PFLOAT)n_samples;
	float lens_u=0.5f, lens_v=0.5f;
	PFLOAT wt, wt_dummy;
	random_t prng(offset*(x*a.Y+a.X)+123);
	renderState_t rstate(&prng);
	rstate.threadID = threadID;
	rstate.cam = camera;
	bool sampleLns = camera->sampleLense();
	int pass_offs=offset, end_x=a.X+a.W, end_y=a.Y+a.H;
	for(int i=a.Y; i<end_y; ++i)
	{
		for(int j=a.X; j<end_x; ++j)
		{
			if(scene->getSignals() & Y_SIG_ABORT) break;
			if(adaptive)
			{
				if(!imageFilm->doMoreSamples(j, i)) continue;
			}
			rstate.pixelNumber = x*i+j;
			//rstate.screenpos = point3d_t(2.0f * j / x - 1.0f, -2.0f * i / y + 1.0f, 0.f); // screen position in -1..1 coordinates
			rstate.samplingOffs = fnv_32a_buf(i*fnv_32a_buf(j));//fnv_32a_buf(rstate.pixelNumber);
			float toff = scrHalton(5, pass_offs+rstate.samplingOffs); // **shall be just the pass number...**
			for(int sample=0; sample<n_samples; ++sample)
			{
				rstate.setDefaults();
				rstate.pixelSample = pass_offs+sample;
				rstate.time = addMod1((PFLOAT)sample*d1, toff);//(0.5+(PFLOAT)sample)*d1;
				// the (1/n, Larcher&Pillichshammer-Seq.) only gives good coverage when total sample count is known
				// hence we use scrambled (Sobol, van-der-Corput) for multipass AA
				if(AA_passes>1)
				{
					dx = RI_S(rstate.pixelSample, rstate.samplingOffs);
					dy = RI_vdC(rstate.pixelSample, rstate.samplingOffs);
				}
				else if(n_samples > 1)
				{
					dx = (0.5+(PFLOAT)sample)*d1;
					dy = RI_LP(sample+rstate.samplingOffs);
				}
				if(sampleLns)
				{
					lens_u = scrHalton(3, rstate.pixelSample+rstate.samplingOffs);
					lens_v = scrHalton(4, rstate.pixelSample+rstate.samplingOffs);
				}
				c_ray = camera->shootRay(j+dx, i+dy, lens_u, lens_v, wt);
				if(wt==0.0) continue;
				//setup ray differentials
				d_ray = camera->shootRay(j+1+dx, i+dy, lens_u, lens_v, wt_dummy);
				c_ray.xfrom = d_ray.from;
				c_ray.xdir = d_ray.dir;
				d_ray = camera->shootRay(j+dx, i+1+dy, lens_u, lens_v, wt_dummy);
				c_ray.yfrom = d_ray.from;
				c_ray.ydir = d_ray.dir;
				c_ray.time = rstate.time;
				c_ray.hasDifferentials = true;
				// col = T * L_o + L_v
				colorA_t col = integrate(rstate, c_ray); // L_o
				// I really don't like this here, bert...
				col *= scene->volIntegrator->transmittance(rstate, c_ray); // T
				col += scene->volIntegrator->integrate(rstate, c_ray); // L_v
				imageFilm->addSample(wt * col, j, i, dx, dy,/*.5f, .5f,*/ &a);
			}
			if(do_depth) imageFilm->setChanPixel(c_ray.tmax, 0, j, i);
		}
	}
	return true;
}

__END_YAFRAY
<commit_msg>- Core: integrator now adds a black sample when camera wt == 0 instead of ommiting sampling, this allows for angular camera circular mask to be antialiased (needs thorough testing)<commit_after>
#include <yafraycore/tiledintegrator.h>
#include <core_api/imagefilm.h>
#include <core_api/camera.h>
#include <yafraycore/timer.h>
#include <yafraycore/scr_halton.h>
#include <utilities/mcqmc.h>
#include <utilities/sample_utils.h>
#include <sstream>

__BEGIN_YAFRAY

#ifdef USING_THREADS

class renderWorker_t: public yafthreads::thread_t
{
	public:
		renderWorker_t(tiledIntegrator_t *it, scene_t *s, imageFilm_t *f, threadControl_t *c, int id, int smpls, int offs=0, bool adptv=false):
			integrator(it), scene(s), imageFilm(f), control(c), samples(smpls), offset(offs), threadID(id), adaptive(adptv)
		{ /* std::cout << "renderWorker_t::renderWorker_t(): *this="<<(void*)this<<std::endl; */ };
		virtual void body();
	protected:
		tiledIntegrator_t *integrator;
		scene_t *scene;
		imageFilm_t *imageFilm;
		threadControl_t *control;
		int samples, offset;
		int threadID;
		bool adaptive;
};

void renderWorker_t::body()
{
	renderArea_t a;
	while(imageFilm->nextArea(a))
	{
		if(scene->getSignals() & Y_SIG_ABORT) break;
		integrator->renderTile(a, samples, offset, adaptive, threadID);
//		imageFilm->finishArea(a);
		control->countCV.lock();
		control->areas.push_back(a);
		control->countCV.signal();
		control->countCV.unlock();
	}
	control->countCV.lock();
	++(control->finishedThreads);
	control->countCV.signal();
	control->countCV.unlock();
}
#endif

bool tiledIntegrator_t::render(imageFilm_t *image)
{
	std::stringstream passString;
	imageFilm = image;
	scene->getAAParameters(AA_samples, AA_passes, AA_inc_samples, AA_threshold);
	Y_INFO << integratorName << ": Rendering "<<AA_passes<<" passes\n";
	Y_INFO << integratorName << ": Min. " << AA_samples << " samples\n";
	Y_INFO << integratorName << ": "<< AA_inc_samples << " per additional pass\n";
	Y_INFO << integratorName << ": Max. "<<AA_samples + std::max(0,AA_passes-1)*AA_inc_samples<<" total samples\n";
	passString << "Rendering pass 1 of " << std::max(1, AA_passes) << "...";
	if(intpb) intpb->setTag(passString.str().c_str());

	gTimer.addEvent("rendert");
	gTimer.start("rendert");
	imageFilm->init(AA_passes);

	renderPass(AA_samples, 0, false);
	for(int i=1; i<AA_passes; ++i)
	{
		if(scene->getSignals() & Y_SIG_ABORT) break;
		imageFilm->setAAThreshold(AA_threshold);
		imageFilm->nextPass(true);
		renderPass(AA_inc_samples, AA_samples + (i-1)*AA_inc_samples, true);
	}

	gTimer.stop("rendert");
	Y_INFO << integratorName << ": Overall rendertime: "<< gTimer.getTime("rendert")<<"s\n";

	return true;
}

bool tiledIntegrator_t::renderPass(int samples, int offset, bool adaptive)
{
	int nthreads = scene->getNumThreads();
#ifdef USING_THREADS
	if(nthreads>1)
	{
		threadControl_t tc;
		std::vector<renderWorker_t *> workers;
		for(int i=0;i<nthreads;++i) workers.push_back(new renderWorker_t(this, scene, imageFilm, &tc, i, samples, offset, adaptive));
		for(int i=0;i<nthreads;++i)
		{
			workers[i]->run();
		}
		//update finished tiles
		tc.countCV.lock();
		while(tc.finishedThreads < nthreads)
		{
			tc.countCV.wait();
			for(size_t i=0; i<tc.areas.size(); ++i) imageFilm->finishArea(tc.areas[i]);
			tc.areas.clear();
		}
		tc.countCV.unlock();
		//join all threads (although they probably have exited already, but not necessarily):
		for(int i=0;i<nthreads;++i) delete workers[i];
	}
	else
	{
#endif
		renderArea_t a;
		while(imageFilm->nextArea(a))
		{
			if(scene->getSignals() & Y_SIG_ABORT) break;
			renderTile(a, samples, offset, adaptive,0);
			imageFilm->finishArea(a);
		}
#ifdef USING_THREADS
	}
#endif
	return true; //hm...quite useless the return value :)
}

bool tiledIntegrator_t::renderTile(renderArea_t &a, int n_samples, int offset, bool adaptive, int threadID)
{
	int x, y;
	const camera_t* camera = scene->getCamera();
	bool do_depth = scene->doDepth();
	x=camera->resX();
	y=camera->resY();
	diffRay_t c_ray;
	ray_t d_ray;
	PFLOAT dx=0.5, dy=0.5, d1=1.0/(PFLOAT)n_samples;
	float lens_u=0.5f, lens_v=0.5f;
	PFLOAT wt, wt_dummy;
	random_t prng(offset*(x*a.Y+a.X)+123);
	renderState_t rstate(&prng);
	rstate.threadID = threadID;
	rstate.cam = camera;
	bool sampleLns = camera->sampleLense();
	int pass_offs=offset, end_x=a.X+a.W, end_y=a.Y+a.H;
	for(int i=a.Y; i<end_y; ++i)
	{
		for(int j=a.X; j<end_x; ++j)
		{
			if(scene->getSignals() & Y_SIG_ABORT) break;
			if(adaptive)
			{
				if(!imageFilm->doMoreSamples(j, i)) continue;
			}
			rstate.pixelNumber = x*i+j;
			//rstate.screenpos = point3d_t(2.0f * j / x - 1.0f, -2.0f * i / y + 1.0f, 0.f); // screen position in -1..1 coordinates
			rstate.samplingOffs = fnv_32a_buf(i*fnv_32a_buf(j));//fnv_32a_buf(rstate.pixelNumber);
			float toff = scrHalton(5, pass_offs+rstate.samplingOffs); // **shall be just the pass number...**
			for(int sample=0; sample<n_samples; ++sample)
			{
				rstate.setDefaults();
				rstate.pixelSample = pass_offs+sample;
				rstate.time = addMod1((PFLOAT)sample*d1, toff);//(0.5+(PFLOAT)sample)*d1;
				// the (1/n, Larcher&Pillichshammer-Seq.) only gives good coverage when total sample count is known
				// hence we use scrambled (Sobol, van-der-Corput) for multipass AA
				if(AA_passes>1)
				{
					dx = RI_S(rstate.pixelSample, rstate.samplingOffs);
					dy = RI_vdC(rstate.pixelSample, rstate.samplingOffs);
				}
				else if(n_samples > 1)
				{
					dx = (0.5+(PFLOAT)sample)*d1;
					dy = RI_LP(sample+rstate.samplingOffs);
				}
				if(sampleLns)
				{
					lens_u = scrHalton(3, rstate.pixelSample+rstate.samplingOffs);
					lens_v = scrHalton(4, rstate.pixelSample+rstate.samplingOffs);
				}
				c_ray = camera->shootRay(j+dx, i+dy, lens_u, lens_v, wt);
				if(wt==0.0)
				{
					imageFilm->addSample(colorA_t(0.f), j, i, dx, dy, &a);
					continue;
				}
				//setup ray differentials
				d_ray = camera->shootRay(j+1+dx, i+dy, lens_u, lens_v, wt_dummy);
				c_ray.xfrom = d_ray.from;
				c_ray.xdir = d_ray.dir;
				d_ray = camera->shootRay(j+dx, i+1+dy, lens_u, lens_v, wt_dummy);
				c_ray.yfrom = d_ray.from;
				c_ray.ydir = d_ray.dir;
				c_ray.time = rstate.time;
				c_ray.hasDifferentials = true;
				// col = T * L_o + L_v
				colorA_t col = integrate(rstate, c_ray); // L_o
				// I really don't like this here, bert...
				col *= scene->volIntegrator->transmittance(rstate, c_ray); // T
				col += scene->volIntegrator->integrate(rstate, c_ray); // L_v
				imageFilm->addSample(wt * col, j, i, dx, dy,/*.5f, .5f,*/ &a);
			}
			if(do_depth) imageFilm->setChanPixel(c_ray.tmax, 0, j, i);
		}
	}
	return true;
}

__END_YAFRAY
<|endoftext|>