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

#include "gflags/gflags.h"
#include "gtest/gtest.h"

#include "cybertron/cybertron.h"

#include "modules/canbus/proto/chassis.pb.h"
#include "modules/localization/proto/localization.pb.h"
#include "modules/perception/proto/traffic_light_detection.pb.h"
#include "modules/prediction/proto/prediction_obstacle.pb.h"
#include "modules/routing/proto/routing.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/planning_component.h"

namespace apollo {
namespace planning {

using apollo::cybertron::ComponentConfig;
using apollo::cybertron::Reader;
using apollo::cybertron::Writer;

using apollo::canbus::Chassis;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::perception::TrafficLightDetection;
using apollo::planning::PlanningComponent;
using apollo::prediction::PredictionObstacles;
using apollo::routing::RoutingResponse;

DEFINE_string(test_data_dir, "", "the test data folder");
DEFINE_bool(test_update_golden_log, false,
            "true to update decision golden log file.");
DEFINE_string(test_routing_response_file, "", "The routing file used in test");
DEFINE_string(test_localization_file, "", "The localization test file");
DEFINE_string(test_chassis_file, "", "The chassis test file");
DEFINE_string(test_prediction_file, "", "The prediction module test file");
DEFINE_string(test_traffic_light_file, "", "The traffic light test file");

class PlanningComponentTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    FLAGS_use_multi_thread_to_add_obstacles = false;
    FLAGS_enable_multi_thread_in_dp_poly_path = false;
    FLAGS_enable_multi_thread_in_dp_st_graph = false;
    FLAGS_planning_config_file =
        "/apollo/modules/planning/conf/planning_config.pb.txt";
    FLAGS_align_prediction_time = false;
    FLAGS_estimate_current_vehicle_state = false;
    FLAGS_enable_reference_line_provider_thread = false;
    FLAGS_planning_test_mode = true;
    // FLAGS_enable_lag_prediction = false;

    SetupCybertron();
  }

 protected:
  bool FeedTestData(LocalView* local_view);
  void SetupCybertron();
  bool RunPlanning(const std::string& test_case_name);
  void TrimPlanning(ADCTrajectory* origin);

 protected:
  bool is_cybertron_initialized_ = false;
  std::mutex mutex_;
  cybertron::ComponentConfig component_config_;

  // cybertron readers/writers
  std::shared_ptr<Writer<Chassis>> chassis_writer_;
  std::shared_ptr<Writer<LocalizationEstimate>> localization_writer_;
  std::shared_ptr<Writer<PredictionObstacles>> prediction_writer_;
  std::shared_ptr<Writer<RoutingResponse>> routing_response_writer_;
  std::shared_ptr<Writer<TrafficLightDetection>>
      traffic_light_detection_writer_;
  std::shared_ptr<Reader<ADCTrajectory>> planning_reader_;

  std::shared_ptr<PlanningComponent> planning_component_ = nullptr;
  ADCTrajectory adc_trajectory_;
};

void PlanningComponentTest::SetupCybertron() {
  if (is_cybertron_initialized_) {
    return;
  }

  // init cybertron framework
  apollo::cybertron::Init("planning_test");

  Clock::SetMode(Clock::CYBERTRON);

  component_config_.set_name("planning_test");
  // note: the sequence to add_readers() must be the same
  //       as what's in PlanningComponent::Proc()
  component_config_.add_readers()->set_channel(FLAGS_prediction_topic);
  component_config_.add_readers()->set_channel(FLAGS_chassis_topic);
  component_config_.add_readers()->set_channel(FLAGS_localization_topic);

  std::shared_ptr<apollo::cybertron::Node> node(
      apollo::cybertron::CreateNode("planning_test"));

  chassis_writer_ = node->CreateWriter<Chassis>(FLAGS_chassis_topic);
  localization_writer_ =
      node->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
  prediction_writer_ =
      node->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
  routing_response_writer_ =
      node->CreateWriter<RoutingResponse>(FLAGS_routing_response_topic);
  traffic_light_detection_writer_ = node->CreateWriter<TrafficLightDetection>(
      FLAGS_traffic_light_detection_topic);

  planning_reader_ = node->CreateReader<ADCTrajectory>(
      FLAGS_planning_trajectory_topic,
      [this](const std::shared_ptr<ADCTrajectory>& adc_trajectory) {
        ADEBUG << "Received planning data: run planning callback.";
        std::lock_guard<std::mutex> lock(mutex_);
        adc_trajectory_.CopyFrom(*adc_trajectory);
      });

  is_cybertron_initialized_ = true;
}

bool PlanningComponentTest::FeedTestData(LocalView* local_view) {
  // chassis
  Chassis chassis;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_chassis_file, &chassis)) {
    AERROR << "failed to load file: " << FLAGS_test_chassis_file;
    return false;
  }

  // localization
  LocalizationEstimate localization;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_localization_file,
          &localization)) {
    AERROR << "failed to load file: " << FLAGS_test_localization_file;
    return false;
  }

  // prediction
  PredictionObstacles prediction;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_prediction_file,
          &prediction)) {
    AERROR << "failed to load file: " << FLAGS_test_prediction_file;
    return false;
  }

  // routing_response
  RoutingResponse routing_response;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_routing_response_file,
          &routing_response)) {
    AERROR << "failed to load file: " << FLAGS_test_routing_response_file;
    return false;
  }

  // traffic_light_detection
  TrafficLightDetection traffic_light_detection;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_traffic_light_file,
          &traffic_light_detection)) {
    AERROR << "failed to load file: " << FLAGS_test_traffic_light_file;
    return false;
  }

  local_view->chassis = std::make_shared<Chassis>(chassis);
  local_view->localization_estimate =
      std::make_shared<LocalizationEstimate>(localization);
  local_view->prediction_obstacles =
      std::make_shared<PredictionObstacles>(prediction);
  local_view->routing = std::make_shared<RoutingResponse>(routing_response);
  local_view->traffic_light =
      std::make_shared<TrafficLightDetection>(traffic_light_detection);

  AINFO << "Successfully feed proto files.";
  return true;
}

bool PlanningComponentTest::RunPlanning(const std::string& test_case_name) {
  LocalView local_view;
  CHECK(FeedTestData(&local_view)) << "Failed to feed test data";

  planning_component_.reset(new PlanningComponent());
  planning_component_->Initialize(component_config_);

  usleep(1000);  // sleep 1ms

  // feed topics
  routing_response_writer_->Write(local_view.routing);
  traffic_light_detection_writer_->Write(local_view.traffic_light);
  chassis_writer_->Write(local_view.chassis);
  localization_writer_->Write(local_view.localization_estimate);

  usleep(1000);  // sleep 1ms to resolve race condition

  // note: main channel must be written last
  prediction_writer_->Write(local_view.prediction_obstacles);

  usleep(200000);  // sleep 200ms

  TrimPlanning(&adc_trajectory_);

  const std::string golden_result_file =
      apollo::common::util::StrCat("result_", test_case_name, "_0.pb.txt");
  std::string full_golden_path = FLAGS_test_data_dir + "/" + golden_result_file;
  if (FLAGS_test_update_golden_log) {
    AINFO << "The golden file is regenerated:" << full_golden_path;
    common::util::SetProtoToASCIIFile(adc_trajectory_, full_golden_path);
  } else {
    ADCTrajectory golden_result;
    bool load_success =
        common::util::GetProtoFromASCIIFile(full_golden_path, &golden_result);
    TrimPlanning(&golden_result);
    if (!load_success ||
        !common::util::IsProtoEqual(golden_result, adc_trajectory_)) {
      char tmp_fname[100] = "/tmp/XXXXXX";
      int fd = mkstemp(tmp_fname);
      if (!common::util::SetProtoToASCIIFile(adc_trajectory_, fd)) {
        AERROR << "Failed to write to file " << tmp_fname;
      }
      AERROR << "found\ndiff " << tmp_fname << " " << full_golden_path;
      AERROR << "visualize diff\n/usr/bin/python "
                "modules/tools/plot_trace/plot_planning_result.py "
             << tmp_fname << " " << full_golden_path;
      return false;
    }
  }
  return true;
}

void PlanningComponentTest::TrimPlanning(ADCTrajectory* origin) {
  origin->clear_latency_stats();
  origin->clear_debug();
  origin->mutable_header()->clear_radar_timestamp();
  origin->mutable_header()->clear_lidar_timestamp();
  origin->mutable_header()->clear_timestamp_sec();
  origin->mutable_header()->clear_camera_timestamp();
  origin->mutable_header()->clear_sequence_num();
}

/*
 * test garage_test/stop_obstacle case, using the exact same test data
 */
TEST_F(PlanningComponentTest, garage_stop_obstacle) {
  FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
  FLAGS_map_dir = "modules/planning/testdata/garage_map";
  FLAGS_base_map_filename = "base_map.txt";
  FLAGS_test_routing_response_file = "garage_routing.pb.txt";
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  FLAGS_enable_multi_thread_in_dp_poly_path = true;
  FLAGS_enable_multi_thread_in_dp_st_graph = true;

  bool run_planning_success = RunPlanning("planning_componnet_stop_obstacle");
  EXPECT_TRUE(run_planning_success);
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Fixed test.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include <memory>

#include "gflags/gflags.h"
#include "gtest/gtest.h"

#include "cybertron/cybertron.h"

#include "modules/canbus/proto/chassis.pb.h"
#include "modules/localization/proto/localization.pb.h"
#include "modules/perception/proto/traffic_light_detection.pb.h"
#include "modules/prediction/proto/prediction_obstacle.pb.h"
#include "modules/routing/proto/routing.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/planning_component.h"

namespace apollo {
namespace planning {

using apollo::cybertron::ComponentConfig;
using apollo::cybertron::Reader;
using apollo::cybertron::Writer;

using apollo::canbus::Chassis;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::perception::TrafficLightDetection;
using apollo::planning::PlanningComponent;
using apollo::prediction::PredictionObstacles;
using apollo::routing::RoutingResponse;

DEFINE_string(test_data_dir, "", "the test data folder");
DEFINE_bool(test_update_golden_log, false,
            "true to update decision golden log file.");
DEFINE_string(test_routing_response_file, "", "The routing file used in test");
DEFINE_string(test_localization_file, "", "The localization test file");
DEFINE_string(test_chassis_file, "", "The chassis test file");
DEFINE_string(test_prediction_file, "", "The prediction module test file");
DEFINE_string(test_traffic_light_file, "", "The traffic light test file");

class PlanningComponentTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    FLAGS_use_multi_thread_to_add_obstacles = false;
    FLAGS_enable_multi_thread_in_dp_poly_path = false;
    FLAGS_enable_multi_thread_in_dp_st_graph = false;
    FLAGS_planning_config_file =
        "/apollo/modules/planning/conf/planning_config.pb.txt";
    FLAGS_align_prediction_time = false;
    FLAGS_estimate_current_vehicle_state = false;
    FLAGS_enable_reference_line_provider_thread = false;
    FLAGS_planning_test_mode = true;
    // FLAGS_enable_lag_prediction = false;

    SetupCybertron();
  }

 protected:
  bool FeedTestData(LocalView* local_view);
  void SetupCybertron();
  bool RunPlanning(const std::string& test_case_name);
  void TrimPlanning(ADCTrajectory* origin);

 protected:
  bool is_cybertron_initialized_ = false;
  std::mutex mutex_;
  cybertron::ComponentConfig component_config_;

  // cybertron readers/writers
  std::shared_ptr<Writer<Chassis>> chassis_writer_;
  std::shared_ptr<Writer<LocalizationEstimate>> localization_writer_;
  std::shared_ptr<Writer<PredictionObstacles>> prediction_writer_;
  std::shared_ptr<Writer<RoutingResponse>> routing_response_writer_;
  std::shared_ptr<Writer<TrafficLightDetection>>
      traffic_light_detection_writer_;
  std::shared_ptr<Reader<ADCTrajectory>> planning_reader_;

  std::shared_ptr<PlanningComponent> planning_component_ = nullptr;
  ADCTrajectory adc_trajectory_;
};

void PlanningComponentTest::SetupCybertron() {
  if (is_cybertron_initialized_) {
    return;
  }

  // init cybertron framework
  apollo::cybertron::Init("planning_test");

  Clock::SetMode(Clock::CYBERTRON);

  component_config_.set_name("planning_test");
  // note: the sequence to add_readers() must be the same
  //       as what's in PlanningComponent::Proc()
  component_config_.add_readers()->set_channel(FLAGS_prediction_topic);
  component_config_.add_readers()->set_channel(FLAGS_chassis_topic);
  component_config_.add_readers()->set_channel(FLAGS_localization_topic);

  std::shared_ptr<apollo::cybertron::Node> node(
      apollo::cybertron::CreateNode("planning_test"));

  chassis_writer_ = node->CreateWriter<Chassis>(FLAGS_chassis_topic);
  localization_writer_ =
      node->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
  prediction_writer_ =
      node->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
  routing_response_writer_ =
      node->CreateWriter<RoutingResponse>(FLAGS_routing_response_topic);
  traffic_light_detection_writer_ = node->CreateWriter<TrafficLightDetection>(
      FLAGS_traffic_light_detection_topic);

  planning_reader_ = node->CreateReader<ADCTrajectory>(
      FLAGS_planning_trajectory_topic,
      [this](const std::shared_ptr<ADCTrajectory>& adc_trajectory) {
        ADEBUG << "Received planning data: run planning callback.";
        std::lock_guard<std::mutex> lock(mutex_);
        adc_trajectory_.CopyFrom(*adc_trajectory);
      });

  is_cybertron_initialized_ = true;
}

bool PlanningComponentTest::FeedTestData(LocalView* local_view) {
  // chassis
  Chassis chassis;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_chassis_file, &chassis)) {
    AERROR << "failed to load file: " << FLAGS_test_chassis_file;
    return false;
  }

  // localization
  LocalizationEstimate localization;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_localization_file,
          &localization)) {
    AERROR << "failed to load file: " << FLAGS_test_localization_file;
    return false;
  }

  // prediction
  PredictionObstacles prediction;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_prediction_file,
          &prediction)) {
    AERROR << "failed to load file: " << FLAGS_test_prediction_file;
    return false;
  }

  // routing_response
  RoutingResponse routing_response;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_routing_response_file,
          &routing_response)) {
    AERROR << "failed to load file: " << FLAGS_test_routing_response_file;
    return false;
  }

  // traffic_light_detection
  TrafficLightDetection traffic_light_detection;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_traffic_light_file,
          &traffic_light_detection)) {
    AERROR << "failed to load file: " << FLAGS_test_traffic_light_file;
    return false;
  }

  local_view->chassis = std::make_shared<Chassis>(chassis);
  local_view->localization_estimate =
      std::make_shared<LocalizationEstimate>(localization);
  local_view->prediction_obstacles =
      std::make_shared<PredictionObstacles>(prediction);
  local_view->routing = std::make_shared<RoutingResponse>(routing_response);
  local_view->traffic_light =
      std::make_shared<TrafficLightDetection>(traffic_light_detection);

  AINFO << "Successfully feed proto files.";
  return true;
}

bool PlanningComponentTest::RunPlanning(const std::string& test_case_name) {
  LocalView local_view;
  CHECK(FeedTestData(&local_view)) << "Failed to feed test data";

  planning_component_.reset(new PlanningComponent());
  planning_component_->Initialize(component_config_);

  usleep(1000);  // sleep 1ms

  // feed topics
  routing_response_writer_->Write(local_view.routing);
  usleep(20000);  // sleep 20 ms

  traffic_light_detection_writer_->Write(local_view.traffic_light);
  usleep(1000);  // sleep 1ms

  chassis_writer_->Write(local_view.chassis);
  usleep(1000);  // sleep 1ms

  localization_writer_->Write(local_view.localization_estimate);
  usleep(1000);  // sleep 1ms to resolve race condition

  // note: main channel must be written last
  prediction_writer_->Write(local_view.prediction_obstacles);
  usleep(200000);  // sleep 200ms

  TrimPlanning(&adc_trajectory_);

  const std::string golden_result_file =
      apollo::common::util::StrCat("result_", test_case_name, "_0.pb.txt");
  std::string full_golden_path = FLAGS_test_data_dir + "/" + golden_result_file;
  if (FLAGS_test_update_golden_log) {
    AINFO << "The golden file is regenerated:" << full_golden_path;
    common::util::SetProtoToASCIIFile(adc_trajectory_, full_golden_path);
  } else {
    ADCTrajectory golden_result;
    bool load_success =
        common::util::GetProtoFromASCIIFile(full_golden_path, &golden_result);
    TrimPlanning(&golden_result);
    if (!load_success ||
        !common::util::IsProtoEqual(golden_result, adc_trajectory_)) {
      char tmp_fname[100] = "/tmp/XXXXXX";
      int fd = mkstemp(tmp_fname);
      if (!common::util::SetProtoToASCIIFile(adc_trajectory_, fd)) {
        AERROR << "Failed to write to file " << tmp_fname;
      }
      AERROR << "found\ndiff " << tmp_fname << " " << full_golden_path;
      AERROR << "visualize diff\n/usr/bin/python "
                "modules/tools/plot_trace/plot_planning_result.py "
             << tmp_fname << " " << full_golden_path;
      return false;
    }
  }
  return true;
}

void PlanningComponentTest::TrimPlanning(ADCTrajectory* origin) {
  origin->clear_latency_stats();
  origin->clear_debug();
  origin->mutable_header()->clear_radar_timestamp();
  origin->mutable_header()->clear_lidar_timestamp();
  origin->mutable_header()->clear_timestamp_sec();
  origin->mutable_header()->clear_camera_timestamp();
  origin->mutable_header()->clear_sequence_num();
}

/*
 * test garage_test/stop_obstacle case, using the exact same test data
 */
TEST_F(PlanningComponentTest, garage_stop_obstacle) {
  FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
  FLAGS_map_dir = "modules/planning/testdata/garage_map";
  FLAGS_base_map_filename = "base_map.txt";
  FLAGS_test_routing_response_file = "garage_routing.pb.txt";
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  FLAGS_enable_multi_thread_in_dp_poly_path = true;
  FLAGS_enable_multi_thread_in_dp_st_graph = true;

  bool run_planning_success = RunPlanning("planning_componnet_stop_obstacle");
  EXPECT_TRUE(run_planning_success);
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkHyperOctreeToUniformGridFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkHyperOctreeToUniformGridFilter.h"

#include "vtkHyperOctree.h"
#include "vtkHyperOctreeCursor.h"
#include "vtkObjectFactory.h"
#include "vtkInformationVector.h"
#include "vtkInformation.h"
#include "vtkCellArray.h"
#include <assert.h>
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkImageData.h"
#include "vtkStreamingDemandDrivenPipeline.h" // WHOLE_EXTENT() key

vtkCxxRevisionMacro(vtkHyperOctreeToUniformGridFilter, "1.3");
vtkStandardNewMacro(vtkHyperOctreeToUniformGridFilter);

// merging: locator
// no merging: insertnextpoint

//----------------------------------------------------------------------------
vtkHyperOctreeToUniformGridFilter::vtkHyperOctreeToUniformGridFilter()
{
  this->InputCD=0;
  this->OutputCD=0;
  this->Cursor=0;
  this->YExtent=1;
  this->ZExtent=1;
  this->Output=0;
}

//----------------------------------------------------------------------------
vtkHyperOctreeToUniformGridFilter::~vtkHyperOctreeToUniformGridFilter()
{
}

//----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  int levels=inInfo->Get(vtkHyperOctree::LEVELS());

  double size[3];
  inInfo->Get(vtkHyperOctree::SIZES(),size);
  double origin[3];
  inInfo->Get(vtkDataObject::ORIGIN(),origin);

  int dim=inInfo->Get(vtkHyperOctree::DIMENSION());

  vtkInformation* outInfo = outputVector->GetInformationObject(0);

   // Set dimensions, spacing and origin for the uniform grid.
  int resolutions[3];
  double spacing[3];
  resolutions[0]=(1<<(levels-1))+1;
  assert("check: min_is_2" && resolutions[0]>=2);
  spacing[0]=size[0]/(resolutions[0]-1);

  if(dim>=2)
    {
    resolutions[1]=resolutions[0];
    spacing[1]=size[1]/(resolutions[1]-1);
    this->YExtent=2;
    }
  else
    {
    resolutions[1]=1;
    spacing[1]=0;
    this->YExtent=1;
    }
  if(dim==3)
    {
    resolutions[2]=resolutions[0];
    spacing[2]=size[2]/(resolutions[2]-1);
    this->ZExtent=2;
    }
  else
    {
    resolutions[2]=1;
    spacing[2]=0;
    this->ZExtent=1;
    }

  outInfo->Set(vtkDataObject::SPACING(),spacing,3);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);

  int extent[6];
  extent[0]=0;
  extent[1]=resolutions[0]-1;
  extent[2]=0;
  extent[3]=resolutions[1]-1;
  extent[4]=0;
  extent[5]=resolutions[2]-1;

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);

  return 1;
}

//----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the upper limit for the number of levels
  int levels=inInfo->Get(vtkHyperOctree::LEVELS());

  // get the input and ouptut
  vtkHyperOctree *input = vtkHyperOctree::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *output = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  assert("check:valid_levels" && levels>=input->GetNumberOfLevels());

  this->Output=output;
  this->InputCD = input->GetPointData();
  this->OutputCD = output->GetCellData();

  int dim=input->GetDimension();
  assert("check: valid_dim" && dim>=1 && dim<=3);

  // Set dimensions, spacing and origin for the uniform grid.
  int resolutions[3];
  double spacing[3];
  cout<<"levels="<<levels<<endl;
  cout<<"inputlevels="<<input->GetNumberOfLevels()<<endl;
  resolutions[0]=(1<<(levels-1))+1;
  assert("check: min_is_2" && resolutions[0]>=2);
  spacing[0]=input->GetSize()[0]/(resolutions[0]-1);

  if(dim>=2)
    {
    resolutions[1]=resolutions[0];
    spacing[1]=input->GetSize()[1]/(resolutions[1]-1);
    this->YExtent=2;
    }
  else
    {
    resolutions[1]=1;
    spacing[1]=0;
    this->YExtent=1;
    }
  if(dim==3)
    {
    resolutions[2]=resolutions[0];
    spacing[2]=input->GetSize()[2]/(resolutions[2]-1);
    this->ZExtent=2;
    }
  else
    {
    resolutions[2]=1;
    spacing[2]=0;
    this->ZExtent=1;
    }
  output->SetDimensions(resolutions);
  output->SetSpacing(spacing);

  output->SetOrigin(input->GetOrigin());

  // Check if our computation is correct.
  cout<<"output="<<output->GetNumberOfPoints()<<endl;
  cout<<"maxinput="<<input->GetMaxNumberOfPoints(0)<<endl;
  assert("check: valid_number_of_points" && output->GetNumberOfPoints()>=input->GetMaxNumberOfPoints(0)); // not equal if LEVELS()>GetNumberOfLevels()
  assert("check valid_y_extent" && this->YExtent==1 || this->YExtent==2);
  assert("check valid_z_extent" && this->ZExtent==1 || this->ZExtent==2);
  //A=>B: not A or B
  // yextent==1 => zextent==1
  assert("check valid_z_extent2" && this->YExtent!=1 || this->ZExtent==1);
  // zextent==2 => yextent==2
  assert("check valid_z_extent3" && this->ZExtent!=2 || this->YExtent==2);

  cout<<"number of cells="<<output->GetNumberOfCells()<<endl;

  // Prepare copy for cell data.
  this->OutputCD->CopyAllocate(this->InputCD,output->GetNumberOfCells());

  // Copy cell data recursively
  this->Cursor=input->NewCellCursor();
  this->Cursor->ToRoot();
  int extent[6];
  output->GetExtent(extent);
  // the given extent is point-based, we want a cell-based extent:
  if(extent[1]>0)
    {
    extent[1]=extent[1]-1;
    }
  if(extent[3]>0)
    {
    extent[3]=extent[3]-1;
    }
  if(extent[5]>0)
    {
    extent[5]=extent[5]-1;
    }
  this->CopyCellData(extent);
  this->Cursor->UnRegister(this);
  this->Cursor=0;
  this->InputCD=0;
  this->OutputCD=0;
  this->Output=0;

  assert("post: valid_output" && output->CheckAttributes()==0);

  return 1;
}
//-----------------------------------------------------------------------------
void vtkHyperOctreeToUniformGridFilter::CopyCellData(int cellExtent[6])
{
  assert("pre: valid_xextent" && cellExtent[0]<=cellExtent[1]);
  assert("pre: valid_yextent" && cellExtent[2]<=cellExtent[3]);
  assert("pre: valid_zextent" && cellExtent[4]<=cellExtent[5]);

  if(this->Cursor->CurrentIsLeaf())
    {
    vtkIdType inId=this->Cursor->GetLeafId();
    int ijk[3];
    ijk[2]=cellExtent[4];

#ifndef NDEBUG
    int atLeastOne=0;
#endif

    while(ijk[2]<=cellExtent[5]) // k
      {
       ijk[1]=cellExtent[2];
       while(ijk[1]<=cellExtent[3]) // j
         {
         ijk[0]=cellExtent[0];
         while(ijk[0]<=cellExtent[1]) // i
           {
#ifndef NDEBUG
           atLeastOne=1;
#endif
           vtkIdType outId=this->Output->ComputeCellId(ijk);
           this->OutputCD->CopyData(this->InputCD,inId,outId);
           ++ijk[0];
           }
         ++ijk[1];
         }
      ++ijk[2];
      }
    assert("check: make sure we entered into the loop" && atLeastOne);
    }
  else
    {
    // traverse children (zi|yi|xi)
    int zmid=(cellExtent[4]+cellExtent[5])>>1; // /2
    int ymid=(cellExtent[2]+cellExtent[3])>>1; // /2
    int xmid=(cellExtent[0]+cellExtent[1])>>1; // /2

    int newExtent[6];
    int zi=0;
    int zchild=0;
    newExtent[4]=cellExtent[4];
    newExtent[5]=zmid;
    while(zi<this->ZExtent)
      {
      int yi=0;
      int ychild=zchild;
      newExtent[2]=cellExtent[2];
      newExtent[3]=ymid;
      while(yi<this->YExtent)
        {
        int xi=0;
        int child=ychild;
        newExtent[0]=cellExtent[0];
        newExtent[1]=xmid;
        while(xi<2)
          {
          this->Cursor->ToChild(child);
          this->CopyCellData(newExtent);
          this->Cursor->ToParent();
          ++child;
          ++xi;
          newExtent[0]=xmid+1;
          newExtent[1]=cellExtent[1];
          }
        ++yi;
        ychild+=2;
        newExtent[2]=ymid+1;
        newExtent[3]=cellExtent[3];
        }
      ++zi;
      zchild+=4;
      newExtent[4]=zmid+1;
      newExtent[5]=cellExtent[5];
      }
    }
}

//-----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::FillInputPortInformation(int,
                                                          vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkHyperOctree");
  return 1;
}

//-----------------------------------------------------------------------------
void vtkHyperOctreeToUniformGridFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>ENH: Merge changes from main tree into VTK-5-2 branch. (cvs -q up -j1.3 -j1.4 Graphics/vtkHyperOctreeToUniformGridFilter.cxx)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkHyperOctreeToUniformGridFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkHyperOctreeToUniformGridFilter.h"

#include "vtkHyperOctree.h"
#include "vtkHyperOctreeCursor.h"
#include "vtkObjectFactory.h"
#include "vtkInformationVector.h"
#include "vtkInformation.h"
#include "vtkCellArray.h"
#include <assert.h>
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkImageData.h"
#include "vtkStreamingDemandDrivenPipeline.h" // WHOLE_EXTENT() key

vtkCxxRevisionMacro(vtkHyperOctreeToUniformGridFilter, "1.3.50.1");
vtkStandardNewMacro(vtkHyperOctreeToUniformGridFilter);

// merging: locator
// no merging: insertnextpoint

//----------------------------------------------------------------------------
vtkHyperOctreeToUniformGridFilter::vtkHyperOctreeToUniformGridFilter()
{
  this->InputCD=0;
  this->OutputCD=0;
  this->Cursor=0;
  this->YExtent=1;
  this->ZExtent=1;
  this->Output=0;
}

//----------------------------------------------------------------------------
vtkHyperOctreeToUniformGridFilter::~vtkHyperOctreeToUniformGridFilter()
{
}

//----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  int levels=inInfo->Get(vtkHyperOctree::LEVELS());

  double size[3];
  inInfo->Get(vtkHyperOctree::SIZES(),size);
  double origin[3];
  inInfo->Get(vtkDataObject::ORIGIN(),origin);

  int dim=inInfo->Get(vtkHyperOctree::DIMENSION());

  vtkInformation* outInfo = outputVector->GetInformationObject(0);

   // Set dimensions, spacing and origin for the uniform grid.
  int resolutions[3];
  double spacing[3];
  resolutions[0]=(1<<(levels-1))+1;
  assert("check: min_is_2" && resolutions[0]>=2);
  spacing[0]=size[0]/(resolutions[0]-1);

  if(dim>=2)
    {
    resolutions[1]=resolutions[0];
    spacing[1]=size[1]/(resolutions[1]-1);
    this->YExtent=2;
    }
  else
    {
    resolutions[1]=1;
    spacing[1]=0;
    this->YExtent=1;
    }
  if(dim==3)
    {
    resolutions[2]=resolutions[0];
    spacing[2]=size[2]/(resolutions[2]-1);
    this->ZExtent=2;
    }
  else
    {
    resolutions[2]=1;
    spacing[2]=0;
    this->ZExtent=1;
    }

  outInfo->Set(vtkDataObject::SPACING(),spacing,3);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);

  int extent[6];
  extent[0]=0;
  extent[1]=resolutions[0]-1;
  extent[2]=0;
  extent[3]=resolutions[1]-1;
  extent[4]=0;
  extent[5]=resolutions[2]-1;

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);

  return 1;
}

//----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the upper limit for the number of levels
  int levels=inInfo->Get(vtkHyperOctree::LEVELS());

  // get the input and ouptut
  vtkHyperOctree *input = vtkHyperOctree::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *output = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  assert("check:valid_levels" && levels>=input->GetNumberOfLevels());

  this->Output=output;
  this->InputCD = input->GetPointData();
  this->OutputCD = output->GetCellData();

  int dim=input->GetDimension();
  assert("check: valid_dim" && dim>=1 && dim<=3);

  // Set dimensions, spacing and origin for the uniform grid.
  int resolutions[3];
  double spacing[3];
  cout<<"levels="<<levels<<endl;
  cout<<"inputlevels="<<input->GetNumberOfLevels()<<endl;
  resolutions[0]=(1<<(levels-1))+1;
  assert("check: min_is_2" && resolutions[0]>=2);
  spacing[0]=input->GetSize()[0]/(resolutions[0]-1);

  if(dim>=2)
    {
    resolutions[1]=resolutions[0];
    spacing[1]=input->GetSize()[1]/(resolutions[1]-1);
    this->YExtent=2;
    }
  else
    {
    resolutions[1]=1;
    spacing[1]=0;
    this->YExtent=1;
    }
  if(dim==3)
    {
    resolutions[2]=resolutions[0];
    spacing[2]=input->GetSize()[2]/(resolutions[2]-1);
    this->ZExtent=2;
    }
  else
    {
    resolutions[2]=1;
    spacing[2]=0;
    this->ZExtent=1;
    }
  output->SetDimensions(resolutions);
  output->SetSpacing(spacing);

  output->SetOrigin(input->GetOrigin());

  // Check if our computation is correct.
  cout<<"output="<<output->GetNumberOfPoints()<<endl;
  cout<<"maxinput="<<input->GetMaxNumberOfPoints(0)<<endl;
  assert("check: valid_number_of_points" && output->GetNumberOfPoints()>=input->GetMaxNumberOfPoints(0)); // not equal if LEVELS()>GetNumberOfLevels()
  assert("check valid_y_extent" && (this->YExtent==1 || this->YExtent==2));
  assert("check valid_z_extent" && (this->ZExtent==1 || this->ZExtent==2));
  //A=>B: not A or B
  // yextent==1 => zextent==1
  assert("check valid_z_extent2" && (this->YExtent!=1 || this->ZExtent==1));
  // zextent==2 => yextent==2
  assert("check valid_z_extent3" && (this->ZExtent!=2 || this->YExtent==2));

  cout<<"number of cells="<<output->GetNumberOfCells()<<endl;

  // Prepare copy for cell data.
  this->OutputCD->CopyAllocate(this->InputCD,output->GetNumberOfCells());

  // Copy cell data recursively
  this->Cursor=input->NewCellCursor();
  this->Cursor->ToRoot();
  int extent[6];
  output->GetExtent(extent);
  // the given extent is point-based, we want a cell-based extent:
  if(extent[1]>0)
    {
    extent[1]=extent[1]-1;
    }
  if(extent[3]>0)
    {
    extent[3]=extent[3]-1;
    }
  if(extent[5]>0)
    {
    extent[5]=extent[5]-1;
    }
  this->CopyCellData(extent);
  this->Cursor->UnRegister(this);
  this->Cursor=0;
  this->InputCD=0;
  this->OutputCD=0;
  this->Output=0;

  assert("post: valid_output" && output->CheckAttributes()==0);

  return 1;
}
//-----------------------------------------------------------------------------
void vtkHyperOctreeToUniformGridFilter::CopyCellData(int cellExtent[6])
{
  assert("pre: valid_xextent" && cellExtent[0]<=cellExtent[1]);
  assert("pre: valid_yextent" && cellExtent[2]<=cellExtent[3]);
  assert("pre: valid_zextent" && cellExtent[4]<=cellExtent[5]);

  if(this->Cursor->CurrentIsLeaf())
    {
    vtkIdType inId=this->Cursor->GetLeafId();
    int ijk[3];
    ijk[2]=cellExtent[4];

#ifndef NDEBUG
    int atLeastOne=0;
#endif

    while(ijk[2]<=cellExtent[5]) // k
      {
       ijk[1]=cellExtent[2];
       while(ijk[1]<=cellExtent[3]) // j
         {
         ijk[0]=cellExtent[0];
         while(ijk[0]<=cellExtent[1]) // i
           {
#ifndef NDEBUG
           atLeastOne=1;
#endif
           vtkIdType outId=this->Output->ComputeCellId(ijk);
           this->OutputCD->CopyData(this->InputCD,inId,outId);
           ++ijk[0];
           }
         ++ijk[1];
         }
      ++ijk[2];
      }
    assert("check: make sure we entered into the loop" && atLeastOne);
    }
  else
    {
    // traverse children (zi|yi|xi)
    int zmid=(cellExtent[4]+cellExtent[5])>>1; // /2
    int ymid=(cellExtent[2]+cellExtent[3])>>1; // /2
    int xmid=(cellExtent[0]+cellExtent[1])>>1; // /2

    int newExtent[6];
    int zi=0;
    int zchild=0;
    newExtent[4]=cellExtent[4];
    newExtent[5]=zmid;
    while(zi<this->ZExtent)
      {
      int yi=0;
      int ychild=zchild;
      newExtent[2]=cellExtent[2];
      newExtent[3]=ymid;
      while(yi<this->YExtent)
        {
        int xi=0;
        int child=ychild;
        newExtent[0]=cellExtent[0];
        newExtent[1]=xmid;
        while(xi<2)
          {
          this->Cursor->ToChild(child);
          this->CopyCellData(newExtent);
          this->Cursor->ToParent();
          ++child;
          ++xi;
          newExtent[0]=xmid+1;
          newExtent[1]=cellExtent[1];
          }
        ++yi;
        ychild+=2;
        newExtent[2]=ymid+1;
        newExtent[3]=cellExtent[3];
        }
      ++zi;
      zchild+=4;
      newExtent[4]=zmid+1;
      newExtent[5]=cellExtent[5];
      }
    }
}

//-----------------------------------------------------------------------------
int vtkHyperOctreeToUniformGridFilter::FillInputPortInformation(int,
                                                          vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkHyperOctree");
  return 1;
}

//-----------------------------------------------------------------------------
void vtkHyperOctreeToUniformGridFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>/*
 * OBJExporter.cpp
 *
 *  Created on: 9 sept. 2009
 *      Author: froy
 */

#include "OBJExporter.h"

#include <sstream>

#include <sofa/core/ObjectFactory.h>

#include <sofa/core/objectmodel/Event.h>
#include <sofa/simulation/common/AnimateBeginEvent.h>
#include <sofa/simulation/common/AnimateEndEvent.h>
#include <sofa/simulation/common/ExportOBJVisitor.h>
#include <sofa/core/objectmodel/KeypressedEvent.h>
#include <sofa/core/objectmodel/KeyreleasedEvent.h>

namespace sofa
{

namespace component
{

namespace misc
{

SOFA_DECL_CLASS(OBJExporter)

int OBJExporterClass = core::RegisterObject("Export under Wavefront OBJ format")
        .add< OBJExporter >();

OBJExporter::OBJExporter()
    : stepCounter(0), outfile(NULL)
    , objFilename( initData(&objFilename, "filename", "output OBJ file name"))
    , exportEveryNbSteps( initData(&exportEveryNbSteps, (unsigned int)0, "exportEveryNumberOfSteps", "export file only at specified number of steps (0=disable)"))
    , exportAtBegin( initData(&exportAtBegin, false, "exportAtBegin", "export file at the initialization"))
    , exportAtEnd( initData(&exportAtEnd, false, "exportAtEnd", "export file when the simulation is finished"))
    , activateExport(false)
{
    this->f_listening.setValue(true);
}

OBJExporter::~OBJExporter()
{
    if (outfile)
        delete outfile;
    if (mtlfile)
        delete mtlfile;
}

void OBJExporter::init()
{
    context = this->getContext();
    maxStep = exportEveryNbSteps.getValue();
}

void OBJExporter::writeOBJ()
{
    std::string filename = objFilename.getFullPath();
    std::ostringstream oss;
    oss.width(5);
    oss.fill('0');
    oss << stepCounter / maxStep;
    filename += oss.str() + ".obj";
    outfile = new std::ofstream(filename.c_str());
    std::cout << "Exporting OBJ as: " << filename << std::endl;

    std::string mtlfilename = objFilename.getFullPath();
    mtlfile = new std::ofstream(mtlfilename.c_str());

    sofa::simulation::ExportOBJVisitor exportOBJ(core::ExecParams::defaultInstance(),outfile, mtlfile);
    context->executeVisitor(&exportOBJ);
    outfile->close();
    mtlfile->close();
}

void OBJExporter::handleEvent(sofa::core::objectmodel::Event *event)
{
    if (sofa::core::objectmodel::KeypressedEvent* ev = dynamic_cast<sofa::core::objectmodel::KeypressedEvent*>(event))
    {
        std::cout << "key pressed " << std::endl;
        switch(ev->getKey())
        {

        case 'E':
        case 'e':
        {
            writeOBJ();
            break;
        }

        case 'P':
        case 'p':
        {
            activateExport = !activateExport;
            break;
        }
        }
    }

    if ( /*simulation::AnimateEndEvent* ev =*/  dynamic_cast<simulation::AnimateEndEvent*>(event))
    {
        if (maxStep == 0 || !activateExport) return;

        stepCounter++;
        if(stepCounter % maxStep == 0)
        {
            //stepCounter = 0;
            writeOBJ();

        }
    }
}

void OBJExporter::cleanup()
{
    if (exportAtEnd.getValue())
        writeOBJ();

}

void OBJExporter::bwdInit()
{
    if (exportAtBegin.getValue())
        writeOBJ();
}

}

}

}
<commit_msg>r10600/sofa-dev : Fix crashes and a few things<commit_after>/*
 * OBJExporter.cpp
 *
 *  Created on: 9 sept. 2009
 *      Author: froy
 */

#include "OBJExporter.h"

#include <sstream>

#include <sofa/core/ObjectFactory.h>

#include <sofa/core/objectmodel/Event.h>
#include <sofa/simulation/common/AnimateBeginEvent.h>
#include <sofa/simulation/common/AnimateEndEvent.h>
#include <sofa/simulation/common/ExportOBJVisitor.h>
#include <sofa/core/objectmodel/KeypressedEvent.h>
#include <sofa/core/objectmodel/KeyreleasedEvent.h>

namespace sofa
{

namespace component
{

namespace misc
{

SOFA_DECL_CLASS(OBJExporter)

int OBJExporterClass = core::RegisterObject("Export under Wavefront OBJ format")
        .add< OBJExporter >();

OBJExporter::OBJExporter()
    : stepCounter(0)
    , outfile(NULL)
    , mtlfile(NULL)
    , objFilename( initData(&objFilename, "filename", "output OBJ file name"))
    , exportEveryNbSteps( initData(&exportEveryNbSteps, (unsigned int)0, "exportEveryNumberOfSteps", "export file only at specified number of steps (0=disable)"))
    , exportAtBegin( initData(&exportAtBegin, false, "exportAtBegin", "export file at the initialization"))
    , exportAtEnd( initData(&exportAtEnd, false, "exportAtEnd", "export file when the simulation is finished"))
    , activateExport(false)
{
    this->f_listening.setValue(true);
}

OBJExporter::~OBJExporter()
{
    if (outfile)
        delete outfile;
    if (mtlfile)
        delete mtlfile;
}

void OBJExporter::init()
{
    context = this->getContext();
    maxStep = exportEveryNbSteps.getValue();
}

void OBJExporter::writeOBJ()
{
    if (!maxStep) return;

    std::string filename = objFilename.getFullPath();
    std::ostringstream oss;
    oss.width(5);
    oss.fill('0');
    oss << stepCounter / maxStep;
    filename += oss.str() + ".obj";
    outfile = new std::ofstream(filename.c_str());

    std::string mtlfilename = objFilename.getFullPath();
    mtlfilename = mtlfilename + ".mtl";
    mtlfile = new std::ofstream(mtlfilename.c_str());
    sofa::simulation::ExportOBJVisitor exportOBJ(core::ExecParams::defaultInstance(),outfile, mtlfile);
    context->executeVisitor(&exportOBJ);
    outfile->close();
    mtlfile->close();

    std::cout << "Exporting OBJ as: " << filename.c_str() << " with MTL file: " << mtlfilename.c_str() << std::endl;
}

void OBJExporter::handleEvent(sofa::core::objectmodel::Event *event)
{
    if (sofa::core::objectmodel::KeypressedEvent* ev = dynamic_cast<sofa::core::objectmodel::KeypressedEvent*>(event))
    {
        switch(ev->getKey())
        {

        case 'E':
        case 'e':
        {
            writeOBJ();
            break;
        }

        case 'P':
        case 'p':
        {
            if (!activateExport)
                std::cout << "Starting OBJ sequece export..." << std::endl;
            else
                std::cout << "Ending OBJ sequece export..." << std::endl;
            activateExport = !activateExport;
            break;
        }
        }
    }

    if ( /*simulation::AnimateEndEvent* ev =*/  dynamic_cast<simulation::AnimateEndEvent*>(event))
    {
        if (maxStep == 0 || !activateExport) return;

        stepCounter++;
        if(stepCounter % maxStep == 0)
        {
            writeOBJ();
        }
    }
}

void OBJExporter::cleanup()
{
    if (exportAtEnd.getValue())
        writeOBJ();

}

void OBJExporter::bwdInit()
{
    if (exportAtBegin.getValue())
        writeOBJ();
}

}

}

}
<|endoftext|>


<commit_before>#include "NMT_Wrapper.h"

#include "util/exception.hh"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <streambuf>
#include <assert.h>

#include <python2.7/Python.h>

using namespace std;
using namespace util;

NMT_Wrapper* NMT_Wrapper::s_nmt;

NMT_Wrapper::NMT_Wrapper()
{
    py_get_log_prob = PyString_FromString((char*)"get_log_prob");
    py_get_log_probs = PyString_FromString((char*)"get_log_probs");
    py_get_vec_log_probs = PyString_FromString((char*)"get_vec_log_probs");
    py_get_context_vectors = PyString_FromString((char*)"get_context_vector");
    py_get_next_states = PyString_FromString((char*)"get_next_states");
    py_get_log_prob_states = PyString_FromString((char*)"get_log_prob_states");

    SetNMT(this);
}

NMT_Wrapper::~NMT_Wrapper () {
    Py_Finalize();
}

void NMT_Wrapper::LoadTargetVocab()
{
    PyObject* py_response = PyObject_CallMethodObjArgs(
                                py_wrapper,
                                PyString_FromString("get_target_vocab"),
                                NULL);
    const size_t vocabSize = PyList_Size(py_response);
    for (size_t i = 0; i < vocabSize; ++i) {
        m_targetVocab.insert(PyString_AsString(PyList_GetItem(py_response, i)));
    }
}

std::vector<bool> IsUnk(const std::vector<std::string>& words)
{
    std::vector<bool> isUnk(words.size());
    for (size_t i = 0; i < words.size(); ++i) {
        if(m_targetVocab.find(words[i]) != m_targetVocab.end()) {
            isUnk[i] = true;
        } else {
            isUnk[i] = false;
        }
    }
    return isUnk;
}

bool NMT_Wrapper::GetContextVectors(const string& source_sentence, PyObject*& vectors)
{
    PyObject* py_source_sentence = PyString_FromString(source_sentence.c_str());
    vectors = PyObject_CallMethodObjArgs(py_wrapper, py_get_context_vectors, py_source_sentence, NULL);
    return true;
}

void NMT_Wrapper::AddPathToSys(const string& path)
{
    PyObject* py_sys_path = PySys_GetObject((char*)"path");
    PyList_Append(py_sys_path, PyString_FromString(path.c_str()));
}

void NMT_Wrapper::Init(
        const std::string& state_path,
        const std::string& model_path,
        const std::string& wrapper_path,
        const std::string& sourceVocabPath,
        const std::string& targetVocabPath)
{
    Py_Initialize();
    AddPathToSys(wrapper_path);

    PyObject* filename = PyString_FromString((char*) "nmt_wrapper");
    PyObject* imp = PyImport_Import(filename);
    UTIL_THROW_IF2(imp == NULL, "The wrapper module could not be imported.");

    PyObject* wrapper_name = PyObject_GetAttrString(imp, (char*)"NMTWrapper");
    UTIL_THROW_IF2(wrapper_name == NULL, "It could not find NMTWrapper class.");

    PyObject* args = PyTuple_Pack(4,
            PyString_FromString(state_path.c_str()),
            PyString_FromString(model_path.c_str()),
            PyString_FromString(sourceVocabPath.c_str()),
            PyString_FromString(targetVocabPath.c_str()));

    py_wrapper = PyObject_CallObject(wrapper_name, args);
    UTIL_THROW_IF2(py_wrapper == NULL, "Problem with creating NMT_Wrapper.");

    UTIL_THROW_IF2(PyObject_CallMethod(py_wrapper, (char*)"build", NULL) == NULL,
            "Problem with build NMT_Wrapper");

    LoadTargetVocab();
}

bool NMT_Wrapper::GetProb(const string& next_word,
                          PyObject* py_context_vectors,
                          const string& last_word,
                          PyObject* input_state,
                          double& output_prob,
                          PyObject*& output_state)
{
    PyObject* py_next_word = PyString_FromString(next_word.c_str());
    PyObject* py_response = NULL;

    if (input_state == NULL)
    {
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_prob, py_next_word, py_context_vectors, NULL);
    }
    else {
        PyObject* py_last_word = PyString_FromString(last_word.c_str());
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_prob, py_next_word, py_context_vectors,
                                                 py_last_word, input_state, NULL);
    }

   if (py_response == NULL) { return false; }
    if (! PyTuple_Check(py_response)) { return false; }

    PyObject* py_prob = PyTuple_GetItem(py_response, 0);
    if (py_prob == NULL) { return false; }
    output_prob = PyFloat_AsDouble(py_prob);

    output_state = PyTuple_GetItem(py_response, 1);
    if (output_state == NULL) { return 0; }

    return true;
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& next_words,
                          PyObject* py_context_vectors,
                          const string& last_word,
                          PyObject* input_state,
                          double& logProb,
                          PyObject*& output_state)
{
    PyObject* py_nextWords = PyList_New(0);
    for (size_t i = 0; i < next_words.size(); ++i) {
        PyList_Append(py_nextWords, PyString_FromString(next_words[i].c_str()));
    }

    PyObject* py_response = NULL;

    if (input_state == NULL)
    {
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_probs,
                                                 py_nextWords, py_context_vectors, NULL);
    }
    else {
        PyObject* py_last_word = PyString_FromString(last_word.c_str());
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_probs, py_nextWords, py_context_vectors,
                                                 py_last_word, input_state, NULL);
    }

    if (py_response == NULL) { return false; }
    if (! PyTuple_Check(py_response)) { return false; }

    PyObject* py_prob = PyTuple_GetItem(py_response, 0);
    if (py_prob == NULL) { return false; }
    logProb = PyFloat_AsDouble(py_prob);

    output_state = PyTuple_GetItem(py_response, 1);
    if (output_state == NULL) { return 0; }

    return true;
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& nextWords,
                          PyObject* pyContextVectors,
                          const std::vector< string >& lastWords,
                          std::vector< PyObject* >& inputStates,
                          std::vector< std::vector< double > >& logProbs,
                          std::vector< std::vector< PyObject* > >& outputStates,
{
    std::vector<bool> unks;
    GetProb(nextWords,
            pyContextVectors,
            lastWords,
            inputStates,
            logProbs,
            outputStates,
            unks);
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& nextWords,
                          PyObject* pyContextVectors,
                          const std::vector< string >& lastWords,
                          std::vector< PyObject* >& inputStates,
                          std::vector< std::vector< double > >& logProbs,
                          std::vector< std::vector< PyObject* > >& outputStates,
                          std::vector<bool> unks)
{
    PyObject* pyNextWords = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyNextWords, PyString_FromString(nextWords[i].c_str()));
    }

    PyObject* pyLastWords = PyList_New(0);
    for (size_t i = 0; i < lastWords.size(); ++i) {
        PyList_Append(pyLastWords, PyString_FromString(lastWords[i].c_str()));
    }

    PyObject* pyResponse = NULL;
    if (inputStates.size() == 0) {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_vec_log_probs,
                                                pyNextWords,
                                                pyContextVectors,
                                                NULL);
    } else {
        PyObject* pyInputStates = PyList_New(0);
        for (size_t i = 0; i < inputStates.size(); ++i) {
            PyList_Append(pyInputStates, inputStates[i]);
        }

        PyObject* pyLastWords = PyList_New(0);
        for (size_t i = 0; i < lastWords.size(); ++i) {
            PyList_Append(pyLastWords, PyString_FromString(lastWords[i].c_str()));
        }

        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_vec_log_probs,
                                                pyNextWords,
                                                pyContextVectors,
                                                pyLastWords,
                                                pyInputStates,
                                                NULL);
    }
    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    size_t inputSize = 0;
    if (inputStates.size() == 0) {
        inputSize = 1;
    } else {
        inputSize = inputStates.size();
    }

    PyObject* pyLogProbMatrix = PyTuple_GetItem(pyResponse, 0);
    PyObject* pyOutputStateMatrix = PyTuple_GetItem(pyResponse, 1);
    logProbs.clear();
    outputStates = vector<vector<PyObject*> >(inputSize, vector<PyObject*>(nextWords.size(), NULL));
    vector<double> hipoProbs;
    vector<PyObject*> hipoStates;
    logProbs.clear();
    for (size_t i = 0; i < inputSize; ++i) {
        hipoProbs.clear();
        hipoStates.clear();

        PyObject* pyLogProbColumn = PyList_GetItem(pyLogProbMatrix, i);
        for (size_t j = 0; j < nextWords.size(); ++j) {
            hipoProbs.push_back(PyFloat_AsDouble(PyList_GetItem(pyLogProbColumn, j)));
        }
        logProbs.push_back(hipoProbs);
    }

    for (size_t j = 0; j < nextWords.size(); ++j) {
        PyObject* pyOutputStateColumn = PyList_GetItem(pyOutputStateMatrix, j);
        for (size_t i = 0; i < inputSize; ++i) {
            outputStates[i][j]  = PyList_GetItem(pyOutputStateColumn, i);
        }

        outputStates.push_back(hipoStates);
    }
    unks = IsUnk(nextWords);

    return true;
}
void NMT_Wrapper::GetNextStates(
        const std::vector<std::string>& nextWords,
        PyObject* pyContextVectors,
        std::vector<PyObject*>& inputStates,
        std::vector<PyObject*>& nextStates)
{
    UTIL_THROW_IF2(nextWords.size() != nextStates.size(), "#nextWords != #inputStates");
    UTIL_THROW_IF2(nextWords.size() == 0, "No hipothesis!");

    PyObject* pyNextWords = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyNextWords, PyString_FromString(nextWords[i].c_str()));
    }

    PyObject* pyInputStates = PyList_New(0);
    for (size_t i = 0; i < inputStates.size(); ++i) {
        PyList_Append(pyInputStates, inputStates[i]);
    }

    PyObject* pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                            py_get_next_states,
                                            pyNextWords,
                                            pyContextVectors,
                                            pyInputStates,
                                            NULL);

    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    nextStates.clear();
    size_t nextStatesSize = PyList_Size(pyResponse);
    UTIL_THROW_IF2(nextStatesSize != inputStates.size(), "Returned bad number of states.");
    for (size_t i = 0; i < nextStatesSize; ++i) {
        nextStates.push_back(PyList_GetItem(pyResponse, i));
    }
}

void NMT_Wrapper::GetNextLogProbStates(
    const std::vector<std::string>& nextWords,
    PyObject* pyContextVectors,
    const std::vector< std::string >& lastWords,
    std::vector<PyObject*>& inputStates,
    std::vector<double>& logProbs,
    std::vector<PyObject*>& nextStates)
{
    std::vector<bool> unks;
    GetNextLogProbStates(nextWords,
                         pyContextVectors,
                         lastWords,
                         inputStates,
                         logProbs,
                         nextWords,
                         unks);
}

void NMT_Wrapper::GetNextLogProbStates(
    const std::vector<std::string>& nextWords,
    PyObject* pyContextVectors,
    const std::vector< std::string >& lastWords,
    std::vector<PyObject*>& inputStates,
    std::vector<double>& logProbs,
    std::vector<PyObject*>& nextStates,
    std::vector<bool>& unks)
{
    UTIL_THROW_IF2(lastWords.size() != inputStates.size(), "#lastWords != #inputStates");

    PyObject* pyNextWords = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyNextWords, PyString_FromString(nextWords[i].c_str()));
    }

    PyObject* pyLastWords = PyList_New(0);
    for (size_t i = 0; i < lastWords.size(); ++i) {
        PyList_Append(pyLastWords, PyString_FromString(lastWords[i].c_str()));
    }

    PyObject* pyResponse = NULL;
    PyObject* pyStates = PyList_New(0);
    for (size_t i = 0; i < inputStates.size(); ++i) {
        PyList_Append(pyStates, inputStates[i]);
    }
    if (inputStates.size() == 0) {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_log_prob_states,
                                                pyNextWords,
                                                pyContextVectors,
                                                NULL);
    } else {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_log_prob_states,
                                                pyNextWords,
                                                pyContextVectors,
                                                pyLastWords,
                                                pyStates,
                                                NULL);
    }
    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    size_t inputSize = 0;
    if (inputStates.size() == 0) {
        inputSize = 1;
    } else {
        inputSize = inputStates.size();
    }

    PyObject* pyLogProbs = PyTuple_GetItem(pyResponse, 0);
    PyObject* pyNextStates = PyTuple_GetItem(pyResponse, 1);
    logProbs.clear();
    nextStates.clear();

    for (size_t j = 0; j < inputSize; ++j) {
        logProbs.push_back(PyFloat_AsDouble(PyList_GetItem(pyLogProbs, j)));
    }
    for (size_t i = 0; i < inputSize; ++i) {
        PyObject* nextState = PyList_GetItem(pyNextStates, i);
        if (nextState == NULL) cerr << "NULL OUTOUT" << endl;
        nextStates.push_back(nextState);
    }
    unks = IsUnk(nextWords);
}
<commit_msg>Repair isUNK<commit_after>#include "NMT_Wrapper.h"

#include "util/exception.hh"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <streambuf>
#include <assert.h>

#include <python2.7/Python.h>

using namespace std;
using namespace util;

NMT_Wrapper* NMT_Wrapper::s_nmt;

NMT_Wrapper::NMT_Wrapper()
{
    py_get_log_prob = PyString_FromString((char*)"get_log_prob");
    py_get_log_probs = PyString_FromString((char*)"get_log_probs");
    py_get_vec_log_probs = PyString_FromString((char*)"get_vec_log_probs");
    py_get_context_vectors = PyString_FromString((char*)"get_context_vector");
    py_get_next_states = PyString_FromString((char*)"get_next_states");
    py_get_log_prob_states = PyString_FromString((char*)"get_log_prob_states");

    SetNMT(this);
}

NMT_Wrapper::~NMT_Wrapper () {
    Py_Finalize();
}

void NMT_Wrapper::LoadTargetVocab()
{
    PyObject* py_response = PyObject_CallMethodObjArgs(
                                py_wrapper,
                                PyString_FromString("get_target_vocab"),
                                NULL);
    const size_t vocabSize = PyList_Size(py_response);
    for (size_t i = 0; i < vocabSize; ++i) {
        m_targetVocab.insert(PyString_AsString(PyList_GetItem(py_response, i)));
    }
}

std::vector<bool> NMT_Wrapper::IsUnk(const std::vector<std::string>& words)
{
    std::vector<bool> isUnk(words.size());
    for (size_t i = 0; i < words.size(); ++i) {
        if(m_targetVocab.find(words[i]) != m_targetVocab.end()) {
            isUnk[i] = true;
        } else {
            isUnk[i] = false;
        }
    }
    return isUnk;
}

bool NMT_Wrapper::GetContextVectors(const string& source_sentence, PyObject*& vectors)
{
    PyObject* py_source_sentence = PyString_FromString(source_sentence.c_str());
    vectors = PyObject_CallMethodObjArgs(py_wrapper, py_get_context_vectors, py_source_sentence, NULL);
    return true;
}

void NMT_Wrapper::AddPathToSys(const string& path)
{
    PyObject* py_sys_path = PySys_GetObject((char*)"path");
    PyList_Append(py_sys_path, PyString_FromString(path.c_str()));
}

void NMT_Wrapper::Init(
        const std::string& state_path,
        const std::string& model_path,
        const std::string& wrapper_path,
        const std::string& sourceVocabPath,
        const std::string& targetVocabPath)
{
    Py_Initialize();
    AddPathToSys(wrapper_path);

    PyObject* filename = PyString_FromString((char*) "nmt_wrapper");
    PyObject* imp = PyImport_Import(filename);
    UTIL_THROW_IF2(imp == NULL, "The wrapper module could not be imported.");

    PyObject* wrapper_name = PyObject_GetAttrString(imp, (char*)"NMTWrapper");
    UTIL_THROW_IF2(wrapper_name == NULL, "It could not find NMTWrapper class.");

    PyObject* args = PyTuple_Pack(4,
            PyString_FromString(state_path.c_str()),
            PyString_FromString(model_path.c_str()),
            PyString_FromString(sourceVocabPath.c_str()),
            PyString_FromString(targetVocabPath.c_str()));

    py_wrapper = PyObject_CallObject(wrapper_name, args);
    UTIL_THROW_IF2(py_wrapper == NULL, "Problem with creating NMT_Wrapper.");

    UTIL_THROW_IF2(PyObject_CallMethod(py_wrapper, (char*)"build", NULL) == NULL,
            "Problem with build NMT_Wrapper");

    LoadTargetVocab();
}

bool NMT_Wrapper::GetProb(const string& next_word,
                          PyObject* py_context_vectors,
                          const string& last_word,
                          PyObject* input_state,
                          double& output_prob,
                          PyObject*& output_state)
{
    PyObject* py_next_word = PyString_FromString(next_word.c_str());
    PyObject* py_response = NULL;

    if (input_state == NULL)
    {
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_prob, py_next_word, py_context_vectors, NULL);
    }
    else {
        PyObject* py_last_word = PyString_FromString(last_word.c_str());
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_prob, py_next_word, py_context_vectors,
                                                 py_last_word, input_state, NULL);
    }

   if (py_response == NULL) { return false; }
    if (! PyTuple_Check(py_response)) { return false; }

    PyObject* py_prob = PyTuple_GetItem(py_response, 0);
    if (py_prob == NULL) { return false; }
    output_prob = PyFloat_AsDouble(py_prob);

    output_state = PyTuple_GetItem(py_response, 1);
    if (output_state == NULL) { return 0; }

    return true;
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& next_words,
                          PyObject* py_context_vectors,
                          const string& last_word,
                          PyObject* input_state,
                          double& logProb,
                          PyObject*& output_state)
{
    PyObject* py_nextWords = PyList_New(0);
    for (size_t i = 0; i < next_words.size(); ++i) {
        PyList_Append(py_nextWords, PyString_FromString(next_words[i].c_str()));
    }

    PyObject* py_response = NULL;

    if (input_state == NULL)
    {
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_probs,
                                                 py_nextWords, py_context_vectors, NULL);
    }
    else {
        PyObject* py_last_word = PyString_FromString(last_word.c_str());
        py_response = PyObject_CallMethodObjArgs(py_wrapper, py_get_log_probs, py_nextWords, py_context_vectors,
                                                 py_last_word, input_state, NULL);
    }

    if (py_response == NULL) { return false; }
    if (! PyTuple_Check(py_response)) { return false; }

    PyObject* py_prob = PyTuple_GetItem(py_response, 0);
    if (py_prob == NULL) { return false; }
    logProb = PyFloat_AsDouble(py_prob);

    output_state = PyTuple_GetItem(py_response, 1);
    if (output_state == NULL) { return 0; }

    return true;
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& nextWords,
                          PyObject* pyContextVectors,
                          const std::vector< string >& lastWords,
                          std::vector< PyObject* >& inputStates,
                          std::vector< std::vector< double > >& logProbs,
                          std::vector< std::vector< PyObject* > >& outputStates,
{
    std::vector<bool> unks;
    GetProb(nextWords,
            pyContextVectors,
            lastWords,
            inputStates,
            logProbs,
            outputStates,
            unks);
}

bool NMT_Wrapper::GetProb(const std::vector<std::string>& nextWords,
                          PyObject* pyContextVectors,
                          const std::vector< string >& lastWords,
                          std::vector< PyObject* >& inputStates,
                          std::vector< std::vector< double > >& logProbs,
                          std::vector< std::vector< PyObject* > >& outputStates,
                          std::vector<bool> unks)
{
    PyObject* pyNextWords = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyNextWords, PyString_FromString(nextWords[i].c_str()));
    }

    PyObject* pyLastWords = PyList_New(0);
    for (size_t i = 0; i < lastWords.size(); ++i) {
        PyList_Append(pyLastWords, PyString_FromString(lastWords[i].c_str()));
    }

    PyObject* pyResponse = NULL;
    if (inputStates.size() == 0) {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_vec_log_probs,
                                                pyNextWords,
                                                pyContextVectors,
                                                NULL);
    } else {
        PyObject* pyInputStates = PyList_New(0);
        for (size_t i = 0; i < inputStates.size(); ++i) {
            PyList_Append(pyInputStates, inputStates[i]);
        }

        PyObject* pyLastWords = PyList_New(0);
        for (size_t i = 0; i < lastWords.size(); ++i) {
            PyList_Append(pyLastWords, PyString_FromString(lastWords[i].c_str()));
        }

        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_vec_log_probs,
                                                pyNextWords,
                                                pyContextVectors,
                                                pyLastWords,
                                                pyInputStates,
                                                NULL);
    }
    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    size_t inputSize = 0;
    if (inputStates.size() == 0) {
        inputSize = 1;
    } else {
        inputSize = inputStates.size();
    }

    PyObject* pyLogProbMatrix = PyTuple_GetItem(pyResponse, 0);
    PyObject* pyOutputStateMatrix = PyTuple_GetItem(pyResponse, 1);
    logProbs.clear();
    outputStates = vector<vector<PyObject*> >(inputSize, vector<PyObject*>(nextWords.size(), NULL));
    vector<double> hipoProbs;
    vector<PyObject*> hipoStates;
    logProbs.clear();
    for (size_t i = 0; i < inputSize; ++i) {
        hipoProbs.clear();
        hipoStates.clear();

        PyObject* pyLogProbColumn = PyList_GetItem(pyLogProbMatrix, i);
        for (size_t j = 0; j < nextWords.size(); ++j) {
            hipoProbs.push_back(PyFloat_AsDouble(PyList_GetItem(pyLogProbColumn, j)));
        }
        logProbs.push_back(hipoProbs);
    }

    for (size_t j = 0; j < nextWords.size(); ++j) {
        PyObject* pyOutputStateColumn = PyList_GetItem(pyOutputStateMatrix, j);
        for (size_t i = 0; i < inputSize; ++i) {
            outputStates[i][j]  = PyList_GetItem(pyOutputStateColumn, i);
        }

        outputStates.push_back(hipoStates);
    }
    unks = IsUnk(nextWords);

    return true;
}
void NMT_Wrapper::GetNextStates(
        const std::vector<std::string>& nextWords,
        PyObject* pyContextVectors,
        std::vector<PyObject*>& inputStates,
        std::vector<PyObject*>& nextStates)
{
    UTIL_THROW_IF2(nextWords.size() != nextStates.size(), "#nextWords != #inputStates");
    UTIL_THROW_IF2(nextWords.size() == 0, "No hipothesis!");

    PyObject* pyNextWords = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyNextWords, PyString_FromString(nextWords[i].c_str()));
    }

    PyObject* pyInputStates = PyList_New(0);
    for (size_t i = 0; i < inputStates.size(); ++i) {
        PyList_Append(pyInputStates, inputStates[i]);
    }

    PyObject* pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                            py_get_next_states,
                                            pyNextWords,
                                            pyContextVectors,
                                            pyInputStates,
                                            NULL);

    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    nextStates.clear();
    size_t nextStatesSize = PyList_Size(pyResponse);
    UTIL_THROW_IF2(nextStatesSize != inputStates.size(), "Returned bad number of states.");
    for (size_t i = 0; i < nextStatesSize; ++i) {
        nextStates.push_back(PyList_GetItem(pyResponse, i));
    }
}

void NMT_Wrapper::GetNextLogProbStates(
    const std::vector<std::string>& nextWords,
    PyObject* pyContextVectors,
    const std::vector< std::string >& lastWords,
    std::vector<PyObject*>& inputStates,
    std::vector<double>& logProbs,
    std::vector<PyObject*>& nextStates)
{
    std::vector<bool> unks;
    GetNextLogProbStates(nextWords,
                         pyContextVectors,
                         lastWords,
                         inputStates,
                         logProbs,
                         nextWords,
                         unks);
}

inline PyObject* StringVector2Python(std::vector<std::string> inputVector)
{
    PyObject* pyList = PyList_New(0);
    for (size_t i = 0; i < nextWords.size(); ++i) {
        PyList_Append(pyList, PyString_FromString(inputVector[i].c_str()));
    }
    return pyList;
}

void NMT_Wrapper::GetNextLogProbStates(
    const std::vector<std::string>& nextWords,
    PyObject* pyContextVectors,
    const std::vector< std::string >& lastWords,
    std::vector<PyObject*>& inputStates,
    std::vector<double>& logProbs,
    std::vector<PyObject*>& nextStates,
    std::vector<bool>& unks)
{
    UTIL_THROW_IF2(lastWords.size() != inputStates.size(), "#lastWords != #inputStates");

    PyObject* pyNextWords = StringVector2Python(nextWords);
    PyObject* pyLastWords = StringVector2Python(lastWords);

    PyObject* pyStates = PyList_New(0);
    for (size_t i = 0; i < inputStates.size(); ++i) {
        PyList_Append(pyStates, inputStates[i]);
    }
    PyObject* pyResponse = NULL;

    if (inputStates.size() == 0) {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_log_prob_states,
                                                pyNextWords,
                                                pyContextVectors,
                                                NULL);
    } else {
        pyResponse = PyObject_CallMethodObjArgs(py_wrapper,
                                                py_get_log_prob_states,
                                                pyNextWords,
                                                pyContextVectors,
                                                pyLastWords,
                                                pyStates,
                                                NULL);
    }
    UTIL_THROW_IF2(pyResponse == NULL, "No response from python module.");

    size_t inputSize = 0;
    if (inputStates.size() == 0) {
        inputSize = 1;
    } else {
        inputSize = inputStates.size();
    }

    PyObject* pyLogProbs = PyTuple_GetItem(pyResponse, 0);
    PyObject* pyNextStates = PyTuple_GetItem(pyResponse, 1);
    logProbs.clear();
    nextStates.clear();

    for (size_t j = 0; j < inputSize; ++j) {
        logProbs.push_back(PyFloat_AsDouble(PyList_GetItem(pyLogProbs, j)));
    }
    for (size_t i = 0; i < inputSize; ++i) {
        PyObject* nextState = PyList_GetItem(pyNextStates, i);
        if (nextState == NULL) cerr << "NULL OUTOUT" << endl;
        nextStates.push_back(nextState);
    }
    unks = IsUnk(nextWords);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#pragma once

#include <cassert>
#include <limits>
#include <string>
#include <uavcan/stdint.hpp>
#include <uavcan/impl_constants.hpp>
#include <uavcan/util/compile_time.hpp>
#include <uavcan/marshal/bit_stream.hpp>

namespace uavcan
{

class UAVCAN_EXPORT ScalarCodec
{
    BitStream& stream_;

    static void swapByteOrder(uint8_t* bytes, unsigned len);

    template <unsigned BitLen, unsigned Size>
    static typename EnableIf<(BitLen > 8)>::Type
    convertByteOrder(uint8_t (&bytes)[Size])
    {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
        static const bool big_endian = BYTE_ORDER == BIG_ENDIAN;
#else
        union { long int l; char c[sizeof(long int)]; } u;
        u.l = 1;
        const bool big_endian = u.c[sizeof(long int) - 1] == 1;
#endif
        /*
         * I didn't have any big endian machine nearby, so big endian support wasn't tested yet.
         * It is likely to be OK anyway, so feel free to remove this assert() as needed.
         */
        assert(big_endian == false);
        if (big_endian)
        {
            swapByteOrder(bytes, Size);
        }
    }

    template <unsigned BitLen, unsigned Size>
    static typename EnableIf<(BitLen <= 8)>::Type
    convertByteOrder(uint8_t (&)[Size]) { }

    template <unsigned BitLen, typename T>
    static typename EnableIf<std::numeric_limits<T>::is_signed && ((sizeof(T) * 8) > BitLen)>::Type
    fixTwosComplement(T& value)
    {
        StaticAssert<std::numeric_limits<T>::is_integer>::check(); // Not applicable to floating point types
        if (value & (T(1) << (BitLen - 1)))                        // The most significant bit is set --> negative
        {
            value |= 0xFFFFFFFFFFFFFFFF & ~((T(1) << BitLen) - 1);
        }
    }

    template <unsigned BitLen, typename T>
    static typename EnableIf<!std::numeric_limits<T>::is_signed || ((sizeof(T) * 8) == BitLen)>::Type
    fixTwosComplement(T&) { }

    template <unsigned BitLen, typename T>
    static typename EnableIf<((sizeof(T) * 8) > BitLen)>::Type
    clearExtraBits(T& value)
    {
        value &= (T(1) << BitLen) - 1;  // Signedness doesn't matter
    }

    template <unsigned BitLen, typename T>
    static typename EnableIf<((sizeof(T) * 8) == BitLen)>::Type
    clearExtraBits(T&) { }

    template <unsigned BitLen, typename T>
    void validate()
    {
        StaticAssert<((sizeof(T) * 8) >= BitLen)>::check();
        StaticAssert<(BitLen <= BitStream::MaxBitsPerRW)>::check();
        StaticAssert<std::numeric_limits<T>::is_signed ? (BitLen > 1) : 1>::check();
    }

    int encodeBytesImpl(uint8_t* bytes, unsigned bitlen);
    int decodeBytesImpl(uint8_t* bytes, unsigned bitlen);

public:
    ScalarCodec(BitStream& stream)
        : stream_(stream)
    { }

    template <unsigned BitLen, typename T>
    int encode(const T value)
    {
        validate<BitLen, T>();
        union ByteUnion
        {
            T value;
            uint8_t bytes[sizeof(T)];
        } byte_union;
        byte_union.value = value;
        clearExtraBits<BitLen>(byte_union.value);
        convertByteOrder<BitLen>(byte_union.bytes);
        return encodeBytesImpl(byte_union.bytes, BitLen);
    }

    template <unsigned BitLen, typename T>
    int decode(T& value)
    {
        validate<BitLen, T>();
        union ByteUnion
        {
            T value;
            uint8_t bytes[sizeof(T)];
        } byte_union;
        byte_union.value = T();
        const int read_res = decodeBytesImpl(byte_union.bytes, BitLen);
        if (read_res > 0)
        {
            convertByteOrder<BitLen>(byte_union.bytes);
            fixTwosComplement<BitLen>(byte_union.value);
            value = byte_union.value;
        }
        return read_res;
    }
};

}
<commit_msg>Out of line methods for ScalarCodec<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#pragma once

#include <cassert>
#include <limits>
#include <string>
#include <uavcan/stdint.hpp>
#include <uavcan/impl_constants.hpp>
#include <uavcan/util/compile_time.hpp>
#include <uavcan/marshal/bit_stream.hpp>

namespace uavcan
{

class UAVCAN_EXPORT ScalarCodec
{
    BitStream& stream_;

    static void swapByteOrder(uint8_t* bytes, unsigned len);

    template <unsigned BitLen, unsigned Size>
    static typename EnableIf<(BitLen > 8)>::Type
    convertByteOrder(uint8_t (&bytes)[Size])
    {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
        static const bool big_endian = BYTE_ORDER == BIG_ENDIAN;
#else
        union { long int l; char c[sizeof(long int)]; } u;
        u.l = 1;
        const bool big_endian = u.c[sizeof(long int) - 1] == 1;
#endif
        /*
         * I didn't have any big endian machine nearby, so big endian support wasn't tested yet.
         * It is likely to be OK anyway, so feel free to remove this assert() as needed.
         */
        assert(big_endian == false);
        if (big_endian)
        {
            swapByteOrder(bytes, Size);
        }
    }

    template <unsigned BitLen, unsigned Size>
    static typename EnableIf<(BitLen <= 8)>::Type
    convertByteOrder(uint8_t (&)[Size]) { }

    template <unsigned BitLen, typename T>
    static typename EnableIf<std::numeric_limits<T>::is_signed && ((sizeof(T) * 8) > BitLen)>::Type
    fixTwosComplement(T& value)
    {
        StaticAssert<std::numeric_limits<T>::is_integer>::check(); // Not applicable to floating point types
        if (value & (T(1) << (BitLen - 1)))                        // The most significant bit is set --> negative
        {
            value |= 0xFFFFFFFFFFFFFFFF & ~((T(1) << BitLen) - 1);
        }
    }

    template <unsigned BitLen, typename T>
    static typename EnableIf<!std::numeric_limits<T>::is_signed || ((sizeof(T) * 8) == BitLen)>::Type
    fixTwosComplement(T&) { }

    template <unsigned BitLen, typename T>
    static typename EnableIf<((sizeof(T) * 8) > BitLen)>::Type
    clearExtraBits(T& value)
    {
        value &= (T(1) << BitLen) - 1;  // Signedness doesn't matter
    }

    template <unsigned BitLen, typename T>
    static typename EnableIf<((sizeof(T) * 8) == BitLen)>::Type
    clearExtraBits(T&) { }

    template <unsigned BitLen, typename T>
    void validate()
    {
        StaticAssert<((sizeof(T) * 8) >= BitLen)>::check();
        StaticAssert<(BitLen <= BitStream::MaxBitsPerRW)>::check();
        StaticAssert<std::numeric_limits<T>::is_signed ? (BitLen > 1) : 1>::check();
    }

    int encodeBytesImpl(uint8_t* bytes, unsigned bitlen);
    int decodeBytesImpl(uint8_t* bytes, unsigned bitlen);

public:
    ScalarCodec(BitStream& stream)
        : stream_(stream)
    { }

    template <unsigned BitLen, typename T>
    int encode(const T value);

    template <unsigned BitLen, typename T>
    int decode(T& value);
};

// ----------------------------------------------------------------------------

template <unsigned BitLen, typename T>
int ScalarCodec::encode(const T value)
{
    validate<BitLen, T>();
    union ByteUnion
    {
        T value;
        uint8_t bytes[sizeof(T)];
    } byte_union;
    byte_union.value = value;
    clearExtraBits<BitLen>(byte_union.value);
    convertByteOrder<BitLen>(byte_union.bytes);
    return encodeBytesImpl(byte_union.bytes, BitLen);
}

template <unsigned BitLen, typename T>
int ScalarCodec::decode(T& value)
{
    validate<BitLen, T>();
    union ByteUnion
    {
        T value;
        uint8_t bytes[sizeof(T)];
    } byte_union;
    byte_union.value = T();
    const int read_res = decodeBytesImpl(byte_union.bytes, BitLen);
    if (read_res > 0)
    {
        convertByteOrder<BitLen>(byte_union.bytes);
        fixTwosComplement<BitLen>(byte_union.value);
        value = byte_union.value;
    }
    return read_res;
}

}
<|endoftext|>


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

#include "XalanEXSLTDateTime.hpp"
#include "XalanEXSLTDateTimeImpl.hpp"

#include <ctime>
#include <cstdio>

#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>

#include <xalanc/XPath/XObjectFactory.hpp>

XALAN_CPP_NAMESPACE_BEGIN

static const XalanEXSLTFunctionDateTime			s_dateTimeFunction;

static const XalanDOMChar	s_dateTimeFunctionName[] =
{
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_e,
	0
};

static const XalanEXSLTDateTimeFunctionsInstaller::FunctionTableEntry	theFunctionTable[] =
{
	{ s_dateTimeFunctionName, &s_dateTimeFunction },
	{ 0, 0 }
};

static const XalanDOMChar	s_dateTimeNamespace[] =
{
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_t,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_d,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	0
};

#if defined(WIN32)
static struct tm *
localtime_r(const time_t *clock, struct tm *res)
{
	assert( res != 0 );

	struct tm * tmpTime = localtime(clock);

	if (tmpTime == 0 )
	{
		return 0;
	}
	else
	{
		*res = *tmpTime;

		return res;
	}

}

static struct tm *
gmtime_r(const time_t *clock, struct tm *res)
{
	assert( res != 0 );

	struct tm * tmpTime = gmtime(clock);

	if (tmpTime == 0 )
	{
		return 0;
	}
	else
	{
		*res = *tmpTime;

		return res;
	}

}

#endif // WIN32

XObjectPtr
XalanEXSLTFunctionDateTime::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	if (args.size() != 0)
	{
		executionContext.error(getError(), context, locator);
	}

	XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

	XalanDOMString&		theResult = theGuard.get();

	theResult.clear();

#if defined(XALAN_STRICT_ANSI_HEADERS)
	using std::localtime_r;
	using std::tm;
	using std::time_t;
	using std::time;
	using std::size_t;
	using std::strftime;
	using std::gmtime_r;
#endif

	time_t long_time;

	time( &long_time );

	struct tm localTime;

	const struct tm*	ptrStrctTime = localtime_r(&long_time, &localTime);

	if (ptrStrctTime != 0 )
	{
		struct tm gmtTime;

		ptrStrctTime = gmtime_r(&long_time, &gmtTime);

		if(ptrStrctTime != 0 )
		{

			const size_t	MAX_DATE_TIME_LEN = 1000;
			char stringTime[MAX_DATE_TIME_LEN + 1];

			const size_t	result = strftime(stringTime, MAX_DATE_TIME_LEN, "%Y-%m-%dT%H:%M:%S", ptrStrctTime);

			if (result != 0)
			{
				theResult.assign(stringTime);

				long localData = localTime.tm_year * 10000 + localTime.tm_mon * 100 + localTime.tm_mday;
				long gmtData = gmtTime.tm_year * 10000 + gmtTime.tm_mon * 100 + gmtTime.tm_mday;

				char timeZone[MAX_DATE_TIME_LEN+1];

				int offset = 0;

				if( localData == gmtData )
				{
					if(localTime.tm_hour == gmtTime.tm_hour)
					{
						offset = 100; //  much bigger then any legal offset
					}
					else
					{
						offset = localTime.tm_hour - gmtTime.tm_hour;
					}
				}
				else if(localData < gmtData)
				{
					offset = localTime.tm_hour - gmtTime.tm_hour - 24;
				}
				else
				{
					offset = localTime.tm_hour - gmtTime.tm_hour + 24;
				}

				if(offset == 100)
					sprintf(timeZone , "%s", "z");
				else
					sprintf(timeZone , "%2.2d:00",offset);

				theResult.append(timeZone);
			}
		}
	}

	return executionContext.getXObjectFactory().createString(theResult);
}

const XalanDOMString
XalanEXSLTFunctionDateTime::getError() const
{
		return XalanMessageLoader::getMessage(XalanMessages::EXSLTFunctionAcceptsOneArgument_1Param, s_dateTimeFunctionName);
}

void
XalanEXSLTDateTimeFunctionsInstaller::installLocal(XPathEnvSupportDefault&		theSupport)
{
	doInstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTDateTimeFunctionsInstaller::installGlobal()
{
	doInstallGlobal(s_dateTimeNamespace, theFunctionTable);

}

void
XalanEXSLTDateTimeFunctionsInstaller::uninstallLocal(XPathEnvSupportDefault&	theSupport)
{
	doUninstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTDateTimeFunctionsInstaller::uninstallGlobal()
{
	doUninstallGlobal(s_dateTimeNamespace, theFunctionTable);
}

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

#include "XalanEXSLTDateTime.hpp"
#include "XalanEXSLTDateTimeImpl.hpp"

#include <time.h>

#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>

#include <xalanc/XPath/XObjectFactory.hpp>

XALAN_CPP_NAMESPACE_BEGIN

static const XalanEXSLTFunctionDateTime			s_dateTimeFunction;

static const XalanDOMChar	s_dateTimeFunctionName[] =
{
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_e,
	0
};

static const XalanEXSLTDateTimeFunctionsInstaller::FunctionTableEntry	theFunctionTable[] =
{
	{ s_dateTimeFunctionName, &s_dateTimeFunction },
	{ 0, 0 }
};

static const XalanDOMChar	s_dateTimeNamespace[] =
{
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_t,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_d,
	XalanUnicode::charHyphenMinus,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_m,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_s,
	0
};

#if defined(WIN32)
static struct tm *
localtime_r(const time_t *clock, struct tm *res)
{
	assert( res != 0 );

	struct tm * tmpTime = localtime(clock);

	if (tmpTime == 0 )
	{
		return 0;
	}
	else
	{
		*res = *tmpTime;

		return res;
	}

}

static struct tm *
gmtime_r(const time_t *clock, struct tm *res)
{
	assert( res != 0 );

	struct tm * tmpTime = gmtime(clock);

	if (tmpTime == 0 )
	{
		return 0;
	}
	else
	{
		*res = *tmpTime;

		return res;
	}

}

#endif // WIN32

XObjectPtr
XalanEXSLTFunctionDateTime::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	if (args.size() != 0)
	{
		executionContext.error(getError(), context, locator);
	}

	XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

	XalanDOMString&		theResult = theGuard.get();

	theResult.clear();

	time_t long_time;

	time( &long_time );

	struct tm localTime;

	const struct tm*	ptrStrctTime = localtime_r(&long_time, &localTime);

	if (ptrStrctTime != 0 )
	{
		struct tm gmtTime;

		ptrStrctTime = gmtime_r(&long_time, &gmtTime);

		if(ptrStrctTime != 0 )
		{

			const size_t	MAX_DATE_TIME_LEN = 1000;
			char stringTime[MAX_DATE_TIME_LEN + 1];

			const size_t	result = strftime(stringTime, MAX_DATE_TIME_LEN, "%Y-%m-%dT%H:%M:%S", ptrStrctTime);

			if (result != 0)
			{
				theResult.assign(stringTime);

				long localData = localTime.tm_year * 10000 + localTime.tm_mon * 100 + localTime.tm_mday;
				long gmtData = gmtTime.tm_year * 10000 + gmtTime.tm_mon * 100 + gmtTime.tm_mday;

				char timeZone[MAX_DATE_TIME_LEN+1];

				int offset = 0;

				if( localData == gmtData )
				{
					if(localTime.tm_hour == gmtTime.tm_hour)
					{
						offset = 100; //  much bigger then any legal offset
					}
					else
					{
						offset = localTime.tm_hour - gmtTime.tm_hour;
					}
				}
				else if(localData < gmtData)
				{
					offset = localTime.tm_hour - gmtTime.tm_hour - 24;
				}
				else
				{
					offset = localTime.tm_hour - gmtTime.tm_hour + 24;
				}

				if(offset == 100)
					sprintf(timeZone , "%s", "z");
				else
					sprintf(timeZone , "%2.2d:00",offset);

				theResult.append(timeZone);
			}
		}
	}

	return executionContext.getXObjectFactory().createString(theResult);
}

const XalanDOMString
XalanEXSLTFunctionDateTime::getError() const
{
		return XalanMessageLoader::getMessage(XalanMessages::EXSLTFunctionAcceptsOneArgument_1Param, s_dateTimeFunctionName);
}

void
XalanEXSLTDateTimeFunctionsInstaller::installLocal(XPathEnvSupportDefault&		theSupport)
{
	doInstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTDateTimeFunctionsInstaller::installGlobal()
{
	doInstallGlobal(s_dateTimeNamespace, theFunctionTable);

}

void
XalanEXSLTDateTimeFunctionsInstaller::uninstallLocal(XPathEnvSupportDefault&	theSupport)
{
	doUninstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTDateTimeFunctionsInstaller::uninstallGlobal()
{
	doUninstallGlobal(s_dateTimeNamespace, theFunctionTable);
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>