<commit_before>// Copyright (c) 2010 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.

#if defined(OS_MACOSX)
#include <signal.h>
#include <unistd.h>
#endif  // OS_MACOSX

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/metrics/field_trial.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
#include "base/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "chrome/renderer/render_process_impl.h"
#include "chrome/renderer/render_thread.h"
#include "content/common/main_function_params.h"
#include "content/common/hi_res_timer_manager.h"
#include "grit/generated_resources.h"
#include "net/base/net_module.h"
#include "ui/base/system_monitor/system_monitor.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/gfx_module.h"

#if defined(OS_MACOSX)
#include "base/eintr_wrapper.h"
#include "chrome/app/breakpad_mac.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#endif  // OS_MACOSX

#if defined(OS_MACOSX)
namespace {

// TODO(viettrungluu): crbug.com/28547: The following signal handling is needed,
// as a stopgap, to avoid leaking due to not releasing Breakpad properly.
// Without this problem, this could all be eliminated. Remove when Breakpad is
// fixed?
// TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing).
// The code should be properly shared (or this code should be eliminated).
int g_shutdown_pipe_write_fd = -1;

void SIGTERMHandler(int signal) {
  RAW_CHECK(signal == SIGTERM);
  RAW_LOG(INFO, "Handling SIGTERM in renderer.");

  // Reinstall the default handler.  We had one shot at graceful shutdown.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_DFL;
  CHECK(sigaction(signal, &action, NULL) == 0);

  RAW_CHECK(g_shutdown_pipe_write_fd != -1);
  size_t bytes_written = 0;
  do {
    int rv = HANDLE_EINTR(
        write(g_shutdown_pipe_write_fd,
              reinterpret_cast<const char*>(&signal) + bytes_written,
              sizeof(signal) - bytes_written));
    RAW_CHECK(rv >= 0);
    bytes_written += rv;
  } while (bytes_written < sizeof(signal));

  RAW_LOG(INFO, "Wrote signal to shutdown pipe.");
}

class ShutdownDetector : public base::PlatformThread::Delegate {
 public:
  explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) {
    CHECK(shutdown_fd_ != -1);
  }

  virtual void ThreadMain() {
    int signal;
    size_t bytes_read = 0;
    ssize_t ret;
    do {
      ret = HANDLE_EINTR(
          read(shutdown_fd_,
               reinterpret_cast<char*>(&signal) + bytes_read,
               sizeof(signal) - bytes_read));
      if (ret < 0) {
        NOTREACHED() << "Unexpected error: " << strerror(errno);
        break;
      } else if (ret == 0) {
        NOTREACHED() << "Unexpected closure of shutdown pipe.";
        break;
      }
      bytes_read += ret;
    } while (bytes_read < sizeof(signal));

    if (bytes_read == sizeof(signal))
      VLOG(1) << "Handling shutdown for signal " << signal << ".";
    else
      VLOG(1) << "Handling shutdown for unknown signal.";

    // Clean up Breakpad if necessary.
    if (IsCrashReporterEnabled()) {
      VLOG(1) << "Cleaning up Breakpad.";
      DestructCrashReporter();
    } else {
      VLOG(1) << "Breakpad not enabled; no clean-up needed.";
    }

    // Something went seriously wrong, so get out.
    if (bytes_read != sizeof(signal)) {
      LOG(WARNING) << "Failed to get signal. Quitting ungracefully.";
      _exit(1);
    }

    // Re-raise the signal.
    kill(getpid(), signal);

    // The signal may be handled on another thread. Give that a chance to
    // happen.
    sleep(3);

    // We really should be dead by now.  For whatever reason, we're not. Exit
    // immediately, with the exit status set to the signal number with bit 8
    // set.  On the systems that we care about, this exit status is what is
    // normally used to indicate an exit by this signal's default handler.
    // This mechanism isn't a de jure standard, but even in the worst case, it
    // should at least result in an immediate exit.
    LOG(WARNING) << "Still here, exiting really ungracefully.";
    _exit(signal | (1 << 7));
  }

 private:
  const int shutdown_fd_;

  DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
};

}  // namespace
#endif  // OS_MACOSX

// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleRendererErrorTestParameters(const CommandLine& command_line) {
  // This parameter causes an assertion.
  if (command_line.HasSwitch(switches::kRendererAssertTest)) {
    DCHECK(false);
  }

#if !defined(OFFICIAL_BUILD)
  // This parameter causes an assertion too.
  if (command_line.HasSwitch(switches::kRendererCheckFalseTest)) {
    CHECK(false);
  }
#endif  // !defined(OFFICIAL_BUILD)

  // This parameter causes a null pointer crash (crash reporter trigger).
  if (command_line.HasSwitch(switches::kRendererCrashTest)) {
    int* bad_pointer = NULL;
    *bad_pointer = 0;
  }

  if (command_line.HasSwitch(switches::kRendererStartupDialog)) {
    ChildProcess::WaitForDebugger("Renderer");
  }
}

// This is a simplified version of the browser Jankometer, which measures
// the processing time of tasks on the render thread.
class RendererMessageLoopObserver : public MessageLoop::TaskObserver {
 public:
  RendererMessageLoopObserver()
      : process_times_(base::Histogram::FactoryGet(
            "Chrome.ProcMsgL RenderThread",
            1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag)) {}
  virtual ~RendererMessageLoopObserver() {}

  virtual void WillProcessTask(const Task* task) {
    begin_process_message_ = base::TimeTicks::Now();
  }

  virtual void DidProcessTask(const Task* task) {
    if (begin_process_message_ != base::TimeTicks())
      process_times_->AddTime(base::TimeTicks::Now() - begin_process_message_);
  }

 private:
  base::TimeTicks begin_process_message_;
  scoped_refptr<base::Histogram> process_times_;
  DISALLOW_COPY_AND_ASSIGN(RendererMessageLoopObserver);
};

// mainline routine for running as the Renderer process
int RendererMain(const MainFunctionParams& parameters) {
  TRACE_EVENT_BEGIN("RendererMain", 0, "");

  const CommandLine& parsed_command_line = parameters.command_line_;
  base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_;

#if defined(OS_MACOSX)
  // TODO(viettrungluu): Code taken from browser_main.cc.
  int pipefd[2];
  int ret = pipe(pipefd);
  if (ret < 0) {
    PLOG(DFATAL) << "Failed to create pipe";
  } else {
    int shutdown_pipe_read_fd = pipefd[0];
    g_shutdown_pipe_write_fd = pipefd[1];
    const size_t kShutdownDetectorThreadStackSize = 4096;
    if (!base::PlatformThread::CreateNonJoinable(
            kShutdownDetectorThreadStackSize,
            new ShutdownDetector(shutdown_pipe_read_fd))) {
      LOG(DFATAL) << "Failed to create shutdown detector task.";
    }
  }

  // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking
  // Mach ports.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIGTERMHandler;
  CHECK(sigaction(SIGTERM, &action, NULL) == 0);
#endif  // OS_MACOSX

#if defined(OS_CHROMEOS)
  // As Zygote process starts up earlier than browser process gets its own
  // locale (at login time for Chrome OS), we have to set the ICU default
  // locale for renderer process here.
  // ICU locale will be used for fallback font selection etc.
  if (parsed_command_line.HasSwitch(switches::kLang)) {
    const std::string locale =
        parsed_command_line.GetSwitchValueASCII(switches::kLang);
    base::i18n::SetICUDefaultLocale(locale);
  }
#endif

  // Configure modules that need access to resources.
  net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
  gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);

  // This function allows pausing execution using the --renderer-startup-dialog
  // flag allowing us to attach a debugger.
  // Do not move this function down since that would mean we can't easily debug
  // whatever occurs before it.
  HandleRendererErrorTestParameters(parsed_command_line);

  RendererMainPlatformDelegate platform(parameters);

  base::StatsScope<base::StatsCounterTimer>
      startup_timer(chrome::Counters::renderer_main());

  RendererMessageLoopObserver task_observer;
#if defined(OS_MACOSX)
  // As long as we use Cocoa in the renderer (for the forseeable future as of
  // now; see http://crbug.com/13890 for info) we need to have a UI loop.
  MessageLoop main_message_loop(MessageLoop::TYPE_UI);
#else
  // The main message loop of the renderer services doesn't have IO or UI tasks,
  // unless in-process-plugins is used.
  MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ?
              MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT);
#endif
  main_message_loop.AddTaskObserver(&task_observer);

  base::PlatformThread::SetName("CrRendererMain");

  ui::SystemMonitor system_monitor;
  HighResolutionTimerManager hi_res_timer_manager;

  platform.PlatformInitialize();

  bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
  platform.InitSandboxTests(no_sandbox);

  // Initialize histogram statistics gathering system.
  // Don't create StatisticsRecorder in the single process mode.
  scoped_ptr<base::StatisticsRecorder> statistics;
  if (!base::StatisticsRecorder::IsActive()) {
    statistics.reset(new base::StatisticsRecorder());
  }

  // Initialize statistical testing infrastructure.
  base::FieldTrialList field_trial;
  // Ensure any field trials in browser are reflected into renderer.
  if (parsed_command_line.HasSwitch(switches::kForceFieldTestNameAndValue)) {
    std::string persistent = parsed_command_line.GetSwitchValueASCII(
        switches::kForceFieldTestNameAndValue);
    bool ret = field_trial.CreateTrialsInChildProcess(persistent);
    DCHECK(ret);
  }

  // Load pepper plugins before engaging the sandbox.
  PepperPluginRegistry::GetInstance();

  {
#if !defined(OS_LINUX)
    // TODO(markus): Check if it is OK to unconditionally move this
    // instruction down.
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif
    bool run_loop = true;
    if (!no_sandbox) {
      run_loop = platform.EnableSandbox();
    } else {
      LOG(ERROR) << "Running without renderer sandbox";
    }
#if defined(OS_LINUX)
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif

    platform.RunSandboxTests();

    startup_timer.Stop();  // End of Startup Time Measurement.

    if (run_loop) {
      if (pool)
        pool->Recycle();
      TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0);
      MessageLoop::current()->Run();
      TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0);
    }
  }
  platform.PlatformUninitialize();
  TRACE_EVENT_END("RendererMain", 0, "");
  return 0;
}
<commit_msg>Revert 78511 - Add a histogram to measure task execution time for the render thread.<commit_after>// Copyright (c) 2010 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.

#if defined(OS_MACOSX)
#include <signal.h>
#include <unistd.h>
#endif  // OS_MACOSX

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/metrics/field_trial.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_util.h"
#include "base/threading/platform_thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "chrome/renderer/render_process_impl.h"
#include "chrome/renderer/render_thread.h"
#include "content/common/main_function_params.h"
#include "content/common/hi_res_timer_manager.h"
#include "grit/generated_resources.h"
#include "net/base/net_module.h"
#include "ui/base/system_monitor/system_monitor.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/gfx_module.h"

#if defined(OS_MACOSX)
#include "base/eintr_wrapper.h"
#include "chrome/app/breakpad_mac.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#endif  // OS_MACOSX

#if defined(OS_MACOSX)
namespace {

// TODO(viettrungluu): crbug.com/28547: The following signal handling is needed,
// as a stopgap, to avoid leaking due to not releasing Breakpad properly.
// Without this problem, this could all be eliminated. Remove when Breakpad is
// fixed?
// TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing).
// The code should be properly shared (or this code should be eliminated).
int g_shutdown_pipe_write_fd = -1;

void SIGTERMHandler(int signal) {
  RAW_CHECK(signal == SIGTERM);
  RAW_LOG(INFO, "Handling SIGTERM in renderer.");

  // Reinstall the default handler.  We had one shot at graceful shutdown.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_DFL;
  CHECK(sigaction(signal, &action, NULL) == 0);

  RAW_CHECK(g_shutdown_pipe_write_fd != -1);
  size_t bytes_written = 0;
  do {
    int rv = HANDLE_EINTR(
        write(g_shutdown_pipe_write_fd,
              reinterpret_cast<const char*>(&signal) + bytes_written,
              sizeof(signal) - bytes_written));
    RAW_CHECK(rv >= 0);
    bytes_written += rv;
  } while (bytes_written < sizeof(signal));

  RAW_LOG(INFO, "Wrote signal to shutdown pipe.");
}

class ShutdownDetector : public base::PlatformThread::Delegate {
 public:
  explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) {
    CHECK(shutdown_fd_ != -1);
  }

  virtual void ThreadMain() {
    int signal;
    size_t bytes_read = 0;
    ssize_t ret;
    do {
      ret = HANDLE_EINTR(
          read(shutdown_fd_,
               reinterpret_cast<char*>(&signal) + bytes_read,
               sizeof(signal) - bytes_read));
      if (ret < 0) {
        NOTREACHED() << "Unexpected error: " << strerror(errno);
        break;
      } else if (ret == 0) {
        NOTREACHED() << "Unexpected closure of shutdown pipe.";
        break;
      }
      bytes_read += ret;
    } while (bytes_read < sizeof(signal));

    if (bytes_read == sizeof(signal))
      VLOG(1) << "Handling shutdown for signal " << signal << ".";
    else
      VLOG(1) << "Handling shutdown for unknown signal.";

    // Clean up Breakpad if necessary.
    if (IsCrashReporterEnabled()) {
      VLOG(1) << "Cleaning up Breakpad.";
      DestructCrashReporter();
    } else {
      VLOG(1) << "Breakpad not enabled; no clean-up needed.";
    }

    // Something went seriously wrong, so get out.
    if (bytes_read != sizeof(signal)) {
      LOG(WARNING) << "Failed to get signal. Quitting ungracefully.";
      _exit(1);
    }

    // Re-raise the signal.
    kill(getpid(), signal);

    // The signal may be handled on another thread. Give that a chance to
    // happen.
    sleep(3);

    // We really should be dead by now.  For whatever reason, we're not. Exit
    // immediately, with the exit status set to the signal number with bit 8
    // set.  On the systems that we care about, this exit status is what is
    // normally used to indicate an exit by this signal's default handler.
    // This mechanism isn't a de jure standard, but even in the worst case, it
    // should at least result in an immediate exit.
    LOG(WARNING) << "Still here, exiting really ungracefully.";
    _exit(signal | (1 << 7));
  }

 private:
  const int shutdown_fd_;

  DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
};

}  // namespace
#endif  // OS_MACOSX

// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleRendererErrorTestParameters(const CommandLine& command_line) {
  // This parameter causes an assertion.
  if (command_line.HasSwitch(switches::kRendererAssertTest)) {
    DCHECK(false);
  }

#if !defined(OFFICIAL_BUILD)
  // This parameter causes an assertion too.
  if (command_line.HasSwitch(switches::kRendererCheckFalseTest)) {
    CHECK(false);
  }
#endif  // !defined(OFFICIAL_BUILD)

  // This parameter causes a null pointer crash (crash reporter trigger).
  if (command_line.HasSwitch(switches::kRendererCrashTest)) {
    int* bad_pointer = NULL;
    *bad_pointer = 0;
  }

  if (command_line.HasSwitch(switches::kRendererStartupDialog)) {
    ChildProcess::WaitForDebugger("Renderer");
  }
}

// mainline routine for running as the Renderer process
int RendererMain(const MainFunctionParams& parameters) {
  TRACE_EVENT_BEGIN("RendererMain", 0, "");

  const CommandLine& parsed_command_line = parameters.command_line_;
  base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_;

#if defined(OS_MACOSX)
  // TODO(viettrungluu): Code taken from browser_main.cc.
  int pipefd[2];
  int ret = pipe(pipefd);
  if (ret < 0) {
    PLOG(DFATAL) << "Failed to create pipe";
  } else {
    int shutdown_pipe_read_fd = pipefd[0];
    g_shutdown_pipe_write_fd = pipefd[1];
    const size_t kShutdownDetectorThreadStackSize = 4096;
    if (!base::PlatformThread::CreateNonJoinable(
            kShutdownDetectorThreadStackSize,
            new ShutdownDetector(shutdown_pipe_read_fd))) {
      LOG(DFATAL) << "Failed to create shutdown detector task.";
    }
  }

  // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking
  // Mach ports.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIGTERMHandler;
  CHECK(sigaction(SIGTERM, &action, NULL) == 0);
#endif  // OS_MACOSX

#if defined(OS_CHROMEOS)
  // As Zygote process starts up earlier than browser process gets its own
  // locale (at login time for Chrome OS), we have to set the ICU default
  // locale for renderer process here.
  // ICU locale will be used for fallback font selection etc.
  if (parsed_command_line.HasSwitch(switches::kLang)) {
    const std::string locale =
        parsed_command_line.GetSwitchValueASCII(switches::kLang);
    base::i18n::SetICUDefaultLocale(locale);
  }
#endif

  // Configure modules that need access to resources.
  net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
  gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);

  // This function allows pausing execution using the --renderer-startup-dialog
  // flag allowing us to attach a debugger.
  // Do not move this function down since that would mean we can't easily debug
  // whatever occurs before it.
  HandleRendererErrorTestParameters(parsed_command_line);

  RendererMainPlatformDelegate platform(parameters);

  base::StatsScope<base::StatsCounterTimer>
      startup_timer(chrome::Counters::renderer_main());

#if defined(OS_MACOSX)
  // As long as we use Cocoa in the renderer (for the forseeable future as of
  // now; see http://crbug.com/13890 for info) we need to have a UI loop.
  MessageLoop main_message_loop(MessageLoop::TYPE_UI);
#else
  // The main message loop of the renderer services doesn't have IO or UI tasks,
  // unless in-process-plugins is used.
  MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ?
              MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT);
#endif

  base::PlatformThread::SetName("CrRendererMain");

  ui::SystemMonitor system_monitor;
  HighResolutionTimerManager hi_res_timer_manager;

  platform.PlatformInitialize();

  bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
  platform.InitSandboxTests(no_sandbox);

  // Initialize histogram statistics gathering system.
  // Don't create StatisticsRecorder in the single process mode.
  scoped_ptr<base::StatisticsRecorder> statistics;
  if (!base::StatisticsRecorder::IsActive()) {
    statistics.reset(new base::StatisticsRecorder());
  }

  // Initialize statistical testing infrastructure.
  base::FieldTrialList field_trial;
  // Ensure any field trials in browser are reflected into renderer.
  if (parsed_command_line.HasSwitch(switches::kForceFieldTestNameAndValue)) {
    std::string persistent = parsed_command_line.GetSwitchValueASCII(
        switches::kForceFieldTestNameAndValue);
    bool ret = field_trial.CreateTrialsInChildProcess(persistent);
    DCHECK(ret);
  }

  // Load pepper plugins before engaging the sandbox.
  PepperPluginRegistry::GetInstance();

  {
#if !defined(OS_LINUX)
    // TODO(markus): Check if it is OK to unconditionally move this
    // instruction down.
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif
    bool run_loop = true;
    if (!no_sandbox) {
      run_loop = platform.EnableSandbox();
    } else {
      LOG(ERROR) << "Running without renderer sandbox";
    }
#if defined(OS_LINUX)
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif

    platform.RunSandboxTests();

    startup_timer.Stop();  // End of Startup Time Measurement.

    if (run_loop) {
      if (pool)
        pool->Recycle();
      TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0);
      MessageLoop::current()->Run();
      TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0);
    }
  }
  platform.PlatformUninitialize();
  TRACE_EVENT_END("RendererMain", 0, "");
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/test/nacl/nacl_ui_test.h"

// TODO(jvoung) see what includes we really need.
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
#include "chrome/common/chrome_paths.h"

namespace {
// NOTE: The base URL of each HTML file is specified in nacl_test.
const FilePath::CharType kPPAPIHwHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_hw_ppapi.html");
const FilePath::CharType kSrpcBasicHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_basic.html");
const FilePath::CharType kSrpcSockAddrHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_sockaddr.html");
const FilePath::CharType kSrpcShmHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_shm.html");
const FilePath::CharType kSrpcPluginHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_plugin.html");
const FilePath::CharType kSrpcNrdXferHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_nrd_xfer.html");
const FilePath::CharType kServerHtmlFileName[] =
  FILE_PATH_LITERAL("server_test.html");
const FilePath::CharType kNpapiHwHtmlFileName[] =
  FILE_PATH_LITERAL("npapi_hw.html");
}  // namespace

NaClUITest::NaClUITest() {
}

NaClUITest::~NaClUITest() {
}

TEST_F(NaClUITest, ServerTest) {
  FilePath test_file(kServerHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, PPAPIHelloWorld) {
  FilePath test_file(kPPAPIHwHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

// http://crbug.com/64973
TEST_F(NaClUITest, DISABLED_SrpcBasicTest) {
  FilePath test_file(kSrpcBasicHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcSockAddrTest) {
  FilePath test_file(kSrpcSockAddrHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcShmTest) {
  FilePath test_file(kSrpcShmHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcPluginTest) {
  FilePath test_file(kSrpcPluginHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcNrdXferTest) {
  FilePath test_file(kSrpcNrdXferHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_NpapiHwTest) {
  FilePath test_file(kNpapiHwHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

// TEST_F(NaClUITest, DISABLED_MultiarchTest) {
//   FilePath test_file(kSrpcHwHtmlFileName);
//   RunMultiarchTest(test_file, TestTimeouts::action_max_timeout_ms());
// }

<commit_msg>Disabling PPAPI hello world test in nacl_ui_tests. This mis-named test uses a now deprecated interface. It's making the nacl-chrome integration builder red.<commit_after>// Copyright (c) 2011 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 "chrome/test/nacl/nacl_ui_test.h"

// TODO(jvoung) see what includes we really need.
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/test/test_timeouts.h"
#include "chrome/common/chrome_paths.h"

namespace {
// NOTE: The base URL of each HTML file is specified in nacl_test.
const FilePath::CharType kPPAPIHwHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_hw_ppapi.html");
const FilePath::CharType kSrpcBasicHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_basic.html");
const FilePath::CharType kSrpcSockAddrHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_sockaddr.html");
const FilePath::CharType kSrpcShmHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_shm.html");
const FilePath::CharType kSrpcPluginHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_plugin.html");
const FilePath::CharType kSrpcNrdXferHtmlFileName[] =
  FILE_PATH_LITERAL("srpc_nrd_xfer.html");
const FilePath::CharType kServerHtmlFileName[] =
  FILE_PATH_LITERAL("server_test.html");
const FilePath::CharType kNpapiHwHtmlFileName[] =
  FILE_PATH_LITERAL("npapi_hw.html");
}  // namespace

NaClUITest::NaClUITest() {
}

NaClUITest::~NaClUITest() {
}

TEST_F(NaClUITest, ServerTest) {
  FilePath test_file(kServerHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

// Uses obsolete srpc interface.
TEST_F(NaClUITest, DISABLED_PPAPIHelloWorld) {
  FilePath test_file(kPPAPIHwHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

// http://crbug.com/64973
TEST_F(NaClUITest, DISABLED_SrpcBasicTest) {
  FilePath test_file(kSrpcBasicHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcSockAddrTest) {
  FilePath test_file(kSrpcSockAddrHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcShmTest) {
  FilePath test_file(kSrpcShmHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcPluginTest) {
  FilePath test_file(kSrpcPluginHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_SrpcNrdXferTest) {
  FilePath test_file(kSrpcNrdXferHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

TEST_F(NaClUITest, DISABLED_NpapiHwTest) {
  FilePath test_file(kNpapiHwHtmlFileName);
  RunTest(test_file, TestTimeouts::action_max_timeout_ms());
}

// TEST_F(NaClUITest, DISABLED_MultiarchTest) {
//   FilePath test_file(kSrpcHwHtmlFileName);
//   RunMultiarchTest(test_file, TestTimeouts::action_max_timeout_ms());
// }

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: MasterPagesPanel.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-18 17:01:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX
#define SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX

#include "taskpane/ScrollPanel.hxx"

namespace sd {
class ViewShellBase;
}

namespace sd { namespace toolpanel {
class ControlFactory;
class TreeNode;
} }

namespace sd { namespace toolpanel { namespace controls {

/** The master pages panel combines three master page related panels into
    one.  This has the benefit that creation of the task pane becomes a
    little bit simpler and that common scroll bars can be displayed.
*/
class MasterPagesPanel
    : public ScrollPanel
{
public:
    MasterPagesPanel (
        TreeNode* pParent,
        ViewShellBase& rBase);
    virtual ~MasterPagesPanel (void);

    static std::auto_ptr<ControlFactory> CreateControlFactory (ViewShellBase& rBase);
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.158); FILE MERGED 2005/09/05 13:24:58 rt 1.4.158.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MasterPagesPanel.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 06:40:54 $
 *
 *  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
 *
 ************************************************************************/

#ifndef SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX
#define SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX

#include "taskpane/ScrollPanel.hxx"

namespace sd {
class ViewShellBase;
}

namespace sd { namespace toolpanel {
class ControlFactory;
class TreeNode;
} }

namespace sd { namespace toolpanel { namespace controls {

/** The master pages panel combines three master page related panels into
    one.  This has the benefit that creation of the task pane becomes a
    little bit simpler and that common scroll bars can be displayed.
*/
class MasterPagesPanel
    : public ScrollPanel
{
public:
    MasterPagesPanel (
        TreeNode* pParent,
        ViewShellBase& rBase);
    virtual ~MasterPagesPanel (void);

    static std::auto_ptr<ControlFactory> CreateControlFactory (ViewShellBase& rBase);
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "BaseSettingItem.h"
#include "ISettingsCollection.h"
#include "DynamicSettingsDatabase.h"

#include <memory>
#include <atlbase.h>
#include <CoreWindow.h>
#include <windows.foundation.h>

#include <iostream>
#include <sstream>
#include <utility>
#include <string>

#pragma comment (lib, "WindowsApp.lib")

using namespace ATL;

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI::Core;

using std::wstring;
using std::istringstream;
using std::pair;

BaseSettingItem::BaseSettingItem() {}

BaseSettingItem::BaseSettingItem(wstring settingId, ATL::CComPtr<ISettingItem> BaseSettingItem) {
    this->settingId = settingId;
    this->setting = BaseSettingItem;
}

BaseSettingItem::BaseSettingItem(const BaseSettingItem & other) {
    this->setting = other.setting;
    this->settingId = other.settingId;
}

BaseSettingItem& BaseSettingItem::operator=(const BaseSettingItem& other) {
    this->setting = other.setting;
    this->settingId = other.settingId;

    return *this;
}

UINT BaseSettingItem::GetId(std::wstring & id) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HSTRING hId = NULL;
    HRESULT res = this->setting->get_Id(&hId);

    if (res == ERROR_SUCCESS && hId != NULL) {
        UINT hIdLenght = 0;
        PCWSTR rawStrBuf = WindowsGetStringRawBuffer(hId, &hIdLenght);

        if (rawStrBuf != NULL) {
            id = std::wstring(rawStrBuf);
        }
    }

    // Release resources
    WindowsDeleteString(hId);

    return res;
}

UINT BaseSettingItem::GetSettingType(SettingType * val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_SettingType(val);
}

UINT BaseSettingItem::GetIsSetByGroupPolicy(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsSetByGroupPolicy(val);
}

UINT BaseSettingItem::GetIsEnabled(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsEnabled(val);
}

UINT BaseSettingItem::GetIsApplicable(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsApplicable(val);
}

UINT BaseSettingItem::GetDescription(std::wstring& desc) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HSTRING hDesc = NULL;
    HRESULT res = this->setting->get_Description(&hDesc);

    if (res == ERROR_SUCCESS && hDesc != NULL) {
        UINT hIdLenght = 0;
        PCWSTR rawStrBuf = WindowsGetStringRawBuffer(hDesc, &hIdLenght);

        if (rawStrBuf != NULL) {
            desc = std::wstring(rawStrBuf);
        }
    }

    // Release resources
    WindowsDeleteString(hDesc);

    return res;
}

UINT BaseSettingItem::GetIsUpdating(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsUpdating(val);
}

UINT BaseSettingItem::GetValue(wstring id, ATL::CComPtr<IInspectable>& item) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };
    if (id.empty()) { return E_INVALIDARG; };

    HRESULT res = ERROR_SUCCESS;
    BOOL isUpdating = false;

    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    IInspectable* curValue = NULL;
    if (res == ERROR_SUCCESS) {
        // Access the simple value from the setting
        res = this->setting->GetValue(hId, &curValue);

        if (res == ERROR_SUCCESS) {
            res = this->setting->get_IsUpdating(&isUpdating);

            if (res == ERROR_SUCCESS) {
                UINT it = 0;
                UINT wait = timeout / retries;

                while (isUpdating == TRUE && res == ERROR_SUCCESS) {
                    System::Threading::Thread::Sleep(10);
                    res = this->setting->get_IsUpdating(&isUpdating);

                    if (res != ERROR_SUCCESS) {
                        break;
                    }
                }

                HSTRING otherStr = NULL;
                res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &otherStr);

                curValue->Release();

                // TODO: This second get is necessary for some settings, like
                // "Collection" settings. For this ones the second get guarantees
                // that the real value is the one received.
                res = this->setting->GetValue(otherStr, &curValue);
                if (res == ERROR_SUCCESS) {
                    item.Attach(curValue);
                } else {
                    curValue->Release();
                }
            }
        }
    }

    return res;
}

HRESULT BaseSettingItem::SetValue(const wstring& id, ATL::CComPtr<IPropertyValue>& item) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res { ERROR_SUCCESS };
    HSTRING hId { NULL };
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->SetValue(hId, static_cast<IInspectable*>(item));
    }

    WindowsDeleteString(hId);

    return res;
}

UINT BaseSettingItem::GetProperty(wstring id, IInspectable** value) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res = ERROR_SUCCESS;
    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->GetProperty(hId, value);
    }

    return res;
}

UINT BaseSettingItem::SetProperty(wstring id, IInspectable* value) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res = ERROR_SUCCESS;
    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->SetProperty(hId, value);
    }

    return res;
}

UINT BaseSettingItem::Invoke() {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    IPropertyValueStatics* propValueFactory;
    HSTRING rTimeClass;
    WindowsCreateString(
        RuntimeClass_Windows_Foundation_PropertyValue,
        static_cast<UINT32>(wcslen(RuntimeClass_Windows_Foundation_PropertyValue)),
        &rTimeClass
    );
    HRESULT result = GetActivationFactory(rTimeClass, &propValueFactory);

    IInspectable* rec;
    Rect baseRect { 0,0,0,0 };
    propValueFactory->CreateRect(baseRect, &rec);

    ICoreWindow* core = NULL;
    ICoreWindowStatic* spCoreWindowStatic;
    ICoreWindow* spCoreWindow;

    HSTRING strIWindowClassId;
    WindowsCreateString(
        RuntimeClass_Windows_UI_Core_CoreWindow,
        static_cast<UINT32>(wcslen(RuntimeClass_Windows_UI_Core_CoreWindow)),
        &strIWindowClassId
    );
    HRESULT hr;

    //Get the activation factory
    hr = (Windows::Foundation::GetActivationFactory(strIWindowClassId, &spCoreWindowStatic));
    if (FAILED(hr)) return true;

    //Get the current thread's object
    hr = spCoreWindowStatic->GetForCurrentThread(&spCoreWindow);
    if (FAILED(hr)) return true;

    hr = this->setting->Invoke(spCoreWindow, rec);

    return hr;
}
<commit_msg>GPII-4152: Removed redundant checks<commit_after>#include "stdafx.h"
#include "BaseSettingItem.h"
#include "ISettingsCollection.h"
#include "DynamicSettingsDatabase.h"

#include <memory>
#include <atlbase.h>
#include <CoreWindow.h>
#include <windows.foundation.h>

#include <iostream>
#include <sstream>
#include <utility>
#include <string>

#pragma comment (lib, "WindowsApp.lib")

using namespace ATL;

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI::Core;

using std::wstring;
using std::istringstream;
using std::pair;

BaseSettingItem::BaseSettingItem() {}

BaseSettingItem::BaseSettingItem(wstring settingId, ATL::CComPtr<ISettingItem> BaseSettingItem) {
    this->settingId = settingId;
    this->setting = BaseSettingItem;
}

BaseSettingItem::BaseSettingItem(const BaseSettingItem & other) {
    this->setting = other.setting;
    this->settingId = other.settingId;
}

BaseSettingItem& BaseSettingItem::operator=(const BaseSettingItem& other) {
    this->setting = other.setting;
    this->settingId = other.settingId;

    return *this;
}

UINT BaseSettingItem::GetId(std::wstring & id) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HSTRING hId = NULL;
    HRESULT res = this->setting->get_Id(&hId);

    if (res == ERROR_SUCCESS && hId != NULL) {
        UINT hIdLenght = 0;
        PCWSTR rawStrBuf = WindowsGetStringRawBuffer(hId, &hIdLenght);

        if (rawStrBuf != NULL) {
            id = std::wstring(rawStrBuf);
        }
    }

    // Release resources
    WindowsDeleteString(hId);

    return res;
}

UINT BaseSettingItem::GetSettingType(SettingType * val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_SettingType(val);
}

UINT BaseSettingItem::GetIsSetByGroupPolicy(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsSetByGroupPolicy(val);
}

UINT BaseSettingItem::GetIsEnabled(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsEnabled(val);
}

UINT BaseSettingItem::GetIsApplicable(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsApplicable(val);
}

UINT BaseSettingItem::GetDescription(std::wstring& desc) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HSTRING hDesc = NULL;
    HRESULT res = this->setting->get_Description(&hDesc);

    if (res == ERROR_SUCCESS && hDesc != NULL) {
        UINT hIdLenght = 0;
        PCWSTR rawStrBuf = WindowsGetStringRawBuffer(hDesc, &hIdLenght);

        if (rawStrBuf != NULL) {
            desc = std::wstring(rawStrBuf);
        }
    }

    // Release resources
    WindowsDeleteString(hDesc);

    return res;
}

UINT BaseSettingItem::GetIsUpdating(BOOL* val) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    return this->setting->get_IsUpdating(val);
}

UINT BaseSettingItem::GetValue(wstring id, ATL::CComPtr<IInspectable>& item) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };
    if (id.empty()) { return E_INVALIDARG; };

    HRESULT res = ERROR_SUCCESS;
    BOOL isUpdating = false;

    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    IInspectable* curValue = NULL;
    if (res == ERROR_SUCCESS) {
        // Access the simple value from the setting
        res = this->setting->GetValue(hId, &curValue);

        if (res == ERROR_SUCCESS) {
            res = this->setting->get_IsUpdating(&isUpdating);

            while (isUpdating == TRUE && res == ERROR_SUCCESS) {
                System::Threading::Thread::Sleep(10);
                res = this->setting->get_IsUpdating(&isUpdating);

                if (res != ERROR_SUCCESS) {
                    break;
                }
            }

            HSTRING otherStr = NULL;
            res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &otherStr);

            curValue->Release();

            // TODO: This second get is necessary for some settings, like
            // "Collection" settings. For this ones the second get guarantees
            // that the real value is the one received.
            res = this->setting->GetValue(otherStr, &curValue);
            if (res == ERROR_SUCCESS) {
                item.Attach(curValue);
            } else {
                curValue->Release();
            }
        }
    }

    return res;
}

HRESULT BaseSettingItem::SetValue(const wstring& id, ATL::CComPtr<IPropertyValue>& item) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res { ERROR_SUCCESS };
    HSTRING hId { NULL };
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->SetValue(hId, static_cast<IInspectable*>(item));
    }

    WindowsDeleteString(hId);

    return res;
}

UINT BaseSettingItem::GetProperty(wstring id, IInspectable** value) const {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res = ERROR_SUCCESS;
    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->GetProperty(hId, value);
    }

    return res;
}

UINT BaseSettingItem::SetProperty(wstring id, IInspectable* value) {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    HRESULT res = ERROR_SUCCESS;
    HSTRING hId = NULL;
    res = WindowsCreateString(id.c_str(), static_cast<UINT32>(id.size()), &hId);

    if (res == ERROR_SUCCESS) {
        res = this->setting->SetProperty(hId, value);
    }

    return res;
}

UINT BaseSettingItem::Invoke() {
    if (this->setting == NULL) { return ERROR_INVALID_HANDLE_STATE; };

    IPropertyValueStatics* propValueFactory;
    HSTRING rTimeClass;
    WindowsCreateString(
        RuntimeClass_Windows_Foundation_PropertyValue,
        static_cast<UINT32>(wcslen(RuntimeClass_Windows_Foundation_PropertyValue)),
        &rTimeClass
    );
    HRESULT result = GetActivationFactory(rTimeClass, &propValueFactory);

    IInspectable* rec;
    Rect baseRect { 0,0,0,0 };
    propValueFactory->CreateRect(baseRect, &rec);

    ICoreWindow* core = NULL;
    ICoreWindowStatic* spCoreWindowStatic;
    ICoreWindow* spCoreWindow;

    HSTRING strIWindowClassId;
    WindowsCreateString(
        RuntimeClass_Windows_UI_Core_CoreWindow,
        static_cast<UINT32>(wcslen(RuntimeClass_Windows_UI_Core_CoreWindow)),
        &strIWindowClassId
    );
    HRESULT hr;

    //Get the activation factory
    hr = (Windows::Foundation::GetActivationFactory(strIWindowClassId, &spCoreWindowStatic));
    if (FAILED(hr)) return true;

    //Get the current thread's object
    hr = spCoreWindowStatic->GetForCurrentThread(&spCoreWindow);
    if (FAILED(hr)) return true;

    hr = this->setting->Invoke(spCoreWindow, rec);

    return hr;
}
<|endoftext|>


<commit_before>//g++ *.cpp -lpthread -lwiringPi -std=c++11
//LATER MET GUI MAKEFILE <sudo make>

#include "I22cCom.h"
// Sensors -------------------
#include "Sensor.h"
#include "Log.h"
#include "Camera.h"
#include "Light.h"
#include "MotionSensor.h"
#include "PressureSensor.h"
// GUI ----------
#include "dialog.h"
#include <QApplication>
#include "tempertuur.h"
// ----------
//#define I2CLOC "/dev/i2c-1"// <-- this is the real I2C device you need with the scale model
#define I2CLOC "/dev/simudrv"
#define LOG "Slaaplog.txt"

#include <vector>
#include <iostream>
#include <wiringPi.h>  //compile with -lwiringPi

using namespace std;

vector<Sensor*> motionSensors;    //Vector of the sensors
vector<Light*> lights;      //Vector of the lights
vector<int> active;
PressureSensor* pressureSensor;
Camera* cam;                //Pointer to the camera
Log* log;

int pressureValue;
bool asleep = false;
bool day = true;
bool anomaly = false;
int temperature = 20;

void checkAnomaly();
void updateSensors();
void checkCam();
void sendAlert();
void init();

int main() {
  init();
  while(1) {
        updateSensors();
        checkAnomaly();
        checkCam();
  }
}

/*Init for the main*/
void init() {
    QApplication a(argc, argv);
	Dialog w;
	w.show();
    wiringPiSetupGpio();
    I2CCom i2c(I2CLOC);     //the i2c to communicate with sensor
    Light x(22);
    MotionSensor s1(0xFC,i2c);
    MotionSensor s2(0xBC,i2c);
    MotionSensor s3(0xEC,i2c);
    PressureSensor s4(0x06, i2c);
    Log l1(LOG);
    Camera c1;
    cam = &c1;
    log = &l1;
    pressureSensor = &s4;
    motionSensors.push_back(&s1);
    motionSensors.push_back(&s2);
    motionSensors.push_back(&s3);
    lights.push_back(&x);

    active.resize(motionSensors.size());
}
/*Updates sensors*/
void updateSensors() {
    //update van elke sensor de value en de active
    bool alert = true;
    for(int i = 0; i<motionSensors.size();i++) {
        if(motionSensors[i]->check()) {
            //active[i]=1;
            alert = false;
		cout <<"halleyula" <<endl;
        } else{
            //active[i]=0;
        }
    }
    if (s4->check()) {
        asleep = true;
    }
    if(alert & !asleep) {
        sendAlert();
    }
    pressureValue = s4->getValue();
}

/*Send Alarm*/
void sendAlert(){
    cout<<"Alert"<<endl;
}

/*Sets the camera*/
void checkCam(){
    if(day) {
        cam->setCamera(true);
    } else if(anomaly) {
        cam->setCamera(true);
    } else {
        cam->setCamera(false);
    }
}

void checkAnomaly(){

    if(pressureValue > 20 && pressureValue < 150) {
        anomaly = true;
    }
    if(pressureValue > 150 && pressureValue < 200) { // Changing positions while asleep
        //Do nothing, maybe verify if person really is sleeping
    }
    if(pressureValue > 200) {
        asleep = true;
    }

}

<commit_msg>spellcheck<commit_after>//g++ *.cpp -lpthread -lwiringPi -std=c++11
//LATER MET GUI MAKEFILE <sudo make>

#include "I22cCom.h"
// Sensors -------------------
#include "Sensor.h"
#include "Log.h"
#include "Camera.h"
#include "Light.h"
#include "MotionSensor.h"
#include "PressureSensor.h"
// GUI ----------
#include "dialog.h"
#include <QApplication>
#include "temperatuur.h"
// ----------
//#define I2CLOC "/dev/i2c-1"// <-- this is the real I2C device you need with the scale model
#define I2CLOC "/dev/simudrv"
#define LOG "Slaaplog.txt"

#include <vector>
#include <iostream>
#include <wiringPi.h>  //compile with -lwiringPi

using namespace std;

vector<Sensor*> motionSensors;    //Vector of the sensors
vector<Light*> lights;      //Vector of the lights
vector<int> active;
PressureSensor* pressureSensor;
Camera* cam;                //Pointer to the camera
Log* log;

int pressureValue;
bool asleep = false;
bool day = true;
bool anomaly = false;
int temperature = 20;

void checkAnomaly();
void updateSensors();
void checkCam();
void sendAlert();
void init();

int main() {
  init();
  while(1) {
        updateSensors();
        checkAnomaly();
        checkCam();
  }
}

/*Init for the main*/
void init() {
    QApplication a(argc, argv);
	Dialog w;
	w.show();
    wiringPiSetupGpio();
    I2CCom i2c(I2CLOC);     //the i2c to communicate with sensor
    Light x(22);
    MotionSensor s1(0xFC,i2c);
    MotionSensor s2(0xBC,i2c);
    MotionSensor s3(0xEC,i2c);
    PressureSensor s4(0x06, i2c);
    Log l1(LOG);
    Camera c1;
    cam = &c1;
    log = &l1;
    pressureSensor = &s4;
    motionSensors.push_back(&s1);
    motionSensors.push_back(&s2);
    motionSensors.push_back(&s3);
    lights.push_back(&x);

    active.resize(motionSensors.size());
}
/*Updates sensors*/
void updateSensors() {
    //update van elke sensor de value en de active
    bool alert = true;
    for(int i = 0; i<motionSensors.size();i++) {
        if(motionSensors[i]->check()) {
            //active[i]=1;
            alert = false;
		cout <<"halleyula" <<endl;
        } else{
            //active[i]=0;
        }
    }
    if (s4->check()) {
        asleep = true;
    }
    if(alert & !asleep) {
        sendAlert();
    }
    pressureValue = s4->getValue();
}

/*Send Alarm*/
void sendAlert(){
    cout<<"Alert"<<endl;
}

/*Sets the camera*/
void checkCam(){
    if(day) {
        cam->setCamera(true);
    } else if(anomaly) {
        cam->setCamera(true);
    } else {
        cam->setCamera(false);
    }
}

void checkAnomaly(){

    if(pressureValue > 20 && pressureValue < 150) {
        anomaly = true;
    }
    if(pressureValue > 150 && pressureValue < 200) { // Changing positions while asleep
        //Do nothing, maybe verify if person really is sleeping
    }
    if(pressureValue > 200) {
        asleep = true;
    }

}

<|endoftext|>


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

///
///    @file    InterfaceWithTetGen.cc
///    @author  Martin Cole
///    @date    Wed Mar 22 07:56:22 2006
///

#include <Modules/Legacy/Fields/InterfaceWithTetGenImpl.h>

#include <Core/Thread/Mutex.h>
#include <Core/Logging/LoggerInterface.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Dataflow/Network/Module.h>

#define TETLIBRARY   // Required definition for use of tetgen library
#include <tetgen.h>

#include <sstream>

#include <sci_debug.h>

using namespace SCIRun;
using namespace Dataflow::Networks;
using namespace Modules::Fields;
using namespace Core::Thread;
using namespace Core::Geometry;

namespace SCIRun {
namespace Modules {
namespace Fields {
namespace detail {

/// @class InterfaceWithTetGen
/// @brief This module interfaces with TetGen.

class InterfaceWithTetGenImplImpl //: public AlgorithmBase
{
  public:
    explicit InterfaceWithTetGenImplImpl(Module* mod);

    FieldHandle runImpl(const std::deque<FieldHandle>& surfaces,
      FieldHandle points, FieldHandle region_attribs, const InterfaceWithTetGenInput& input) const;

  private:
    // translate the ui variables into the string with options
    // that TetGen uses
    Module* module_;
    static Mutex TetGenMutex;
};

Mutex InterfaceWithTetGenImplImpl::TetGenMutex("Protect TetGen from running in parallel");
}}}}

detail::InterfaceWithTetGenImplImpl::InterfaceWithTetGenImplImpl(Module* module) : module_(module)
{}

std::string InterfaceWithTetGenInput::fillCommandOptions(bool addPoints) const
{
  // Collect the options in this output string stream
  std::ostringstream oss;
  if (addPoints)
  {
    oss << "i";
  }

  if (piecewiseFlag_)
  {
    oss << "p";
  }

  if (suppressSplitFlag_)
  {
    if (setSplitFlag_)
    {
      oss << "YY";
    }
    else
    {
      oss << "Y";
    }
  }

  // Always use zero indexing that is the only thing SCIRun knows....
  oss << "z";

  if (qualityFlag_)
  {
    oss << "q";
    if (setRatioFlag_)
    {
      oss << minRadius_;
    }
  }
  if (volConstraintFlag_)
  {
    oss << "a";
    if (setMaxVolConstraintFlag_)
    {
      oss << maxVolConstraint_;
    }
  }
  if (detectIntersectionsFlag_)
  {
    oss << "d";
  }
  if (assignFlag_)
  {
    if (setNonzeroAttributeFlag_)
    {
      oss << "AA";
    }
    else
    {
      oss << "A";
    }
  }

  // Add in whatever the user wants to add additionally.
  oss << moreSwitches_;
  return oss.str();
}

FieldHandle detail::InterfaceWithTetGenImplImpl::runImpl(const std::deque<FieldHandle>& surfaces,
  FieldHandle points, FieldHandle region_attribs, const InterfaceWithTetGenInput& input) const
{
#if 0
  if (inputs_changed_ || piecewiseFlag_.changed() ||
      assignFlag_.changed() || setNonzeroAttributeFlag_.changed() ||
      suppressSplitFlag_.changed() || setSplitFlag_.changed() ||
      qualityFlag_.changed() || setRatioFlag_.changed() ||
      volConstraintFlag_.changed() || setMaxVolConstraintFlag_.changed() ||
      minRadius_.changed() || maxVolConstraint_.changed() ||
      detectIntersectionsFlag_.changed() || moreSwitches_.changed() ||
      !oport_cached("TetVol"))
  #endif
  //{
    // Tell SCIRun we are actually doing some work
//    update_state(Executing);

  //TODO DAN: check for proper memory management with these classes.
    tetgenio in, addin, out;

    bool add_points = false;
    if (points)
    {
      VMesh* mesh = points->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();

      addin.numberofpoints = num_nodes;
      addin.pointlist = new REAL[num_nodes*3];
      for(VMesh::Node::index_type idx=0; idx<num_nodes; ++idx)
      {
        Point p;
        mesh->get_center(p, idx);
        addin.pointlist[idx * 3] = p.x();
        addin.pointlist[idx * 3 + 1] = p.y();
        addin.pointlist[idx * 3 + 2] = p.z();
      }
      add_points = true;
      module_->remark("Added extra interior points from Points port.");
    }

    if (region_attribs)
    {
      VMesh* mesh = region_attribs->vmesh();
      VField* field = region_attribs->vfield();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();

      in.regionlist = new REAL[num_nodes*5];
      in.numberofregions = num_nodes;
      for(VMesh::Node::index_type idx=0; idx<num_nodes; ++idx)
      {
        Point p; double val;
        mesh->get_center(p, idx);
        in.regionlist[idx * 5] = p.x();
        in.regionlist[idx * 5 + 1] = p.y();
        in.regionlist[idx * 5 + 2] = p.z();
        in.regionlist[idx * 5 + 3] = idx;
        field->get_value(val, idx);
        in.regionlist[idx * 5 + 4] = val;
      }
    }

    // indices start from 0.
    in.firstnumber = 0;
    in.mesh_dim = 3;

    int marker = -10;

    VMesh::size_type tot_num_nodes = 0;
    VMesh::size_type tot_num_elems = 0;

    for (size_t j=0; j< surfaces.size(); j++)
    {
      VMesh*  mesh = surfaces[j]->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();
      VMesh::Elem::size_type num_elems = mesh->num_elems();

      tot_num_nodes += num_nodes;
      tot_num_elems += num_elems;
    }

    in.pointlist = new REAL[(tot_num_nodes) * 3];
    in.numberofpoints = tot_num_nodes;

    in.facetlist = new tetgenio::facet[tot_num_elems];
    in.facetmarkerlist = new int[tot_num_elems];
    in.numberoffacets = tot_num_elems;

    VMesh::index_type idx = 0;
    VMesh::index_type fidx = 0;
    VMesh::index_type off;

    for (size_t j=0; j< surfaces.size(); j++)
    {
      VMesh*  mesh = surfaces[j]->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();
      VMesh::Elem::size_type num_elems = mesh->num_elems();

      off = idx;
      for(VMesh::Node::index_type nidx=0; nidx<num_nodes; ++nidx)
      {
        Point p;
        mesh->get_center(p, nidx);
        in.pointlist[idx * 3] = p.x();
        in.pointlist[idx * 3 + 1] = p.y();
        in.pointlist[idx * 3 + 2] = p.z();
        ++idx;
      }

      unsigned int vert_per_face = mesh->num_nodes_per_elem();

      // iterate over faces.
      VMesh::Node::array_type nodes;

      for(VMesh::Elem::index_type eidx=0; eidx<num_elems; ++eidx)
      {
        tetgenio::facet *f = &in.facetlist[fidx];
        f->numberofpolygons = 1;
        f->polygonlist = new tetgenio::polygon[1];
        f->numberofholes = 0;
        f->holelist = nullptr;
        tetgenio::polygon *p = &f->polygonlist[0];
        p->numberofvertices = vert_per_face;
        p->vertexlist = new int[p->numberofvertices];

        mesh->get_nodes(nodes, eidx);
        for (size_t i=0; i<nodes.size(); i++)
        {
          p->vertexlist[i] = VMesh::index_type(nodes[i]) + off;
        }

        in.facetmarkerlist[fidx] = marker;
        ++fidx;
      }

      marker *= 2;
    }

    module_->getUpdaterFunc()(.2);
    // Save files for later debugging.
    // std::string filename = std::string(sci_getenv("SCIRUN_TMP_DIR")) + "/tgIN";
    // in.save_nodes((char*)filename.c_str());
    // in.save_poly((char*)filename.c_str());

    std::string cmmd_ln = input.fillCommandOptions(add_points);
  #if DEBUG
    std::cerr << "\nTetgen command line: " << cmmd_ln << std::endl;
  #endif
    tetgenio *addtgio = nullptr;
    if (add_points)
    {
       addtgio = &addin;
    }
    // Create the new mesh.

    // Make sure only one thread accesses TetGen
    // It is not thread safe :)
    {
      Guard g(TetGenMutex.get());
      try
      {
        tetrahedralize(const_cast<char*>(cmmd_ln.c_str()), &in, &out, addtgio);
      }
      catch(std::exception& e)
      {
        module_->error(std::string("TetGen failed to generate a mesh: ") + e.what());
        return nullptr;
      }
      catch (...)
      {
        module_->error("TetGen failed to generate a mesh");
        return nullptr;
      }
    }

    module_->getUpdaterFunc()(.9);
    FieldInformation fi(TETVOLMESH_E,CONSTANTDATA_E,DOUBLE_E);
    FieldHandle tetvol_out = CreateField(fi);
    // Convert to a SCIRun TetVol.

    VMesh* mesh = tetvol_out->vmesh();
    VField* field = tetvol_out->vfield();
    for (int i = 0; i < out.numberofpoints; i++)
    {
      Point p(out.pointlist[i*3], out.pointlist[i*3+1], out.pointlist[i*3+2]);
      mesh->add_point(p);
    }

    VMesh::Node::size_type numnodes = mesh->num_nodes();
    VMesh::Node::array_type nodes(4);
    for (int i = 0; i < out.numberoftetrahedra; i++)
    {
      nodes[0] = out.tetrahedronlist[i*4];
      nodes[1] = out.tetrahedronlist[i*4+1];
      nodes[2] = out.tetrahedronlist[i*4+2];
      nodes[3] = out.tetrahedronlist[i*4+3];

      if (nodes[0] >= numnodes ||nodes[1] >= numnodes ||
          nodes[2] >= numnodes ||nodes[3] >= numnodes )
      {
        module_->error("TetGen failed to produce a valid tetrahedralization");
        return nullptr;
      }
      mesh->add_elem(nodes);
    }

    field->resize_values();

    int atts =  out.numberoftetrahedronattributes;

    for (int i = 0; i < out.numberoftetrahedra; i++)
    {
      for (int j = 0; j < atts; j++)
      {
        double val = out.tetrahedronattributelist[i * atts + j];
        field->set_value(val, VMesh::Elem::index_type(i));
      }
    }

    module_->getUpdaterFunc()(1.0);
    return tetvol_out;
}

InterfaceWithTetGenInput::InterfaceWithTetGenInput() :
piecewiseFlag_(true),
assignFlag_(true),
setNonzeroAttributeFlag_(false),
suppressSplitFlag_(true),
setSplitFlag_(false),
qualityFlag_(true),
setRatioFlag_(false),
volConstraintFlag_(false),
setMaxVolConstraintFlag_(false),
// see TetGen documentation for "-q" switch: default is 2.0
minRadius_(2.0),
maxVolConstraint_(0.1),
detectIntersectionsFlag_(false),
moreSwitches_("")
{
}

InterfaceWithTetGenImpl::InterfaceWithTetGenImpl(Module* module, const InterfaceWithTetGenInput& input) :
  impl_(new detail::InterfaceWithTetGenImplImpl(module)),
  inputFlags_(input)
{}

FieldHandle InterfaceWithTetGenImpl::runImpl(const std::deque<FieldHandle>& surfaces, FieldHandle points, FieldHandle region_attribs) const
{
  return impl_->runImpl(surfaces, points, region_attribs, inputFlags_);
}
<commit_msg>Fix for tetgen crash<commit_after>//
//  For more information, please see: http://software.sci.utah.edu
//
//  The MIT License
//
//  Copyright (c) 2015 Scientific Computing and Imaging Institute,
//  University of Utah.
//
//
//  Permission is hereby granted, free of charge, to any person obtaining a
//  copy of this software and associated documentation files (the "Software"),
//  to deal in the Software without restriction, including without limitation
//  the rights to use, copy, modify, merge, publish, distribute, sublicense,
//  and/or sell copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included
//  in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
//  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.
//

///
///    @file    InterfaceWithTetGen.cc
///    @author  Martin Cole
///    @date    Wed Mar 22 07:56:22 2006
///

#include <Modules/Legacy/Fields/InterfaceWithTetGenImpl.h>

#include <Core/Thread/Mutex.h>
#include <Core/Logging/LoggerInterface.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/VMesh.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Dataflow/Network/Module.h>

#define TETLIBRARY   // Required definition for use of tetgen library
#include <tetgen.h>

#include <sstream>

#include <sci_debug.h>

using namespace SCIRun;
using namespace Dataflow::Networks;
using namespace Modules::Fields;
using namespace Core::Thread;
using namespace Core::Geometry;

namespace SCIRun {
namespace Modules {
namespace Fields {
namespace detail {

/// @class InterfaceWithTetGen
/// @brief This module interfaces with TetGen.

class InterfaceWithTetGenImplImpl //: public AlgorithmBase
{
  public:
    explicit InterfaceWithTetGenImplImpl(Module* mod);

    FieldHandle runImpl(const std::deque<FieldHandle>& surfaces,
      FieldHandle points, FieldHandle region_attribs, const InterfaceWithTetGenInput& input) const;

  private:
    // translate the ui variables into the string with options
    // that TetGen uses
    Module* module_;
    static Mutex TetGenMutex;
};

Mutex InterfaceWithTetGenImplImpl::TetGenMutex("Protect TetGen from running in parallel");
}}}}

detail::InterfaceWithTetGenImplImpl::InterfaceWithTetGenImplImpl(Module* module) : module_(module)
{}

std::string InterfaceWithTetGenInput::fillCommandOptions(bool addPoints) const
{
  // Collect the options in this output string stream
  std::ostringstream oss;
  if (addPoints)
  {
    oss << "i";
  }

  if (piecewiseFlag_)
  {
    oss << "p";
  }

  if (suppressSplitFlag_)
  {
    if (setSplitFlag_)
    {
      oss << "YY";
    }
    else
    {
      oss << "Y";
    }
  }

  // Always use zero indexing that is the only thing SCIRun knows....
  oss << "z";

  if (qualityFlag_)
  {
    oss << "q";
    if (setRatioFlag_)
    {
      oss << minRadius_;
    }
  }
  if (volConstraintFlag_)
  {
    oss << "a";
    if (setMaxVolConstraintFlag_)
    {
      oss << maxVolConstraint_;
    }
  }
  if (detectIntersectionsFlag_)
  {
    oss << "d";
  }
  if (assignFlag_)
  {
    if (setNonzeroAttributeFlag_)
    {
      oss << "AA";
    }
    else
    {
      oss << "A";
    }
  }

  // Add in whatever the user wants to add additionally.
  oss << moreSwitches_;
  return oss.str();
}

FieldHandle detail::InterfaceWithTetGenImplImpl::runImpl(const std::deque<FieldHandle>& surfaces,
  FieldHandle points, FieldHandle region_attribs, const InterfaceWithTetGenInput& input) const
{
#if 0
  if (inputs_changed_ || piecewiseFlag_.changed() ||
      assignFlag_.changed() || setNonzeroAttributeFlag_.changed() ||
      suppressSplitFlag_.changed() || setSplitFlag_.changed() ||
      qualityFlag_.changed() || setRatioFlag_.changed() ||
      volConstraintFlag_.changed() || setMaxVolConstraintFlag_.changed() ||
      minRadius_.changed() || maxVolConstraint_.changed() ||
      detectIntersectionsFlag_.changed() || moreSwitches_.changed() ||
      !oport_cached("TetVol"))
  #endif
  //{
    // Tell SCIRun we are actually doing some work
//    update_state(Executing);

  //TODO DAN: check for proper memory management with these classes.
    tetgenio in, addin, out;

    bool add_points = false;
    if (points)
    {
      VMesh* mesh = points->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();

      addin.numberofpoints = num_nodes;
      addin.pointlist = new REAL[num_nodes*3];
      for(VMesh::Node::index_type idx=0; idx<num_nodes; ++idx)
      {
        Point p;
        mesh->get_center(p, idx);
        addin.pointlist[idx * 3] = p.x();
        addin.pointlist[idx * 3 + 1] = p.y();
        addin.pointlist[idx * 3 + 2] = p.z();
      }
      add_points = true;
      module_->remark("Added extra interior points from Points port.");
    }

    if (region_attribs)
    {
      VMesh* mesh = region_attribs->vmesh();
      VField* field = region_attribs->vfield();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();

      in.regionlist = new REAL[num_nodes*5];
      in.numberofregions = num_nodes;
      for(VMesh::Node::index_type idx=0; idx<num_nodes; ++idx)
      {
        Point p; double val;
        mesh->get_center(p, idx);
        in.regionlist[idx * 5] = p.x();
        in.regionlist[idx * 5 + 1] = p.y();
        in.regionlist[idx * 5 + 2] = p.z();
        in.regionlist[idx * 5 + 3] = idx;
        field->get_value(val, idx);
        in.regionlist[idx * 5 + 4] = val;
      }
    }

    // indices start from 0.
    in.firstnumber = 0;
    in.mesh_dim = 3;

    int marker = -10;

    VMesh::size_type tot_num_nodes = 0;
    VMesh::size_type tot_num_elems = 0;

    for (size_t j=0; j< surfaces.size(); j++)
    {
      VMesh*  mesh = surfaces[j]->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();
      VMesh::Elem::size_type num_elems = mesh->num_elems();

      tot_num_nodes += num_nodes;
      tot_num_elems += num_elems;
    }

    in.pointlist = new REAL[(tot_num_nodes) * 3];
    in.numberofpoints = tot_num_nodes;

    in.facetlist = new tetgenio::facet[tot_num_elems];
    in.facetmarkerlist = new int[tot_num_elems];
    in.numberoffacets = tot_num_elems;

    VMesh::index_type idx = 0;
    VMesh::index_type fidx = 0;
    VMesh::index_type off;

    for (size_t j=0; j< surfaces.size(); j++)
    {
      VMesh*  mesh = surfaces[j]->vmesh();
      VMesh::Node::size_type num_nodes = mesh->num_nodes();
      VMesh::Elem::size_type num_elems = mesh->num_elems();

      off = idx;
      for(VMesh::Node::index_type nidx=0; nidx<num_nodes; ++nidx)
      {
        Point p;
        mesh->get_center(p, nidx);
        in.pointlist[idx * 3] = p.x();
        in.pointlist[idx * 3 + 1] = p.y();
        in.pointlist[idx * 3 + 2] = p.z();
        ++idx;
      }

      unsigned int vert_per_face = mesh->num_nodes_per_elem();

      // iterate over faces.
      VMesh::Node::array_type nodes;

      for(VMesh::Elem::index_type eidx=0; eidx<num_elems; ++eidx)
      {
        tetgenio::facet *f = &in.facetlist[fidx];
        f->numberofpolygons = 1;
        f->polygonlist = new tetgenio::polygon[1];
        f->numberofholes = 0;
        f->holelist = nullptr;
        tetgenio::polygon *p = &f->polygonlist[0];
        p->numberofvertices = vert_per_face;
        if (vert_per_face > 0)
        {
          p->vertexlist = new int[p->numberofvertices];
          mesh->get_nodes(nodes, eidx);
          for (size_t i = 0; i < nodes.size(); i++)
          {
            p->vertexlist[i] = VMesh::index_type(nodes[i]) + off;
          }
        }
        else
        {
          p->vertexlist = nullptr;
        }

        in.facetmarkerlist[fidx] = marker;
        ++fidx;
      }

      marker *= 2;
    }

    module_->getUpdaterFunc()(.2);
    // Save files for later debugging.
    // std::string filename = std::string(sci_getenv("SCIRUN_TMP_DIR")) + "/tgIN";
    // in.save_nodes((char*)filename.c_str());
    // in.save_poly((char*)filename.c_str());

    std::string cmmd_ln = input.fillCommandOptions(add_points);
  #if DEBUG
    std::cerr << "\nTetgen command line: " << cmmd_ln << std::endl;
  #endif
    tetgenio *addtgio = nullptr;
    if (add_points)
    {
       addtgio = &addin;
    }
    // Create the new mesh.

    // Make sure only one thread accesses TetGen
    // It is not thread safe :)
    {
      Guard g(TetGenMutex.get());
      try
      {
        tetrahedralize(const_cast<char*>(cmmd_ln.c_str()), &in, &out, addtgio);
      }
      catch(std::exception& e)
      {
        module_->error(std::string("TetGen failed to generate a mesh: ") + e.what());
        return nullptr;
      }
      catch (...)
      {
        module_->error("TetGen failed to generate a mesh");
        return nullptr;
      }
    }

    module_->getUpdaterFunc()(.9);
    FieldInformation fi(TETVOLMESH_E,CONSTANTDATA_E,DOUBLE_E);
    FieldHandle tetvol_out = CreateField(fi);
    // Convert to a SCIRun TetVol.

    VMesh* mesh = tetvol_out->vmesh();
    VField* field = tetvol_out->vfield();
    for (int i = 0; i < out.numberofpoints; i++)
    {
      Point p(out.pointlist[i*3], out.pointlist[i*3+1], out.pointlist[i*3+2]);
      mesh->add_point(p);
    }

    VMesh::Node::size_type numnodes = mesh->num_nodes();
    VMesh::Node::array_type nodes(4);
    for (int i = 0; i < out.numberoftetrahedra; i++)
    {
      nodes[0] = out.tetrahedronlist[i*4];
      nodes[1] = out.tetrahedronlist[i*4+1];
      nodes[2] = out.tetrahedronlist[i*4+2];
      nodes[3] = out.tetrahedronlist[i*4+3];

      if (nodes[0] >= numnodes ||nodes[1] >= numnodes ||
          nodes[2] >= numnodes ||nodes[3] >= numnodes )
      {
        module_->error("TetGen failed to produce a valid tetrahedralization");
        return nullptr;
      }
      mesh->add_elem(nodes);
    }

    field->resize_values();

    int atts =  out.numberoftetrahedronattributes;

    for (int i = 0; i < out.numberoftetrahedra; i++)
    {
      for (int j = 0; j < atts; j++)
      {
        double val = out.tetrahedronattributelist[i * atts + j];
        field->set_value(val, VMesh::Elem::index_type(i));
      }
    }

    module_->getUpdaterFunc()(1.0);
    return tetvol_out;
}

InterfaceWithTetGenInput::InterfaceWithTetGenInput() :
piecewiseFlag_(true),
assignFlag_(true),
setNonzeroAttributeFlag_(false),
suppressSplitFlag_(true),
setSplitFlag_(false),
qualityFlag_(true),
setRatioFlag_(false),
volConstraintFlag_(false),
setMaxVolConstraintFlag_(false),
// see TetGen documentation for "-q" switch: default is 2.0
minRadius_(2.0),
maxVolConstraint_(0.1),
detectIntersectionsFlag_(false),
moreSwitches_("")
{
}

InterfaceWithTetGenImpl::InterfaceWithTetGenImpl(Module* module, const InterfaceWithTetGenInput& input) :
  impl_(new detail::InterfaceWithTetGenImplImpl(module)),
  inputFlags_(input)
{}

FieldHandle InterfaceWithTetGenImpl::runImpl(const std::deque<FieldHandle>& surfaces, FieldHandle points, FieldHandle region_attribs) const
{
  return impl_->runImpl(surfaces, points, region_attribs, inputFlags_);
}
<|endoftext|>


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

// Interface header.
#include "diffusebtdf.h"

// appleseed.renderer headers.
#include "renderer/kernel/lighting/scatteringmode.h"
#include "renderer/kernel/shading/directshadingcomponents.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/bsdf/bsdfsample.h"
#include "renderer/modeling/bsdf/bsdfwrapper.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/fresnel.h"
#include "foundation/math/sampling/mappings.h"
#include "foundation/math/vector.h"
#include "foundation/utility/api/specializedapiarrays.h"
#include "foundation/utility/containers/dictionary.h"

// Standard headers.
#include <algorithm>
#include <cmath>
#include <cstddef>

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Diffuse BTDF.
    //

    const char* Model = "diffuse_btdf";

    class DiffuseBTDFImpl
      : public BSDF
    {
      public:
        DiffuseBTDFImpl(
            const char*                 name,
            const ParamArray&           params)
          : BSDF(name, Transmissive, ScatteringMode::Diffuse, params)
        {
            m_inputs.declare("transmittance", InputFormatSpectralReflectance);
            m_inputs.declare("transmittance_multiplier", InputFormatFloat, "1.0");
        }

        void release() override
        {
            delete this;
        }

        const char* get_model() const override
        {
            return Model;
        }

        size_t compute_input_data_size() const override
        {
            return sizeof(InputValues);
        }

        void prepare_inputs(
            Arena&                      arena,
            const ShadingPoint&         shading_point,
            void*                       data) const override
        {
            InputValues* values = static_cast<InputValues*>(data);
            new (&values->m_precomputed) InputValues::Precomputed();
            values->m_precomputed.m_backfacing = !shading_point.is_entering();
        }

        void sample(
            SamplingContext&            sampling_context,
            const void*                 data,
            const bool                  adjoint,
            const bool                  cosine_mult,
            const int                   modes,
            BSDFSample&                 sample) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return;

            const InputValues* values = static_cast<const InputValues*>(data);

            // Compute the incoming direction.
            sampling_context.split_in_place(2, 1);
            const Vector2f s = sampling_context.next2<Vector2f>();
            Vector3f wi = sample_hemisphere_cosine(s);
            const float cos_in = wi.y;

            // Compute the probability density of the sampled direction.
            const float probability = cos_in * RcpPi<float>();
            assert(probability > 0.0f);

            if (probability > 1.0e-6f)
            {
                sample.set_to_scattering(ScatteringMode::Diffuse, probability);

                // Flip the incoming direction to the other side of the surface.
                wi.y = -wi.y;

                sample.m_incoming = Dual3f(sample.m_shading_basis.transform_to_parent(wi));

                // Compute the BRDF value.
                sample.m_value.m_diffuse = values->m_transmittance;
                sample.m_value.m_diffuse *= values->m_transmittance_multiplier * RcpPi<float>();
                sample.m_value.m_beauty = sample.m_value.m_diffuse;
                sample.m_aov_components.m_albedo = values->m_transmittance;

                sample.m_min_roughness = 1.0f;
            }
        }

        float evaluate(
            const void*                 data,
            const bool                  adjoint,
            const bool                  cosine_mult,
            const Vector3f&             geometric_normal,
            const Basis3f&              shading_basis,
            const Vector3f&             outgoing,
            const Vector3f&             incoming,
            const int                   modes,
            DirectShadingComponents&    value) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return 0.0f;

            const Vector3f& n = shading_basis.get_normal();
            const float cos_in = dot(incoming, n);
            const float cos_on = dot(outgoing, n);

            if (cos_in * cos_on < 0.0f)
            {
                const InputValues* values = static_cast<const InputValues*>(data);

                // Compute the BRDF value.
                value.m_diffuse = values->m_transmittance;
                value.m_diffuse *= values->m_transmittance_multiplier * RcpPi<float>();
                value.m_beauty = value.m_diffuse;

                // Return the probability density of the sampled direction.
                return abs(cos_in) * RcpPi<float>();
            }
            else
            {
                // No transmission in the same hemisphere as outgoing.
                return 0.0f;
            }
        }

        float evaluate_pdf(
            const void*                 data,
            const bool                  adjoint,
            const Vector3f&             geometric_normal,
            const Basis3f&              shading_basis,
            const Vector3f&             outgoing,
            const Vector3f&             incoming,
            const int                   modes) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return 0.0f;

            const Vector3f& n = shading_basis.get_normal();
            const float cos_in = dot(incoming, n);
            const float cos_on = dot(outgoing, n);

            if (cos_in * cos_on < 0.0f)
                return abs(cos_in) * RcpPi<float>();
            else
            {
                // No transmission in the same hemisphere as outgoing.
                return 0.0f;
            }
        }

      private:
        typedef DiffuseBTDFInputValues InputValues;
    };

    typedef BSDFWrapper<DiffuseBTDFImpl> DiffuseBTDF;
}

//
// DiffuseBTDFFactory class implementation.
//

void DiffuseBTDFFactory::release()
{
    delete this;
}

const char* DiffuseBTDFFactory::get_model() const
{
    return Model;
}

Dictionary DiffuseBTDFFactory::get_model_metadata() const
{
    return
        Dictionary()
            .insert("name", Model)
            .insert("label", "Diffuse BTDF");
}

DictionaryArray DiffuseBTDFFactory::get_input_metadata() const
{
    DictionaryArray metadata;

    metadata.push_back(
        Dictionary()
            .insert("name", "transmittance")
            .insert("label", "Transmittance")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Texture Instances"))
            .insert("use", "required")
            .insert("default", "0.5"));

    metadata.push_back(
        Dictionary()
            .insert("name", "transmittance_multiplier")
            .insert("label", "Transmittance Multiplier")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Texture Instances"))
            .insert("use", "optional")
            .insert("default", "1.0"));

    return metadata;
}

auto_release_ptr<BSDF> DiffuseBTDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<BSDF>(new DiffuseBTDF(name, params));
}

}   // namespace renderer
<commit_msg>Fix diffuse btdf aov components (#2670)<commit_after>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "diffusebtdf.h"

// appleseed.renderer headers.
#include "renderer/kernel/lighting/scatteringmode.h"
#include "renderer/kernel/shading/directshadingcomponents.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/bsdf/bsdfsample.h"
#include "renderer/modeling/bsdf/bsdfwrapper.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/fresnel.h"
#include "foundation/math/sampling/mappings.h"
#include "foundation/math/vector.h"
#include "foundation/utility/api/specializedapiarrays.h"
#include "foundation/utility/containers/dictionary.h"

// Standard headers.
#include <algorithm>
#include <cmath>
#include <cstddef>

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Diffuse BTDF.
    //

    const char* Model = "diffuse_btdf";

    class DiffuseBTDFImpl
      : public BSDF
    {
      public:
        DiffuseBTDFImpl(
            const char*                 name,
            const ParamArray&           params)
          : BSDF(name, Transmissive, ScatteringMode::Diffuse, params)
        {
            m_inputs.declare("transmittance", InputFormatSpectralReflectance);
            m_inputs.declare("transmittance_multiplier", InputFormatFloat, "1.0");
        }

        void release() override
        {
            delete this;
        }

        const char* get_model() const override
        {
            return Model;
        }

        size_t compute_input_data_size() const override
        {
            return sizeof(InputValues);
        }

        void prepare_inputs(
            Arena&                      arena,
            const ShadingPoint&         shading_point,
            void*                       data) const override
        {
            InputValues* values = static_cast<InputValues*>(data);
            new (&values->m_precomputed) InputValues::Precomputed();
            values->m_precomputed.m_backfacing = !shading_point.is_entering();
        }

        void sample(
            SamplingContext&            sampling_context,
            const void*                 data,
            const bool                  adjoint,
            const bool                  cosine_mult,
            const int                   modes,
            BSDFSample&                 sample) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return;

            const InputValues* values = static_cast<const InputValues*>(data);

            // Compute the incoming direction.
            sampling_context.split_in_place(2, 1);
            const Vector2f s = sampling_context.next2<Vector2f>();
            Vector3f wi = sample_hemisphere_cosine(s);
            const float cos_in = wi.y;

            // Compute the probability density of the sampled direction.
            const float probability = cos_in * RcpPi<float>();
            assert(probability > 0.0f);

            if (probability > 1.0e-6f)
            {
                sample.set_to_scattering(ScatteringMode::Diffuse, probability);

                // Flip the incoming direction to the other side of the surface.
                wi.y = -wi.y;

                sample.m_incoming = Dual3f(sample.m_shading_basis.transform_to_parent(wi));

                // Compute the BRDF value.
                sample.m_value.m_diffuse = values->m_transmittance;
                sample.m_value.m_diffuse *= values->m_transmittance_multiplier;
                sample.m_aov_components.m_albedo = sample.m_value.m_diffuse;
                sample.m_value.m_diffuse *= RcpPi<float>();
                sample.m_value.m_beauty = sample.m_value.m_diffuse;

                sample.m_min_roughness = 1.0f;
            }
        }

        float evaluate(
            const void*                 data,
            const bool                  adjoint,
            const bool                  cosine_mult,
            const Vector3f&             geometric_normal,
            const Basis3f&              shading_basis,
            const Vector3f&             outgoing,
            const Vector3f&             incoming,
            const int                   modes,
            DirectShadingComponents&    value) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return 0.0f;

            const Vector3f& n = shading_basis.get_normal();
            const float cos_in = dot(incoming, n);
            const float cos_on = dot(outgoing, n);

            if (cos_in * cos_on < 0.0f)
            {
                const InputValues* values = static_cast<const InputValues*>(data);

                // Compute the BRDF value.
                value.m_diffuse = values->m_transmittance;
                value.m_diffuse *= values->m_transmittance_multiplier * RcpPi<float>();
                value.m_beauty = value.m_diffuse;

                // Return the probability density of the sampled direction.
                return abs(cos_in) * RcpPi<float>();
            }
            else
            {
                // No transmission in the same hemisphere as outgoing.
                return 0.0f;
            }
        }

        float evaluate_pdf(
            const void*                 data,
            const bool                  adjoint,
            const Vector3f&             geometric_normal,
            const Basis3f&              shading_basis,
            const Vector3f&             outgoing,
            const Vector3f&             incoming,
            const int                   modes) const override
        {
            if (!ScatteringMode::has_diffuse(modes))
                return 0.0f;

            const Vector3f& n = shading_basis.get_normal();
            const float cos_in = dot(incoming, n);
            const float cos_on = dot(outgoing, n);

            if (cos_in * cos_on < 0.0f)
                return abs(cos_in) * RcpPi<float>();
            else
            {
                // No transmission in the same hemisphere as outgoing.
                return 0.0f;
            }
        }

      private:
        typedef DiffuseBTDFInputValues InputValues;
    };

    typedef BSDFWrapper<DiffuseBTDFImpl> DiffuseBTDF;
}

//
// DiffuseBTDFFactory class implementation.
//

void DiffuseBTDFFactory::release()
{
    delete this;
}

const char* DiffuseBTDFFactory::get_model() const
{
    return Model;
}

Dictionary DiffuseBTDFFactory::get_model_metadata() const
{
    return
        Dictionary()
            .insert("name", Model)
            .insert("label", "Diffuse BTDF");
}

DictionaryArray DiffuseBTDFFactory::get_input_metadata() const
{
    DictionaryArray metadata;

    metadata.push_back(
        Dictionary()
            .insert("name", "transmittance")
            .insert("label", "Transmittance")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Texture Instances"))
            .insert("use", "required")
            .insert("default", "0.5"));

    metadata.push_back(
        Dictionary()
            .insert("name", "transmittance_multiplier")
            .insert("label", "Transmittance Multiplier")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Texture Instances"))
            .insert("use", "optional")
            .insert("default", "1.0"));

    return metadata;
}

auto_release_ptr<BSDF> DiffuseBTDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<BSDF>(new DiffuseBTDF(name, params));
}

}   // namespace renderer
<|endoftext|>