text:
/*
 * Copyright (C) 2012 Open Source Robotics 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.
 *
 */

#ifdef _WIN32
  // Ensure that Winsock2.h is included before Windows.h, which can get
  // pulled in by anybody (e.g., Boost).
  #include <Winsock2.h>
  // For _access()
  #include <io.h>
#endif

#include <boost/filesystem.hpp>
#include <stdio.h>

#include "gazebo/common/CommonIface.hh"
#include "gazebo/common/SystemPaths.hh"
#include "gazebo/gui/DataLogger.hh"
#include "gazebo/gui/DataLoggerPrivate.hh"
#include "gazebo/msgs/msgs.hh"
#include "gazebo/transport/transport.hh"

using namespace gazebo;
using namespace gui;

/////////////////////////////////////////////////
DataLogger::DataLogger(QWidget *_parent)
  : QDialog(_parent),
    dataPtr(new DataLoggerPrivate())
{
  this->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
      Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);

  // This name is used in the qt style sheet
  this->setObjectName("dataLogger");
  this->setWindowIcon(QIcon(":/images/gazebo.svg"));
  this->setWindowTitle(tr("Gazebo: Data Logger"));
  this->setWindowFlags(Qt::Window | Qt::WindowCloseButtonHint |
      Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);

  // The record button allows the user to start and pause data recording
  this->dataPtr->recordButton = new QToolButton(this);
  this->dataPtr->recordButton->setIcon(QPixmap(":/images/record.png"));
  this->dataPtr->recordButton->setStatusTip(tr("Record a log file"));
  this->dataPtr->recordButton->setCheckable(true);
  this->dataPtr->recordButton->setChecked(false);
  this->dataPtr->recordButton->setIconSize(QSize(30, 30));
  this->dataPtr->recordButton->setObjectName("dataLoggerRecordButton");
  connect(this->dataPtr->recordButton, SIGNAL(toggled(bool)),
          this, SLOT(OnRecord(bool)));

  // Textual status information
  this->dataPtr->statusLabel = new QLabel("Ready");
  this->dataPtr->statusLabel->setObjectName("dataLoggerStatusLabel");
  this->dataPtr->statusLabel->setStyleSheet(
      "QLabel{padding-left: 14px; padding-top: 9px}");

  // Duration of logging
  this->dataPtr->timeLabel = new QLabel("00:00:00.000");
  this->dataPtr->timeLabel->setObjectName("dataLoggerTimeLabel");
  this->dataPtr->timeLabel->setFixedWidth(90);

  // Size of log file
  this->dataPtr->sizeLabel = new QLabel("(0.00 B)");
  this->dataPtr->sizeLabel->setObjectName("dataLoggerSizeLabel");

  // Horizontal separator
  QFrame *separator = new QFrame();
  separator->setFrameShape(QFrame::HLine);
  separator->setLineWidth(1);
  separator->setFixedHeight(30);

  // Address label
  QLabel *uriLabel = new QLabel("Address: ");
  uriLabel->setStyleSheet(
      "QLabel {color: #aeaeae; font-size: 11px; background: transparent}");

  this->dataPtr->recordResourcesBox = new QCheckBox("Record model resources");
  this->dataPtr->recordResourcesBox->setChecked(false);
  connect(this->dataPtr->recordResourcesBox, SIGNAL(clicked(bool)), this,
    SLOT(OnRecordResources(bool)));
  this->dataPtr->recordResourcesBox->setStyleSheet(
    "QCheckBox {color: #aeaeae; font-size: 11px; background: transparent}");

  // Address URI Line Edit
  this->dataPtr->destURI = new QLineEdit;
  this->dataPtr->destURI->setReadOnly(true);
  this->dataPtr->destURI->setObjectName("dataLoggerDestnationURILabel");
  this->dataPtr->destURI->setStyleSheet(
      "QLineEdit {color: #aeaeae; font-size: 11px; background: transparent}");

  // "Save to" label
  QLabel *pathLabel = new QLabel("Save to: ");
  pathLabel->setStyleSheet(
      "QLabel {\
         color: #aeaeae;\
         font-size: 11px;\
         background: transparent;\
         padding-top: 4px;\
       }");

  // Destination path Text Edit
  this->dataPtr->destPath = new QPlainTextEdit();
  this->dataPtr->destPath->setObjectName("dataLoggerDestnationPathLabel");
  this->dataPtr->destPath->setMinimumWidth(200);
  this->dataPtr->destPath->setMaximumHeight(50);
  this->dataPtr->destPath->setReadOnly(true);
  this->dataPtr->destPath->setFrameStyle(QFrame::NoFrame);
  this->dataPtr->destPath->setLineWrapMode(QPlainTextEdit::WidgetWidth);
  this->dataPtr->destPath->setWordWrapMode(QTextOption::WrapAnywhere);
  this->dataPtr->destPath->setStyleSheet(
      "QPlainTextEdit {\
         color: #aeaeae;\
         font-size: 11px;\
         background: transparent;\
       }");

  // Browser button
  QPushButton *browseButton = new QPushButton("Browse");
  browseButton->setFixedWidth(100);
  browseButton->setFocusPolicy(Qt::NoFocus);
  connect(browseButton, SIGNAL(clicked()), this, SLOT(OnBrowse()));

  // Button which toggles recordings
  QRadioButton *recordingsButton = new QRadioButton();
  recordingsButton->setChecked(false);
  recordingsButton->setFocusPolicy(Qt::NoFocus);
  recordingsButton->setText("Recordings");
  recordingsButton->setStyleSheet(
     "QRadioButton {\
        color: #d0d0d0;\
      }\
      QRadioButton::indicator::unchecked {\
        image: url(:/images/right_arrow.png);\
      }\
      QRadioButton::indicator::checked {\
        image: url(:/images/down_arrow.png);\
      }");
  connect(recordingsButton, SIGNAL(toggled(bool)), this,
      SLOT(OnToggleSettings(bool)));

  // Insert widgets in the top layout
  QGridLayout *topLayout = new QGridLayout();
  topLayout->addWidget(this->dataPtr->recordButton, 0, 0, 2, 1);
  topLayout->addWidget(this->dataPtr->statusLabel, 0, 1, 2, 2);
  topLayout->addWidget(this->dataPtr->timeLabel, 0, 3);
  topLayout->addWidget(this->dataPtr->sizeLabel, 1, 3);
  topLayout->addWidget(separator, 2, 0, 1, 4);
  topLayout->addWidget(this->dataPtr->recordResourcesBox, 3, 0, 1, 4);
  topLayout->addWidget(uriLabel, 4, 0);
  topLayout->addWidget(this->dataPtr->destURI, 4, 1, 1, 3);
  topLayout->addWidget(pathLabel, 5, 0);
  topLayout->addWidget(this->dataPtr->destPath, 5, 1, 1, 2);
  topLayout->addWidget(browseButton, 5, 3);
  topLayout->addWidget(recordingsButton, 6, 0, 1, 4);

  // Align widgets within layout
  topLayout->setAlignment(this->dataPtr->recordResourcesBox, Qt::AlignLeft);
  topLayout->setAlignment(pathLabel, Qt::AlignTop | Qt::AlignRight);
  topLayout->setAlignment(browseButton, Qt::AlignTop);
  topLayout->setAlignment(this->dataPtr->destURI, Qt::AlignLeft);
  topLayout->setAlignment(this->dataPtr->destPath, Qt::AlignLeft);
  topLayout->setAlignment(this->dataPtr->statusLabel, Qt::AlignLeft);
  topLayout->setAlignment(this->dataPtr->timeLabel, Qt::AlignRight);
  topLayout->setAlignment(this->dataPtr->sizeLabel,
      Qt::AlignRight | Qt::AlignTop);
  topLayout->setAlignment(uriLabel, Qt::AlignRight);

  // Put the layout in a widget to be able to control size
  QWidget *topWidget = new QWidget();
  topWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  topWidget->setLayout(topLayout);

  // List of recorded logs
  this->dataPtr->logList = new QTextBrowser(this);
  this->dataPtr->logList->setObjectName("dataLoggerRecordingsList");

  // Layout to hold the list
  QVBoxLayout *settingsLayout = new QVBoxLayout;
  settingsLayout->setContentsMargins(2, 2, 2, 2);
  settingsLayout->addWidget(this->dataPtr->logList);

  // Frame that can be hidden by toggling the expand button
  this->dataPtr->settingsFrame = new QFrame();
  this->dataPtr->settingsFrame->setObjectName("dataLoggerSettingFrame");
  this->dataPtr->settingsFrame->setLayout(settingsLayout);
  this->dataPtr->settingsFrame->setSizePolicy(QSizePolicy::Expanding,
      QSizePolicy::Expanding);
  this->dataPtr->settingsFrame->hide();

  // Mainlayout for the whole widget
  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
  mainLayout->addWidget(topWidget);
  mainLayout->addWidget(this->dataPtr->settingsFrame);

  // Assign the mainlayout to this widget
  this->setLayout(mainLayout);

  // Create a QueuedConnection to set time. This is used for thread safety.
  connect(this, SIGNAL(SetTime(QString)), this->dataPtr->timeLabel,
      SLOT(setText(QString)), Qt::QueuedConnection);

  // Create a QueuedConnection to set size. This is used for thread safety.
  connect(this, SIGNAL(SetSize(QString)), this->dataPtr->sizeLabel,
      SLOT(setText(QString)), Qt::QueuedConnection);

  // Create a QueuedConnection to set destination path.
  // This is used for thread safety.
  connect(this, SIGNAL(SetDestinationPath(QString)),
          this, SLOT(OnSetDestinationPath(QString)), Qt::QueuedConnection);

  // Create a QueuedConnection to set destination URI.
  // This is used for thread safety.
  connect(this, SIGNAL(SetDestinationURI(QString)),
          this, SLOT(OnSetDestinationURI(QString)), Qt::QueuedConnection);

  connect(this, SIGNAL(rejected()), this, SLOT(OnCancel()));

  // Timer used to blink the status label
  this->dataPtr->statusTimer = new QTimer();
  connect(this->dataPtr->statusTimer,
      SIGNAL(timeout()), this, SLOT(OnBlinkStatus()));
  this->dataPtr->statusTime = 0;

  // Timer used to hide the confirmation dialog
  this->dataPtr->confirmationDialog = NULL;
  this->dataPtr->confirmationTimer = new QTimer(this);
  connect(this->dataPtr->confirmationTimer, SIGNAL(timeout()), this,
      SLOT(OnConfirmationTimeout()));

  // Create a node from communication.
  this->dataPtr->node = transport::NodePtr(new transport::Node());
  this->dataPtr->node->TryInit(common::Time::Maximum());

  // Advertise on the log control topic. The server listens to log control
  // messages.
  this->dataPtr->pub =
      this->dataPtr->node->Advertise<msgs::LogControl>("~/log/control");

  // Subscribe to the log status topic. The server publishes log status
  // messages.
  this->dataPtr->sub = this->dataPtr->node->Subscribe<msgs::LogStatus>(
      "~/log/status",  &DataLogger::OnStatus, this);

  // Fill the path with the home folder - duplicated from util/LogRecord
#ifndef _WIN32
  const char *homePath = common::getEnv("HOME");
#else
  const char *homePath = common::getEnv("HOMEPATH");
#endif

  GZ_ASSERT(homePath, "HOME environment variable is missing");

  if (!homePath)
  {
    common::SystemPaths *paths = common::SystemPaths::Instance();
    this->dataPtr->basePath =
        QString::fromStdString(paths->TmpPath() + "/gazebo");
  }
  else
  {
    this->dataPtr->basePath =
        QString::fromStdString(boost::filesystem::path(homePath).string());
  }

  this->dataPtr->basePath = this->dataPtr->basePath + "/.gazebo/log/";
  this->SetDestinationPath(this->dataPtr->basePath);
}

/////////////////////////////////////////////////
DataLogger::~DataLogger()
{
  this->dataPtr->sub.reset();
  this->dataPtr->pub.reset();
  if (this->dataPtr->node)
    this->dataPtr->node->Fini();
  this->dataPtr->node.reset();
}

/////////////////////////////////////////////////
void DataLogger::OnRecord(bool _toggle)
{
  // If _toggle, then we should start logging data.
  if (_toggle)
  {
    // Switch the icon
    this->dataPtr->recordButton->setIcon(QPixmap(":/images/record_stop.png"));

    this->dataPtr->statusLabel->setText("Recording...");
    this->dataPtr->statusTimer->start(100);

    // Tell the server to start data logging
    msgs::LogControl msg;
    msg.set_start(true);
    this->dataPtr->pub->Publish(msg);
  }
  // Otherwise pause data logging
  else
  {
    // Switch the icon
    this->dataPtr->recordButton->setIcon(QPixmap(":/images/record.png"));

    // Display confirmation
    this->dataPtr->confirmationTimer->start(2000);
    QLabel *confirmationLabel = new QLabel("Saved to \n" +
        this->dataPtr->destPath->toPlainText());
    confirmationLabel->setObjectName("dataLoggerConfirmationLabel");
    QHBoxLayout *confirmationLayout = new QHBoxLayout();
    confirmationLayout->addWidget(confirmationLabel);

    if (this->dataPtr->confirmationDialog)
      this->dataPtr->confirmationDialog->close();
    this->dataPtr->confirmationDialog =
        new QDialog(this, Qt::FramelessWindowHint);
    this->dataPtr->confirmationDialog->setObjectName(
        "dataLoggerConfirmationDialog");
    this->dataPtr->confirmationDialog->setLayout(confirmationLayout);
    this->dataPtr->confirmationDialog->setStyleSheet(
        "QDialog {background-color: #eee}\
         QLabel {color: #111}");
    this->dataPtr->confirmationDialog->setModal(false);
    this->dataPtr->confirmationDialog->show();
    this->dataPtr->confirmationDialog->move(this->mapToGlobal(
        QPoint((this->width()-this->dataPtr->confirmationDialog->width())*0.5,
        this->height() + 10)));

    // Change the status
    this->dataPtr->statusLabel->setText("Ready");
    this->dataPtr->statusLabel->setStyleSheet(
        "QLabel {\
           color: #aeaeae;\
           padding-left: 14px;\
           padding-top: 9px;\
         }");
    this->dataPtr->statusTimer->stop();

    // Change the Save to box
    this->SetDestinationPath(this->dataPtr->basePath);

    // Tell the server to stop data logging
    msgs::LogControl msg;
    msg.set_stop(true);
    this->dataPtr->pub->Publish(msg);

    this->dataPtr->logList->append(this->dataPtr->destPath->toPlainText());
  }
}

/////////////////////////////////////////////////
void DataLogger::OnStatus(ConstLogStatusPtr &_msg)
{
  // A new log status message has arrived, let's display the contents.
  common::Time time = msgs::Convert(_msg->sim_time());
  std::ostringstream stream;

  // Compute the hours, minutes, seconds, and milliseconds that logging has
  // been running.
  unsigned int hours = time.sec / 3600;
  unsigned int min = (time.sec - hours * 3600) / 60;
  unsigned int sec = (time.sec - hours * 3600  - min * 60);
  unsigned int msec = rint(time.nsec * 1e-6);

  // Display the time.
  stream << std::setw(2) << std::setfill('0') << hours  << ":";
  stream << std::setw(2) << std::setfill('0') << min << ":";
  stream << std::setw(2) << std::setfill('0') << sec << ".";
  stream << std::setw(3) << std::setfill('0') << msec;

  this->SetTime(QString::fromStdString(stream.str()));

  // Reset the stream
  stream.str("");

  // If there is log file information in the message...
  if (_msg->has_log_file())
  {
    // If there is file name information and we're recording...
    if (_msg->log_file().has_base_path() &&
        this->dataPtr->recordButton->isChecked())
    {
      std::string logBasePath = _msg->log_file().base_path();

      // Display the log path
      if (_msg->log_file().has_full_path() && !logBasePath.empty())
      {
        std::string fullPath = _msg->log_file().full_path();
        if (!fullPath.empty())
          this->SetDestinationPath(QString::fromStdString(fullPath));
      }
    }

    // Display the URI
    if (_msg->log_file().has_uri())
      this->SetDestinationURI(QString::fromStdString(_msg->log_file().uri()));
    else
      this->SetDestinationURI(tr(""));

    // If there is log file size information...
    if (_msg->log_file().has_size() && _msg->log_file().has_size_units())
    {
      // Get the size of the log file.
      stream << std::fixed << std::setprecision(2) << "(" <<
          _msg->log_file().size();

      // Get the size units.
      switch (_msg->log_file().size_units())
      {
        case msgs::LogStatus::LogFile::BYTES:
          stream << "B)";
          break;
        case msgs::LogStatus::LogFile::K_BYTES:
          stream << "KB)";
          break;
        case msgs::LogStatus::LogFile::M_BYTES:
          stream << "MB)";
          break;
        default:
          stream << "GB)";
          break;
      }

      this->SetSize(QString::fromStdString(stream.str()));
    }
    else
      this->SetSize("(0.00 B)");
  }
}

/////////////////////////////////////////////////
void DataLogger::OnSetDestinationPath(QString _filename)
{
  if (!_filename.isEmpty())
    this->dataPtr->destPath->setPlainText(_filename);
}

/////////////////////////////////////////////////
void DataLogger::OnSetDestinationURI(QString _uri)
{
  if (!_uri.isEmpty())
    this->dataPtr->destURI->setText(_uri);
  else
    this->dataPtr->destURI->setText("");
}

/////////////////////////////////////////////////
void DataLogger::OnToggleSettings(bool _checked)
{
  if (_checked)
    this->dataPtr->settingsFrame->show();
  else
    this->dataPtr->settingsFrame->hide();
}

/////////////////////////////////////////////////
void DataLogger::OnRecordResources(bool _checked)
{
  msgs::LogControl msg;
  msg.set_record_resources(_checked);
  this->dataPtr->pub->Publish(msg);
}

/////////////////////////////////////////////////
void DataLogger::OnBrowse()
{
  QFileDialog fileDialog(this, tr("Set log directory"), QDir::homePath());
  fileDialog.setFileMode(QFileDialog::Directory);
  fileDialog.setFilter(QDir::AllDirs | QDir::Hidden);
  fileDialog.setOptions(QFileDialog::ShowDirsOnly
      | QFileDialog::DontResolveSymlinks);
  fileDialog.setWindowFlags(Qt::Window | Qt::WindowCloseButtonHint |
      Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);

  if (fileDialog.exec() != QDialog::Accepted)
    return;

  QStringList selected = fileDialog.selectedFiles();
  if (selected.empty())
    return;

  boost::filesystem::path path = selected[0].toStdString();

  // Make sure the  directory exists
  if (!boost::filesystem::exists(path))
  {
    QMessageBox msgBox(this);
    std::ostringstream stream;
    stream << "Directory " << path << " does not exist.";
    msgBox.setText(stream.str().c_str());
    msgBox.exec();
    return;
  }

  // Make sure we have a directory
  if (!boost::filesystem::is_directory(path))
  {
    QMessageBox msgBox(this);
    std::ostringstream stream;
    stream << "Path " << path << " is not a directory. Please only specify a "
           << "directory for data logging.";
    msgBox.setText(stream.str().c_str());
    msgBox.exec();
    return;
  }

  // Make sure the path is writable.
  // Note: This is not cross-platform compatible.
#ifdef _WIN32
  // Check for write-only (2) and read-write (6)
  if ((_access(path.string().c_str(), 2) != 0) &&
      (_access(path.string().c_str(), 6) != 0))
#else
  if (access(path.string().c_str(), W_OK) != 0)
#endif
  {
    QMessageBox msgBox(this);
    std::ostringstream stream;
    stream << "You do no have permission to write into " << path;
    msgBox.setText(stream.str().c_str());
    msgBox.exec();
    return;
  }

  // Set the new base path
  msgs::LogControl msg;
  msg.set_base_path(path.string());
  this->dataPtr->pub->Publish(msg);

  this->dataPtr->basePath = QString::fromStdString(path.string());
  this->SetDestinationPath(this->dataPtr->basePath);
}

/////////////////////////////////////////////////
void DataLogger::OnBlinkStatus()
{
  this->dataPtr->statusTime += 1.0/10;

  if (this->dataPtr->statusTime >= 1)
    this->dataPtr->statusTime = 0;

  this->dataPtr->statusLabel->setStyleSheet(QString::fromStdString(
      "QLabel{color: rgb("+
          std::to_string(255+(128*(this->dataPtr->statusTime-1)))+", "+
          std::to_string(255+(128*(this->dataPtr->statusTime-1)))+", "+
          std::to_string(255+(128*(this->dataPtr->statusTime-1)))+
      "); "+
      "padding-left: 15px; padding-top: 9px}"));
}

/////////////////////////////////////////////////
void DataLogger::OnConfirmationTimeout()
{
  this->dataPtr->confirmationDialog->close();
  this->dataPtr->confirmationTimer->stop();
}

/////////////////////////////////////////////////
void DataLogger::OnCancel()
{
  if (this->dataPtr->recordButton->isChecked())
    this->dataPtr->recordButton->click();
}


text:
//
//  ExporterGLTF.cpp
//  Kuplung
//
//  Created by Sergey Petrov on 07/08/17.
//  Copyright © 2017 supudo.net. All rights reserved.
//

#include "ExporterGLTF.hpp"
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include "kuplung/meshes/scene/ModelFaceData.hpp"
#include "kuplung/utilities/cpp-base64/base64.h"
#include <glm/gtx/string_cast.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

namespace KuplungApp { namespace Utilities { namespace Export {

ExporterGLTF::~ExporterGLTF() {
}

void ExporterGLTF::init(const std::function<void(float)>& doProgress) {
  this->funcProgress = doProgress;
  this->addSuffix = false;
#ifdef _WIN32
  this->nlDelimiter = "\r\n";
#elif defined macintosh // OS 9
  this->nlDelimiter = "\r";
#else
  this->nlDelimiter = "\n";
#endif

  this->exportFileFolder = "";
  this->parserUtils = std::make_unique<ParserUtils>();
	this->gltfGenerator = "Kuplung (https://github.com/supudo/Kuplung)";
	this->defaultSceneName = "KuplungScene";
	this->defaultMaterialName = "KuplungMaterial";
	this->gltfVersion = "2.0";
	this->BufferInExternalFile = false;
}

void ExporterGLTF::exportToFile(const FBEntity& file, const std::vector<ModelFaceBase*>& faces, const std::vector<std::string>& settings, std::unique_ptr<ObjectsManager> &managerObjects) {
	this->exportFile = file;
	this->objSettings = settings;

	this->prepFolderLocation();

	nlohmann::json j;
	j["asset"] = { { "generator", this->gltfGenerator }, { "version", this->gltfVersion } };
	j["scene"] = 0;
	j["cameras"] = this->exportCameras(managerObjects);

	std::string meshNameSuffix = "_mesh";
	std::string suffix_Indices = "_indices";
	std::string suffix_Vertices = "_vertices";
	std::string suffix_Normals = "_normals";
	std::string suffix_UVs = "_uvs";
	std::string meshAccessorSuffix_Indices = meshNameSuffix + "_accessor" + suffix_Indices;
	std::string meshAccessorSuffix_Vertices = meshNameSuffix + "_accessor" + suffix_Vertices;
	std::string meshAccessorSuffix_Normals = meshNameSuffix + "_accessor" + suffix_Normals;
	std::string meshAccessorSuffix_UVs = meshNameSuffix + "_accessor" + suffix_UVs;
	std::string bufferViewSuffix = "_view";

	nlohmann::json jBufferViews, jAccessors, jBuffers, jMaterials, jNodes, jScenes, jMeshes;
	int totalBufferLength = 0, meshCounter = 0, nodeCounter = 0;
	int currentBufferCounter = 0, currentAccessorCounter = 0, currentMaterialCounter = 0;
	std::string bufferData;
	std::vector<ModelFaceBase*>::const_iterator faceIterator;

	jScenes.push_back(
		{
			{ "name", this->defaultSceneName }
		}
	);

	for (faceIterator = faces.begin(); faceIterator != faces.end(); ++faceIterator) {
		const ModelFaceBase& face = **faceIterator;
		MeshModel model = face.meshModel;
		MeshModelMaterial mat = model.ModelMaterial;
		std::string modelTitleLocal = model.ModelTitle + "_" + std::to_string(meshCounter);

		// ---------------------------------------------------------
		// scenes
		jScenes[0]["nodes"].push_back(nodeCounter);

		// ---------------------------------------------------------
		// nodes
		jNodes.push_back({
			{ "mesh", meshCounter },
			{ "name", modelTitleLocal },
			{ "translation", { face.positionX->point, face.positionY->point, face.positionZ->point } },
			{ "rotation", { face.rotateX->point, face.rotateY->point, face.rotateZ->point } },
		});

		// ---------------------------------------------------------
		// materials
		jMaterials.push_back(
			{
				{ "name", model.MaterialTitle },
				{ "values",
					{
						{ "ambient", { face.materialAmbient->color.r, face.materialAmbient->color.g, face.materialAmbient->color.b, face.Setting_Alpha } },
						{ "diffuse", { face.materialDiffuse->color.r, face.materialDiffuse->color.g, face.materialDiffuse->color.b, face.Setting_Alpha } },
						{ "specular", { face.materialSpecular->color.r, face.materialSpecular->color.g, face.materialSpecular->color.b, face.Setting_Alpha } },
						{ "emission", { face.materialEmission->color.r, face.materialEmission->color.g, face.materialEmission->color.b, face.Setting_Alpha } },
						{ "shininess", 0.0f },
					}
				}
			}
		);

		// ---------------------------------------------------------
		// images
		if (!mat.TextureAmbient.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureAmbient.Image));
		if (!mat.TextureBump.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureBump.Image));
		if (!mat.TextureDiffuse.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureDiffuse.Image));
		if (!mat.TextureDisplacement.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureDisplacement.Image));
		if (!mat.TextureDissolve.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureDissolve.Image));
		if (!mat.TextureSpecular.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureSpecular.Image));
		if (!mat.TextureSpecularExp.Image.empty())
			j["images"].push_back(this->copyImage(mat.TextureSpecularExp.Image));

		// ---------------------------------------------------------
		// buffer views
		// indices
		jBufferViews.push_back(
			{
				{ "name", modelTitleLocal + bufferViewSuffix + suffix_Indices },
				{ "buffer", 0 },
				{ "byteOffset", totalBufferLength},
				{ "byteLength", model.indices.size() },
				{ "target", 34963 }
			}
		);
		// vertices
		jBufferViews.push_back(
			{
				{ "name", modelTitleLocal + bufferViewSuffix + suffix_Vertices },
				{ "buffer", 0 },
				{ "byteOffset", totalBufferLength + model.indices.size() + 1 },
				{ "byteLength", model.vertices.size() * 3 * sizeof(float) },
				{ "target", 34962 }
			}
		);
		// normals
		jBufferViews.push_back(
			{
				{ "name", modelTitleLocal + bufferViewSuffix + suffix_Normals },
				{ "buffer", 0 },
				{ "byteOffset", totalBufferLength + model.indices.size() + (model.vertices.size() * 3 * sizeof(float)) + 1 },
				{ "byteLength", model.normals.size() * 3 * sizeof(float) },
				{ "target", 34962 }
			}
		);
		// uvs
		if (model.texture_coordinates.size() > 0)
			jBufferViews.push_back(
				{
					{ "name", modelTitleLocal + bufferViewSuffix + suffix_Normals },
					{ "buffer", 0 },
					{ "byteOffset", totalBufferLength + model.indices.size() + (model.vertices.size() * 3 * sizeof(float)) + (model.normals.size() * 3 * sizeof(float)) + 1 },
					{ "byteLength", model.texture_coordinates.size() },
					{ "target", "34962" }
				}
			);

		// ---------------------------------------------------------
		// accessors
		// indices
		jAccessors.push_back(
			{
				{ "name", modelTitleLocal + meshAccessorSuffix_Indices },
				{ "bufferView", currentBufferCounter },
				{ "byteOffset", 0 },
				{ "componentType", 5125 },
				{ "count", model.indices.size() },
				{ "type", "SCALAR" },
				{ "min", { *std::min_element(model.indices.begin(), model.indices.end()) } },
				{ "max", { *std::max_element(model.indices.begin(), model.indices.end()) } }
			}
		);
		currentBufferCounter += 1;
		// vertices
		float min_vertex_x = (*std::min_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.x < b.x); })).x;
		float min_vertex_y = (*std::min_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.y < b.y); })).y;
		float min_vertex_z = (*std::min_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.z < b.z); })).z;
		float max_vertex_x = (*std::max_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.x < b.x); })).x;
		float max_vertex_y = (*std::max_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.y < b.y); })).y;
		float max_vertex_z = (*std::max_element(model.vertices.begin(), model.vertices.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.z < b.z); })).z;
		jAccessors.push_back(
			{
				{ "name", modelTitleLocal + meshAccessorSuffix_Vertices },
				{ "bufferView", currentBufferCounter },
				{ "byteOffset", 0 },
				{ "componentType", 5126 },
				{ "count", model.vertices.size() },
				{ "type", "VEC3" },
				{ "min", { min_vertex_x, min_vertex_y, min_vertex_z } },
				{ "max", { max_vertex_x, max_vertex_y, max_vertex_z } }
			}
		);
		currentBufferCounter += 1;
		// normals
		float min_normal_x = (*std::min_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.x < b.x); })).x;
		float min_normal_y = (*std::min_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.y < b.y); })).y;
		float min_normal_z = (*std::min_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.z < b.z); })).z;
		float max_normal_x = (*std::max_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.x < b.x); })).x;
		float max_normal_y = (*std::max_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.y < b.y); })).y;
		float max_normal_z = (*std::max_element(model.normals.begin(), model.normals.end(), [](const glm::vec3& a, const glm::vec3& b) { return (a.z < b.z); })).z;
		jAccessors.push_back(
			{
				{ "name", modelTitleLocal + meshAccessorSuffix_Normals },
				{ "bufferView", currentBufferCounter },
				{ "byteOffset", 0 },
				{ "componentType", 5126 },
				{ "count", model.normals.size() },
				{ "type", "VEC3" },
				{ "min", { min_normal_x, min_normal_y, min_normal_z } },
				{ "max", { max_normal_x, max_normal_y, max_normal_z } }
			}
		);
		currentBufferCounter += 1;
		// uvs
		if (model.texture_coordinates.size() > 0) {
			float min_uv_s = (*std::min_element(model.texture_coordinates.begin(), model.texture_coordinates.end(), [](const glm::vec2& a, const glm::vec2& b) { return (a.s < b.s); })).s;
			float min_uv_t = (*std::min_element(model.texture_coordinates.begin(), model.texture_coordinates.end(), [](const glm::vec2& a, const glm::vec2& b) { return (a.t < b.t); })).t;
			float max_uv_s = (*std::max_element(model.texture_coordinates.begin(), model.texture_coordinates.end(), [](const glm::vec2& a, const glm::vec2& b) { return (a.s < b.s); })).s;
			float max_uv_t = (*std::max_element(model.texture_coordinates.begin(), model.texture_coordinates.end(), [](const glm::vec2& a, const glm::vec2& b) { return (a.t < b.t); })).t;
			jAccessors.push_back(
				{
					{ "name", modelTitleLocal + meshAccessorSuffix_UVs },
					{ "bufferView", currentBufferCounter },
					{ "byteOffset", 0 },
					{ "componentType", 5126 },
					{ "count", model.texture_coordinates.size() },
					{ "type", "VEC2" },
					{ "min", { min_uv_s, min_uv_t } },
					{ "max", { max_uv_s, max_uv_t } }
				}
			);
			currentBufferCounter += 1;
		}

		// ---------------------------------------------------------
		// buffers
		int base64_size_indices = model.indices.size() * sizeof(unsigned int);
		int base64_size_vertices = model.vertices.size() * sizeof(glm::vec3);
		int base64_size_normals = model.normals.size() * sizeof(glm::vec3);
		int base64_size_textureCoordinates = model.texture_coordinates.size() * sizeof(glm::vec2);

		std::string base64_indices = "";
		std::string base64_vertices = "";
		std::string base64_normals = "";
		std::string base64_textureCoordinates = "";

		std::vector<unsigned char> buffer_data;
		for (std::vector<unsigned int>::iterator it = model.indices.begin(); it != model.indices.end(); ++it) {
			buffer_data.push_back(static_cast<unsigned char>(*it));
			buffer_data.push_back(static_cast<unsigned char>(*it));
		}

		for (std::vector<glm::vec3>::iterator it = model.vertices.begin(); it != model.vertices.end(); ++it) {
			buffer_data.push_back(static_cast<unsigned char>((*it).x));
			buffer_data.push_back(static_cast<unsigned char>((*it).y));
			buffer_data.push_back(static_cast<unsigned char>((*it).z));
		}

		for (std::vector<glm::vec3>::iterator it = model.normals.begin(); it != model.normals.end(); ++it) {
			buffer_data.push_back(static_cast<unsigned char>((*it).x));
			buffer_data.push_back(static_cast<unsigned char>((*it).y));
			buffer_data.push_back(static_cast<unsigned char>((*it).z));
		}

		if (model.texture_coordinates.size() > 0) {
			for (std::vector<glm::vec2>::iterator it = model.texture_coordinates.begin(); it != model.texture_coordinates.end(); ++it) {
				buffer_data.push_back(static_cast<unsigned char>((*it).x));
				buffer_data.push_back(static_cast<unsigned char>((*it).y));
			}
		}

		buffer_data.push_back('\0');

		// misc
		totalBufferLength += base64_size_indices + base64_size_vertices + base64_size_normals + base64_size_textureCoordinates;
		bufferData = base64_encode(&*buffer_data.begin(), totalBufferLength);

		// ---------------------------------------------------------
		// meshes
		nlohmann::json jMesh;
		jMesh["name"] = modelTitleLocal + meshNameSuffix;
		if (model.texture_coordinates.size() > 0) {
			jMesh["primitives"] = {
				{ "mode", 4 },
				{ "material", currentMaterialCounter },
				{ "indices", currentAccessorCounter + 0 },
				{ "attributes",
					{
						{ "POSITION", currentAccessorCounter + 1 },
						{ "NORMAL", currentAccessorCounter + 2 },
						{ "TEXCOORD_0", currentAccessorCounter + 3 }
					}
				}
			};
			currentAccessorCounter += 4;
		}
		else {
			jMesh["primitives"].push_back({
				{ "mode", 4 },
				{ "material", currentMaterialCounter },
				{ "indices", currentAccessorCounter + 0 },
				{ "attributes",
					{
						{ "POSITION", currentAccessorCounter + 1 },
						{ "NORMAL", currentAccessorCounter + 2 }
					}
				}
			});
			currentAccessorCounter += 3;
		}
		currentMaterialCounter += 1;
		jMeshes.push_back(jMesh);

		meshCounter += 1;
		nodeCounter += 1;
	}

	if (!this->BufferInExternalFile) {
		jBuffers.push_back(
			{
				{ "name", this->defaultSceneName + "_buffer" },
				{ "byteLength", totalBufferLength },
				{ "uri", "data:application/octet-stream;base64," + bufferData }
			}
		);
	}

	j["scenes"] = jScenes;
	j["buffers"] = jBuffers;
	j["bufferViews"] = jBufferViews;
	j["accessors"] = jAccessors;
	j["materials"] = jMaterials;
	j["nodes"] = jNodes;
	j["meshes"] = jMeshes;

	if (this->BufferInExternalFile) {
		j["buffers"]["byteLength"] = totalBufferLength;
		j["buffers"]["uri"] = this->exportFileFolder + "/" + this->exportFile.title + ".gltf.bin";
		if (!this->saveBufferFile(bufferData))
			Settings::Instance()->funcDoLog("[Kuplung] Error occured while writing the BIN glTF file!");
	}

  if (!this->saveFile(j))
    Settings::Instance()->funcDoLog("[Kuplung] Could not save glTF file!");
}

const nlohmann::json ExporterGLTF::exportCameras(std::unique_ptr<ObjectsManager> &managerObjects) const {
  nlohmann::json j;
  nlohmann::json viewportCamera;
  viewportCamera["type"] = "perspective";
  viewportCamera["perspective"] = {
    { "aspectRatio", managerObjects->Setting_RatioWidth / managerObjects->Setting_RatioHeight },
    { "yfov", managerObjects->Setting_FOV },
    { "zfar", managerObjects->Setting_PlaneFar },
    { "znear", managerObjects->Setting_PlaneClose }
  };
  j.push_back(viewportCamera);
  return j;
}

const nlohmann::json ExporterGLTF::exportScenes(const std::vector<ModelFaceBase*>& faces) const {
  nlohmann::json j;
	std::vector<ModelFaceBase*>::const_iterator faceIterator;
	for (faceIterator = faces.begin(); faceIterator != faces.end(); ++faceIterator) {
		const ModelFaceBase& face = **faceIterator;
		MeshModel model = face.meshModel;
		j[this->defaultSceneName]["nodes"][faceIterator - faces.begin()] = model.ModelTitle;
	}
  return j;
}

const nlohmann::json ExporterGLTF::copyImage(std::string imagePath) const {
    nlohmann::json j;
    std::string imageFilename = imagePath.substr(imagePath.find_last_of("\\/"));
    boost::replace_all(imageFilename, "/", "");
    std::string newImagePath = this->exportFile.path.substr(0, this->exportFile.path.find_last_of("\\/")) + "/" + this->exportFile.title + "/" + imageFilename;
    boost::filesystem::copy_file(imagePath, newImagePath, boost::filesystem::copy_options::overwrite_existing);
    j["uri"] = imageFilename;
    return j;
}

void ExporterGLTF::prepFolderLocation() {
  std::string folder = this->exportFile.path.substr(0, this->exportFile.path.find_last_of("\\/"));
  std::string newFolder = folder + "/" + this->exportFile.title;
  if (!boost::filesystem::exists(newFolder)) {
    boost::filesystem::path dir(newFolder);
    if (!boost::filesystem::create_directory(dir))
      Settings::Instance()->funcDoLog(Settings::Instance()->string_format("[ExportGLTF] Cannot create destination folder : %s!", newFolder.c_str()));
  }
  this->exportFileFolder = newFolder;
}

const bool ExporterGLTF::saveFile(const nlohmann::json& jsonObj) const {
  time_t t = time(0);
  const struct tm * now = localtime(&t);

  const int year = now->tm_year + 1900;
  const int month = now->tm_mon + 1;
  const int day = now->tm_mday;
  const int hour = now->tm_hour;
  const int minute = now->tm_min;
  const int seconds = now->tm_sec;

  std::string fileSuffix = "_" +
    std::to_string(year) + std::to_string(month) + std::to_string(day) +
    std::to_string(hour) + std::to_string(minute) + std::to_string(seconds);

  if (!this->addSuffix)
    fileSuffix.clear();
  std::string filePath = this->exportFileFolder;
  std::string fileName = this->exportFile.title;
  if (boost::algorithm::ends_with(fileName, ".gltf"))
    fileName = fileName.substr(0, fileName.size() - 4);

  std::ofstream out(filePath + "/" + fileName + fileSuffix + ".gltf");
  if (out.is_open()) {
    out << std::setw(4) << jsonObj << std::endl;
    out.close();
  }

	return true;
}

const bool ExporterGLTF::saveBufferFile(std::string buffer) const {
	std::string file = this->exportFileFolder + "/" + this->exportFile.title + ".gltf.bin";

	auto f = fopen(file.c_str(), "wt");
	if (!f) {
		Settings::Instance()->funcDoLog("[Kuplung] Could not create glTF binary file!");
		return false;
	}

	uint32_t buffer_length = buffer.size();

	// 12-byte header
	// - magic
	uint32_t magic = 0x46546C67;
	if (!std::fwrite(&magic, 1, 1, f))
		return false;

	// - version
	uint32_t version = 2;
	if (!std::fwrite(&version, 1, 1, f))
		return false;

	// - length
	uint32_t length = 12 + buffer_length;
  if (!std::fwrite(&length, 1, 1, f)) {
    std::fclose(f);
    return false;
  }

  if (!std::fwrite(&buffer, buffer_length, 1, f)) {
    std::fclose(f);
    return false;
  }

	std::fclose(f);

	return true;
}

}}}

ext: cpp

max_stars_repo_name: supudo/Kuplung

max_issues_repo_name: supudo/Kuplung

max_forks_repo_name: supudo/Kuplung


text:
///////////////////////////////////////////////////////////////////////////////
//
// http://protoc.sourceforge.net/
//
// Copyright (C) 2014 Bjorn Reese <breese@users.sourceforge.net>
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////

#include <boost/test/unit_test.hpp>

#include <protoc/exceptions.hpp>
#include <protoc/output_vector.hpp>
#include <protoc/output_array.hpp>
#include <protoc/msgpack/writer.hpp>
#include <protoc/msgpack/detail/codes.hpp>

namespace format = protoc::msgpack;
namespace detail = format::detail;

template<std::size_t N>
struct test_array : public protoc::output_array<format::writer::value_type, N>
{
};

struct test_vector : public protoc::output_vector<format::writer::value_type>
{
};

BOOST_AUTO_TEST_SUITE(msgpack_writer_suite)

//-----------------------------------------------------------------------------
// Basic types
//-----------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(test_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.size(), 0);
}

BOOST_AUTO_TEST_CASE(test_null)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(), 1);

    format::writer::value_type expected[] = { detail::code_null };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_true)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(true), 1);

    format::writer::value_type expected[] = { detail::code_true };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_false)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(false), 1);

    format::writer::value_type expected[] = { detail::code_false };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_integer_zero)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(0), 1);

    format::writer::value_type expected[] = { 0x00 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_long_zero)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(0LL), 1);

    format::writer::value_type expected[] = { 0x00 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_float_zero)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(0.0f), 5);

    format::writer::value_type expected[] = { detail::code_float32, 0x00, 0x00, 0x00, 0x00 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_double_zero)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(0.0), 9);

    format::writer::value_type expected[] = { detail::code_float64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_literal_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write(""), 1);

    format::writer::value_type expected[] = { detail::code_fixstr_0 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_literal_alpha)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.write("ALPHA"), 6);

    format::writer::value_type expected[] = { detail::code_fixstr_5, 0x41, 0x4C, 0x50, 0x48, 0x41 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_string_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    std::string text;
    BOOST_REQUIRE_EQUAL(writer.write(text), 1);

    format::writer::value_type expected[] = { detail::code_fixstr_0 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_string_alpha)
{
    test_vector buffer;
    format::writer writer(buffer);
    std::string text("ALPHA");
    BOOST_REQUIRE_EQUAL(writer.write(text), 6);

    format::writer::value_type expected[] = { detail::code_fixstr_5, 0x41, 0x4C, 0x50, 0x48, 0x41 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_binary_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    std::vector<format::writer::value_type> data;
    BOOST_REQUIRE_EQUAL(writer.write(data.data(), data.size()), 2);

    format::writer::value_type expected[] = { detail::code_bin8, 0x00 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_binary_one)
{
    test_vector buffer;
    format::writer writer(buffer);
    std::vector<format::writer::value_type> data;
    data.push_back(0x12);
    BOOST_REQUIRE_EQUAL(writer.write(data.data(), data.size()), 3);

    format::writer::value_type expected[] = { detail::code_bin8, 0x01, 0x12 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

//-----------------------------------------------------------------------------
// Array
//-----------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(test_array_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.array_begin(0), 1);
    BOOST_REQUIRE_EQUAL(writer.array_end(), 0);

    format::writer::value_type expected[] = { detail::code_fixarray_0 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_array_one)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.array_begin(1), 1);
    BOOST_REQUIRE_EQUAL(writer.write(), 1);
    BOOST_REQUIRE_EQUAL(writer.array_end(), 0);

    format::writer::value_type expected[] = { detail::code_fixarray_1, detail::code_null };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(fail_array_no_count)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_THROW(writer.array_begin(), protoc::invalid_value);
}

BOOST_AUTO_TEST_CASE(fail_array_count_too_small)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.array_begin(0), 1);
    BOOST_REQUIRE_THROW(writer.write(), protoc::invalid_scope);
}

BOOST_AUTO_TEST_CASE(fail_array_count_too_big)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.array_begin(2), 1);
    BOOST_REQUIRE_EQUAL(writer.write(), 1);
    BOOST_REQUIRE_THROW(writer.array_end(), protoc::invalid_scope);
}

//-----------------------------------------------------------------------------
// Map
//-----------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(test_map_empty)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.map_begin(0), 1);
    BOOST_REQUIRE_EQUAL(writer.map_end(), 0);

    format::writer::value_type expected[] = { detail::code_fixmap_0 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(test_map_one)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.map_begin(1), 1);
    BOOST_REQUIRE_EQUAL(writer.write(1), 1);
    BOOST_REQUIRE_EQUAL(writer.write(2), 1);
    BOOST_REQUIRE_EQUAL(writer.map_end(), 0);

    format::writer::value_type expected[] = { detail::code_fixmap_1, 0x01, 0x02 };
    BOOST_REQUIRE_EQUAL_COLLECTIONS(buffer.begin(), buffer.end(),
                                    expected, expected + sizeof(expected));
}

BOOST_AUTO_TEST_CASE(fail_map_no_count)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_THROW(writer.map_begin(), protoc::invalid_value);
}

BOOST_AUTO_TEST_CASE(fail_map_count_too_small)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.map_begin(0), 1);
    BOOST_REQUIRE_THROW(writer.write(), protoc::invalid_scope);
}

BOOST_AUTO_TEST_CASE(fail_map_count_too_big)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.map_begin(2), 1);
    BOOST_REQUIRE_EQUAL(writer.write(), 1);
    BOOST_REQUIRE_THROW(writer.map_end(), protoc::invalid_scope);
}

BOOST_AUTO_TEST_CASE(fail_map_count_odd)
{
    test_vector buffer;
    format::writer writer(buffer);
    BOOST_REQUIRE_EQUAL(writer.map_begin(1), 1);
    BOOST_REQUIRE_EQUAL(writer.write(), 1);
    BOOST_REQUIRE_THROW(writer.map_end(), protoc::invalid_scope);
}

BOOST_AUTO_TEST_SUITE_END()


text:
// Date Last Altered: $Date: 2008-08-04 22:55:41 -0600 (Mon, 04 Aug 2008) $
// Revision Number: $Revision: 344 $
//--------------------------------------------*-C++-*------------------------------------//
/*! \file SweepIterator1D.hh
 *  \author Greg Davidson
 *  \date February 6, 2006
 *
 *  \brief Provides a one-dimensional sweep iterator.
 *
 *  This file provides the \c SweepIterator<OneD> class.  This class provides the
 *  ability to iterate over the \c Zone<OneD> objects in the \c CartesianMesh<OneD>
 *  in a sweeping pattern, dependent upon the streaming angle.  This class receives
 *  some functionality from \c SweepIterator_base<OneD> through inheritance. */

#ifndef SWEEPITERATOR1D_HH
#define SWEEPITERATOR1D_HH

#include <boost/iterator/iterator_facade.hpp>

#include "SweepIterator_base.hh"
#include "Angle1D.hh"

using boost::iterator_facade;

/*! \addtogroup MeshMod Mesh Module
 *  @{ */

/*! \brief Iterates over the <tt>Zone</tt>s in a one-dimensional \c CartesianMesh in a sweep
 *         pattern.
 *
 *  The \c SweepIterator<OneD> class iterates over the \c Zone<OneD> objects stored in
 *  a \c CartesianMesh<OneD> in the correct order for a sweeping pattern given the streaming
 *  angle \f$ \mu \f$.  If \b NITERCHK is defined, range checking for this iterator will be
 *  disabled. */
template<>
class SweepIterator<OneD, ptr_vector< Zone<OneD> > >
                                 : public SweepIterator_base<OneD, ptr_vector< Zone<OneD> > >,
                                   public iterator_facade< SweepIterator<OneD, ptr_vector< Zone<OneD> > >,
                                                           Zone<OneD>,
                                                           boost::forward_traversal_tag,
                                                           const Zone<OneD>& >
{
private:
   /// Defines the \c Base type.
   typedef SweepIterator_base<OneD, ptr_vector< Zone<OneD> > >    Base;
   /// Defines the \c Zone type.
   typedef Zone<OneD>                  Zone;

public:
   /// Imports the \c AngleType from the \c Base type.
   typedef Base::AngleType       AngleType;
   /// Defines the \c const_reference type for this iterator.
   typedef const Zone&           const_reference;

   /*! \brief Bring the \c IncrementBeyondRange exception class into the \c SweepIterator scope.
    *         Thrown when the iterator is incremented beyond the range of the \c CartesianMesh. */
   typedef Iterator_IncrementBeyondRange     IncrementBeyondSweepRange;
   /*! \brief Bring the \c DereferenceOutOfRange exception class into the \c SweepIterator scope.
    *         Thrown when an out-of-range \c SweepIterator is dereferenced. */
   typedef Iterator_DereferenceOutOfRange    DereferenceOutOfSweepRange;

	/// Default constructor.
	SweepIterator()
			: SweepIterator_base<OneD, ptr_vector< Zone > >()
	{  }

	/*! \brief Constructor.  Takes an angle, the container reference, and a \c const_iterator.
	 *
	 *  Constructor. Takes an angle, a reference to the container holding the \c Zone
	 *  objects, and a \c const_iterator for the container.
	 *  \param[in] angle_in  The \f$ S_N \f$ quadrature angle of the sweep.
	 *  \param[in] cont_in   The container holding the \c Zone objects.
	 *  \param[in] iter_in   The \c ContainerType::const_iterator over the container of
	                     \c Zone objects. */
   SweepIterator(const Angle<OneD>& angle_in, const ContainerType& cont_in,
	              const ContainerType::const_iterator& iter_in)
	   : SweepIterator_base<OneD, ptr_vector< Zone > >(angle_in, cont_in, iter_in)
	{  }

   /*! \brief Copy constructor.
    *
    *  Copy constructor.
	 *  \param[in] iter_in  The \c SweepIterator to be copied. */
    SweepIterator(const SweepIterator<OneD, ptr_vector< Zone > >& iter_in)
			: SweepIterator_base<OneD, ptr_vector< Zone > >( iter_in.mAngle, iter_in.mContainer,
			                            iter_in.mIterator )
	{  }

private:
	/// Necessary to use \c boost::iterator_facade.
	friend class boost::iterator_core_access;

	/*! \brief Increments the iterator.
	 *
	 *  Increments the iterator.  Used by \c boost::iterator_facade.
	 *  \throw IncrementBeyondSweepRange  Throws this exception class if the iterator is incremented
	 *                                    out of the container's range. */
	void increment() throw(IncrementBeyondSweepRange)
	{
		if(mAngle.mu() > 0)  // Positive angle.
		{
#ifndef NITERCHK
			if(mIterator == mContainer->end())
				throw IncrementBeyondSweepRange(__LINE__, __FILE__);
#endif
			++mIterator;
		}
		else                 // Negative angle.
		{
#ifndef NITERCHK
			if(mIterator == mContainer->begin())
				throw IncrementBeyondSweepRange(__LINE__, __FILE__);
#endif
			--mIterator;
		}
	}

   /*! \brief Test for equality.
    *
    *  Tests whether two \c SweepIterator objects are equal
	 *  \param[in] iter_in  The iterator to test for equality.
	 *  \return    Whether \a iter_in is equal to this \c SweepIterator. */
	bool equal(const SweepIterator<DimensionType, ContainerType>& iter_in) const
	{
	   typedef AngleType::AngleType::OrdinateType  AngleOrdType;

	   if( fabs(iter_in.mAngle.mu() - Base::mAngle.mu()) < 1.0e-6 )
	      return (iter_in.mContainer == Base::mContainer && iter_in.mIterator == Base::mIterator);
	   else
	      return false;
	}

   /*! \brief Return a \c const_reference to the object pointed at by this \c SweepIterator.
    *
    *  Returns a \c const_reference to the object pointed at by this \c SweepIterator.
    *  \return A \c const_reference to the object pointed at by this \c SweepIterator.
    *  \throw  DereferenceOutOfSweepRange  Throws this exception is a dereference of an
    *                                      out-of-range \c SweepIterator is attempted. */
	const_reference dereference() const throw(DereferenceOutOfSweepRange)
   {
#ifndef NITERCHK
      if(mAngle.mu() > 0)
      {
         if( mIterator == mContainer->begin()-1 || mIterator == mContainer->end() )
            throw DereferenceOutOfSweepRange(__LINE__, __FILE__);
      }
      else
      {
         if( mIterator == mContainer->begin() || mIterator == mContainer->end()+1 )
            throw DereferenceOutOfSweepRange(__LINE__, __FILE__);
      }
#endif
      if(mAngle.mu() > 0)
         return *mIterator;
      else
         return *(mIterator-1);
   }
};

/// @}

#endif

ext: hh

max_stars_repo_name: jlconlin/PhDThesis

max_issues_repo_name: jlconlin/PhDThesis

max_forks_repo_name: jlconlin/PhDThesis


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//

#ifndef BOOST_URL_IMPL_SEGMENTS_IPP
#define BOOST_URL_IMPL_SEGMENTS_IPP

#include <boost/url/segments.hpp>
#include <boost/url/url.hpp>
#include <boost/url/detail/path.hpp>
#include <boost/url/detail/pct_encoding.hpp>
#include <boost/assert.hpp>

namespace boost {
namespace urls {

//------------------------------------------------
//
// Modifiers
//
//------------------------------------------------

auto
segments::
insert(
    iterator before,
    string_view s) ->
        iterator
{
    BOOST_ASSERT(before.impl_.pos_ >= u_->string().data());
    BOOST_ASSERT(before.impl_.pos_ <= u_->string().data() +
        u_->string().size());
    detail::copied_strings cs(
        u_->string());
    s = cs.maybe_copy(s);
    u_->edit_segments(
        before.impl_.i_,
        before.impl_.i_,
        detail::make_plain_segs_iter(
            &s, &s + 1),
        detail::make_plain_segs_iter(
            &s, &s + 1));
    return std::next(begin(), before.impl_.i_);
}

auto
segments::
segments::
erase(
    iterator first,
    iterator last) noexcept ->
        iterator
{
    BOOST_ASSERT(first.impl_.pos_ >= u_->string().data());
    BOOST_ASSERT(last.impl_.pos_ >= u_->string().data());
    BOOST_ASSERT(first.impl_.pos_ <= u_->string().data() +
        u_->string().size());
    BOOST_ASSERT(last.impl_.pos_ <= u_->string().data() +
        u_->string().size());
    string_view s;
    u_->edit_segments(
        first.impl_.i_, last.impl_.i_,
        detail::make_enc_segs_iter(&s, &s),
        detail::make_enc_segs_iter(&s, &s));
    return std::next(begin(), first.impl_.i_);
}

} // urls
} // boost

#endif

ext: ipp

max_stars_repo_name: abitmore/url

max_issues_repo_name: abitmore/url

max_forks_repo_name: alandefreitas/url


text:
// Copyright (c) 2019, FlightAware LLC.
// All rights reserved.
// Licensed under the 2-clause BSD license; see the LICENSE file

#include <boost/exception/diagnostic_information.hpp>
#include <boost/program_options.hpp>
#include <boost/regex.hpp>

#include <iostream>
#include <memory>

#include "message_source.h"
#include "skyaware_writer.h"
#include "socket_input.h"
#include "uat_message.h"

using namespace flightaware::uat;
using namespace flightaware::skyaware;

namespace po = boost::program_options;
using boost::asio::ip::tcp;

struct connect_option {
    std::string host;
    std::string port;
};

// Specializations of validate for --connect
void validate(boost::any &v, const std::vector<std::string> &values, connect_option *target_type, int) {
    po::validators::check_first_occurrence(v);
    const std::string &s = po::validators::get_single_string(values);

    static const boost::regex r("(?:([^:]+):)?(\\d+)");
    boost::smatch match;
    if (boost::regex_match(s, match, r)) {
        v = boost::any(connect_option{match[1], match[2]});
    } else {
        throw po::validation_error(po::validation_error::invalid_option_value);
    }
}

#define EXIT_NO_RESTART (64)

static int realmain(int argc, char **argv) {
    boost::asio::io_service io_service;

    // clang-format off
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("version", "show version")
        ("connect", po::value<connect_option>(), "connect to host:port for raw UAT data")
        ("reconnect-interval", po::value<unsigned>()->default_value(0), "on connection failure, attempt to reconnect after this interval (seconds); 0 disables")
        ("json-dir", po::value<std::string>(), "write json files to given directory")
        ("history-count", po::value<unsigned>()->default_value(120), "number of history files to maintain")
        ("history-interval", po::value<unsigned>()->default_value(30), "interval between history files (seconds)")
        ("lat", po::value<double>(), "latitude of receiver")
        ("lon", po::value<double>(), "longitude of receiver");
    // clang-format on

    po::variables_map opts;

    try {
        po::store(po::parse_command_line(argc, argv, desc), opts);
        po::notify(opts);
    } catch (boost::program_options::error &err) {
        std::cerr << err.what() << std::endl;
        std::cerr << desc << std::endl;
        return EXIT_NO_RESTART;
    }

    if (opts.count("help")) {
        std::cerr << "skyaware978 " << VERSION << std::endl;
        std::cerr << desc << std::endl;
        return EXIT_NO_RESTART;
    }

    if (opts.count("version")) {
        std::cerr << "skyaware978 " << VERSION << std::endl;
        return EXIT_NO_RESTART;
    }

    if (!opts.count("connect")) {
        std::cerr << "--connect option is required" << std::endl;
        return EXIT_NO_RESTART;
    }

    if (!opts.count("json-dir")) {
        std::cerr << "--json-dir option is required" << std::endl;
        return EXIT_NO_RESTART;
    }

    auto connect = opts["connect"].as<connect_option>();
    auto reconnect_interval = opts["reconnect-interval"].as<unsigned>();
    auto input = RawInput::Create(io_service, connect.host, connect.port, std::chrono::milliseconds(reconnect_interval * 1000));

    auto tracker = Tracker::Create(io_service);
    input->SetConsumer(std::bind(&Tracker::HandleMessages, tracker, std::placeholders::_1));
    input->SetErrorHandler([&io_service, reconnect_interval](const boost::system::error_code &ec) {
        std::cerr << "Connection failed: " << ec.message() << std::endl;
        if (!reconnect_interval) {
            io_service.stop();
        }
    });

    boost::optional<std::pair<double, double>> location = boost::make_optional(false, std::make_pair(0.0, 0.0));
    if (opts.count("lat") && opts.count("lon")) {
        location.emplace(opts["lat"].as<double>(), opts["lon"].as<double>());
    }

    auto dir = opts["json-dir"].as<std::string>();
    auto writer = SkyAwareWriter::Create(io_service, tracker, dir, std::chrono::milliseconds(1000), opts["history-count"].as<unsigned>(), std::chrono::milliseconds(opts["history-interval"].as<unsigned>() * 1000), location);

    writer->Start();
    tracker->Start();
    input->Start();

    io_service.run();

    input->Stop();
    tracker->Stop();
    writer->Stop();

    return 1; // connection loss is abnormal
}

int main(int argc, char **argv) {
#ifndef DEBUG_EXCEPTIONS
    try {
        return realmain(argc, argv);
    } catch (...) {
        std::cerr << "Uncaught exception: " << boost::current_exception_diagnostic_information() << std::endl;
        return 2;
    }
#else
    return realmain(argc, argv);
#endif
}

ext: cc


text:
/*
 * Copyright 2014-2015 Arne Johanson
 *
 * 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.
 */

#ifndef ARITHMETIC_HPP_
#define ARITHMETIC_HPP_

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <boost/proto/proto.hpp>
#ifdef SPRAT_BUILD_WITH_MPI
#include <mpi.h>
#endif
#include "config.hpp"
#include "util.hpp"
#include "pvector.hpp"
#include "sparse_matrices.hpp"
#include "mesh.hpp"
#include "mesh_traits.hpp"

#define mvAssert(MSG, COND) \
	assert((COND) && MSG);

// *************************************** Vectors

// See pvectors.hpp

// *************************************** Element Vectors & Matrices

#include "element_mvtypes.hpp"

// *************************************** Proto Grammars

struct VectorType
	: boost::proto::or_<
	    boost::proto::terminal< BareVector >
	  , boost::proto::terminal< BareVectorView >
	  , boost::proto::terminal< BareDistributedVector >
	  , boost::proto::terminal< BareDistributedVectorView >
> {};

struct ElementVectorType
	: boost::proto::or_<
	    boost::proto::terminal< BareElementVector >
	  , boost::proto::terminal< BareElementVectorView >
> {};

struct ElemetMatrixType
	: boost::proto::or_<
	  	  boost::proto::terminal< BareElementMatrix >
		, boost::proto::terminal< BareLightweightScaledElementMatrix >
		, boost::proto::terminal< BareElementMatrixView >
> {};

struct MatrixType
	: boost::proto::or_<
	  boost::proto::terminal< BareMatrix >
	, boost::proto::terminal< BareCSRMatrix >
//	, ElemetMatrixType
> {};

struct VectorGrammar
	: boost::proto::or_<
	    VectorType
	  , boost::proto::terminal< boost::proto::convertible_to<real> >
	  , boost::proto::plus< VectorGrammar, VectorGrammar >
	  , boost::proto::minus< VectorGrammar, VectorGrammar >
	  , boost::proto::multiplies< VectorGrammar, VectorGrammar >
	  , boost::proto::divides< VectorGrammar, VectorGrammar >
	  , boost::proto::negate< VectorGrammar >
> {};

struct ElementVectorGrammar
	: boost::proto::or_<
	    VectorType
	  , ElementVectorType
	  , boost::proto::terminal< boost::proto::convertible_to<real> >
	  , boost::proto::plus< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::minus< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::multiplies< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::divides< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::negate< ElementVectorGrammar >
> {};

struct ElementMatrixGrammar
	: boost::proto::or_<
	    boost::proto::plus< ElementMatrixGrammar, ElementMatrixGrammar >
	  , boost::proto::minus< ElementMatrixGrammar, ElementMatrixGrammar >
	  , boost::proto::multiplies< ElemetMatrixType, ElementVectorGrammar >
> {};

struct ElementMVGrammar
	: boost::proto::or_<
	  	 boost::proto::or_<
	    	 VectorType
	     , ElementVectorType
	     , boost::proto::terminal< boost::proto::convertible_to<real> >
		 >
	  , boost::proto::plus< ElementMVGrammar, ElementMVGrammar >
	  , boost::proto::minus< ElementMVGrammar, ElementMVGrammar >
	  , boost::proto::multiplies< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::multiplies< ElemetMatrixType, VectorGrammar >
	  , boost::proto::divides< ElementVectorGrammar, ElementVectorGrammar >
	  , boost::proto::negate< ElementMVGrammar >
> {};

struct MVGrammar
	: boost::proto::or_<
		 boost::proto::or_<
			 VectorType
		 , boost::proto::terminal< boost::proto::convertible_to<real> >
//		 , ElementVectorType
		 >
	  , boost::proto::plus< MVGrammar, MVGrammar >
	  , boost::proto::minus< MVGrammar, MVGrammar >
	  , boost::proto::multiplies< MVGrammar, MVGrammar >
	  , boost::proto::multiplies< MatrixType, MVGrammar >
	  , boost::proto::divides< MVGrammar, MVGrammar >
	  , boost::proto::negate< MVGrammar >
> {};

// ******************************** Forward-Declared Expression Wrappers

template<typename Expr>
struct ElemMVExprWrapper;

template<typename Expr>
struct ElemVectorExprWrapper;

template<typename Expr>
struct VectorExprWrapper;

template<typename Expr>
struct MVExprWrapper;

// ******************************** Proto-fying Bare Data Types

typedef VectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareVector > > > ProtoVector;
typedef VectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareVectorView > > > ProtoVectorView;
typedef VectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareDistributedVector > > > ProtoDistributedVector;
typedef VectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareDistributedVectorView > > > ProtoDistributedVectorView;

typedef ElemVectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareElementVector > > > ProtoElementVector;
typedef ElemVectorExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareElementVectorView > > > ProtoElementVectorView;

typedef ElemMVExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareElementMatrix > > > ProtoElementMatrix;
typedef ElemMVExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareLightweightScaledElementMatrix > > > ProtoLightweightScaledElementMatrix;
typedef ElemMVExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareElementMatrixView > > > ProtoElementMatrixView;

typedef MVExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareCSRMatrix > > > ProtoCSRMatrix;
typedef MVExprWrapper<boost::proto::basic_expr<boost::proto::tag::terminal, boost::proto::term< BareMatrix > > > ProtoMatrix;

// ******************************** Proto Domains

struct MVDomain : boost::proto::domain< boost::proto::generator<MVExprWrapper> , MVGrammar > {};
struct ElementMVDomain : boost::proto::domain< boost::proto::generator<ElemMVExprWrapper> , ElementMVGrammar, MVDomain > {};
struct ElementVectorDomain : boost::proto::domain< boost::proto::generator<ElemVectorExprWrapper> , ElementVectorGrammar, ElementMVDomain > {};
struct VectorDomain : boost::proto::domain< boost::proto::generator<VectorExprWrapper> , VectorGrammar, ElementVectorDomain > {};

// ******************************** Proto Expression Wrappers I

template<typename Expr>
struct ElemMVExprWrapper : boost::proto::extends<Expr, ElemMVExprWrapper<Expr>, ElementMVDomain>
{
	typedef boost::proto::extends<Expr, ElemMVExprWrapper<Expr>, ElementMVDomain>   base_type;

	ElemMVExprWrapper(Expr const& expr = Expr()) : base_type(expr) {}
};

template<typename Expr>
struct MVExprWrapper : boost::proto::extends<Expr, MVExprWrapper<Expr>, MVDomain>
{
	typedef boost::proto::extends<Expr, MVExprWrapper<Expr>, MVDomain>   base_type;

	MVExprWrapper(Expr const& expr = Expr()) : base_type(expr) {}
};

// *************************** Matrix-Proto-Types

#include "proto_matrix.hpp"

typedef CSRMatrix_<> CSRMatrix;
typedef Matrix_<> Matrix;

typedef ElementMatrix_<> ElementMatrix;
typedef LightweightScaledElementMatrix_<> LightweightScaledElementMatrix;
typedef ElementMatrixView_<> ElementMatrixView;

// *************************** Proto Execution Contexts

#include "proto_context.hpp"

// *************************** Proto Expression Wrappers II

template<typename Expr>
struct ElemVectorExprWrapper : boost::proto::extends<Expr, ElemVectorExprWrapper<Expr>, ElementVectorDomain>
{
	typedef boost::proto::extends<Expr, ElemVectorExprWrapper<Expr>, ElementVectorDomain>   base_type;

	ElemVectorExprWrapper(Expr const& expr = Expr()) : base_type(expr) {}
};

template<typename Expr>
struct VectorExprWrapper : boost::proto::extends<Expr, VectorExprWrapper<Expr>, VectorDomain>
{
	typedef boost::proto::extends<Expr, VectorExprWrapper<Expr>, VectorDomain>   base_type;

	VectorExprWrapper(Expr const& expr = Expr()) : base_type(expr) {}

	typedef real result_type;

	real operator[](index_t i) const
	{
		VectorSubscriptContext const ctx(i);
		return boost::proto::eval(*this, ctx);
	}
};

// ************************************** Vector-Proto-Types

#include "proto_vector.hpp"

// ************************************** Proto Element Array Types

#include "element_arraytypes.hpp"

#endif /* ARITHMETIC_HPP_ */

ext: hpp

max_stars_repo_name: cau-se/sprat-pde-dsl

max_issues_repo_name: cau-se/sprat-pde-dsl

max_forks_repo_name: cau-se/sprat-pde-dsl


text:
#pragma once

#include <boost/container/small_vector.hpp>
#include <boost/optional.hpp>
#include <zmq.hpp>

#include <chrono>
#include <cstddef>
#include <cstdint>
#include <string>

namespace sb::net {
  using signal = boost::container::small_vector<float, 16>;

  struct message {
    std::string channel;
    sb::net::signal signal;
  };

  boost::optional<signal> parse(std::uint8_t const*, std::size_t);

  boost::optional<message> poll(zmq::socket_t&, std::chrono::milliseconds);
}

max_stars_repo_name: rightfold/signalbox

max_issues_repo_name: rightfold/signalbox

max_forks_repo_name: rightfold/signalbox


text:
// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is 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.
// __END_LICENSE__

#include <vw/Math/Matrix.h>
#include <vw/Math/Quaternion.h>
#include <vw/Math/Vector.h>
#include <vw/Math/LevenbergMarquardt.h>
#include <vw/Camera/CameraModel.h>
#include <asp/IsisIO/IsisInterfaceMapLineScan.h>

#include <algorithm>
#include <limits>
#include <string>
#include <vector>

#include <Camera.h>
#include <CameraDistortionMap.h>
#include <CameraFocalPlaneMap.h>
#include <CameraGroundMap.h>
#include <Latitude.h>
#include <Longitude.h>
#include <Projection.h>
#include <ProjectionFactory.h>
#include <Sensor.h>
#include <SpiceRotation.h>
#include <iTime.h>

#include <boost/smart_ptr/scoped_ptr.hpp>

using namespace vw;
using namespace asp;
using namespace asp::isis;

// Constructor
IsisInterfaceMapLineScan::IsisInterfaceMapLineScan( std::string const& filename ) :
  IsisInterface( filename ){//, m_projection( Isis::ProjectionFactory::CreateFromCube(*m_label) ) {

  Isis::TProjection* tempProj = (Isis::TProjection*)Isis::ProjectionFactory::CreateFromCube(*m_label);
  m_projection.reset(tempProj);

  // Gutting Isis::Camera
  m_distortmap = m_camera->DistortionMap();
  m_groundmap = m_camera->GroundMap();
  m_focalmap = m_camera->FocalPlaneMap();
  m_cache_px[0] = m_cache_px[1] = std::numeric_limits<double>::quiet_NaN();
}

// Custom Functions
class EphemerisLMA : public vw::math::LeastSquaresModelBase<EphemerisLMA> {
  vw::Vector3 m_point;
  Isis::Camera* m_camera;
  Isis::CameraDistortionMap *m_distortmap;
  Isis::CameraFocalPlaneMap *m_focalmap;
public:
  typedef vw::Vector<double> result_type; // Back project result
      typedef vw::Vector<double> domain_type; // Ephemeris time
  typedef vw::Matrix<double> jacobian_type;

  inline EphemerisLMA( vw::Vector3 const& point,
                       Isis::Camera* camera,
                       Isis::CameraDistortionMap* distortmap,
                       Isis::CameraFocalPlaneMap* focalmap ) : m_point(point), m_camera(camera), m_distortmap(distortmap), m_focalmap(focalmap) {}

  inline result_type operator()( domain_type const& x ) const;
};

// LMA for projecting point to linescan camera
EphemerisLMA::result_type
EphemerisLMA::operator()( EphemerisLMA::domain_type const& x ) const {

  // Setting Ephemeris Time
  m_camera->setTime( Isis::iTime( x[0] ));

  // Calculating the look direction in camera frame
  Vector3 instru;
  m_camera->instrumentPosition(&instru[0]);
  instru *= 1000;  // Spice gives in km
  Vector3 lookB = normalize( m_point - instru );
  std::vector<double> lookB_copy(3);
  std::copy(lookB.begin(),lookB.end(),lookB_copy.begin());
  std::vector<double> lookJ = m_camera->bodyRotation()->J2000Vector(lookB_copy);
  std::vector<double> lookC = m_camera->instrumentRotation()->ReferenceVector(lookJ);
  Vector3 look;
  std::copy(lookC.begin(),lookC.end(),look.begin());

  // Projecting to mm focal plane
  look = m_camera->FocalLength() * (look / look[2]);
  m_distortmap->SetUndistortedFocalPlane(look[0], look[1]);
  m_focalmap->SetFocalPlane( m_distortmap->FocalPlaneX(),
                             m_distortmap->FocalPlaneY() );
  result_type result(1);
  // Not exactly sure about lineoffset .. but ISIS does it
  result[0] = m_focalmap->DetectorLineOffset() - m_focalmap->DetectorLine();

  return result;
}

Vector2
IsisInterfaceMapLineScan::point_to_pixel( Vector3 const& point ) const {

  // First seed LMA with an ephemeris time in the middle of the image
  double middle_et =
    m_camera->cacheStartTime().Et() + (m_camera->cacheEndTime().Et()-m_camera->cacheStartTime().Et())/2.0;

  // Build LMA
  EphemerisLMA model( point, m_camera.get(), m_distortmap, m_focalmap );
  int status;
  Vector<double> objective(1), start(1);
  start[0] = middle_et;
  Vector<double> solution_e = math::levenberg_marquardt( model,
                                                         start,
                                                         objective,
                                                         status );

  // Make sure we found ideal time
  VW_ASSERT( status > 0,
             camera::PointToPixelErr() << " Unable to project point into ISIS map linescan camera " );

  // Setting to camera time to solution
  m_camera->setTime( Isis::iTime( solution_e[0] ) );

  // Working out pointing
  Vector3 center;
  m_camera->instrumentPosition(&center[0]);
  Vector3 look = normalize(point-1000*center);

  // Calculating rotation to camera frame
  std::vector<double> rot_inst = m_camera->instrumentRotation()->Matrix();
  std::vector<double> rot_body = m_camera->bodyRotation()->Matrix();
  MatrixProxy<double,3,3> R_inst(&(rot_inst[0]));
  MatrixProxy<double,3,3> R_body(&(rot_body[0]));
  look = transpose(R_body*transpose(R_inst))*look;
  look = m_camera->FocalLength() * (look / look[2]);

  // Projecting back on to ground to find out time
  m_groundmap->SetFocalPlane( look[0],
                              look[1],
                              look[2] );

  m_projection->SetGround( m_camera->UniversalLatitude(),
                           m_camera->UniversalLongitude() );
  m_cache_px = Vector2( m_projection->WorldX()-1,
                        m_projection->WorldY()-1 );
  return m_cache_px;
}

Vector3
IsisInterfaceMapLineScan::camera_center( Vector2 const& px ) const {
  if ( px != m_cache_px ) {
    m_cache_px = px;
    if (!m_projection->SetWorld( px[0]+1,
                                 px[1]+1 ))
      vw_throw( camera::PixelToRayErr() << "Failed to SetWorld." );
    if (!m_groundmap->SetGround( Isis::Latitude(m_projection->UniversalLatitude(),Isis::Angle::Degrees),
                                 Isis::Longitude(m_projection->UniversalLongitude(),Isis::Angle::Degrees) ) )
      vw_throw( camera::PixelToRayErr() << "Failed to SetGround." );
  }
  Vector3 position;
  m_camera->instrumentPosition( &position[0] );
  return position * 1e3;
}

Vector3
IsisInterfaceMapLineScan::pixel_to_vector( Vector2 const& px ) const {
  Vector3 sB = camera_center( px );
  Vector3 p_pB;
  m_camera->Sensor::Coordinate( &p_pB[0] );
  return normalize(p_pB*1000 - sB);
}

Quat
IsisInterfaceMapLineScan::camera_pose( Vector2 const& px ) const {
  camera_center( px );
  std::vector<double> rot_inst = m_camera->instrumentRotation()->Matrix();
  std::vector<double> rot_body = m_camera->bodyRotation()->Matrix();
  MatrixProxy<double,3,3> R_inst(&(rot_inst[0]));
  MatrixProxy<double,3,3> R_body(&(rot_body[0]));
  return Quat(R_body*transpose(R_inst));
}

max_stars_repo_name: PicoJr/StereoPipeline

max_issues_repo_name: PicoJr/StereoPipeline

max_forks_repo_name: PicoJr/StereoPipeline


text:
#include <iterator>
#include <fstream>
#include <chrono>
#include <iostream>
#include <boost/program_options.hpp>
#include <rapidmp/parser/python.hpp>

int main( int argc, char *argv[] ) {
  Py_Initialize();
  namespace po = boost::program_options;
  po::options_description options("option");
  options.add_options()
    ( "help,h", "show this message" )
    ( "input,i", po::value<std::string>(), "MessagePack file to parse" )
    ( "repeat,n", po::value<size_t>(),  "number of times to parse" );
  po::variables_map args;
  po::store(
    po::parse_command_line( argc, argv, options ),
    args
  );
  po::notify( args );
  if( args.count("help") || !args.count("input") || !args.count("repeat") )
    std::cerr << options << std::endl;
  else {
    std::fstream  file( args[ "input" ].as< std::string >(), std::ios::in|std::ios::binary );
    const std::vector< char > serialized( std::istreambuf_iterator< char >( file.rdbuf() ), std::istreambuf_iterator< char >() );
    const size_t repeat = args[ "repeat" ].as<size_t>();
    const auto begin_time = std::chrono::high_resolution_clock::now();
    for( size_t count = 0; count != repeat; ++count ) {
      auto iter = serialized.data();
      const auto end = serialized.data() + serialized.size();
      rapidmp::parse_object< rapidmp::version_1_1 >( iter, end );
    }
    const auto end_time = std::chrono::high_resolution_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>( end_time - begin_time ).count() << "msec" << std::endl;
  }
}

max_stars_repo_name: Fadis/rapidmp

max_issues_repo_name: Fadis/rapidmp

max_forks_repo_name: Fadis/rapidmp