<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawsh.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-06 12:44:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_DRAWSH_HXX
#define SC_DRAWSH_HXX

#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#include "shellids.hxx"
#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif

#ifndef _SVDMARK_HXX //autogen
#include <svx/svdmark.hxx>
#endif

#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif

class AbstractSvxNameDialog; //CHINA001 class SvxNameDialog;
class ScViewData;
class ScDrawView;

class ScDrawShell : public SfxShell
{
    ScViewData* pViewData;

    DECL_LINK( NameObjectHdl, AbstractSvxNameDialog* );

#ifdef ISSUE66550_HLINK_FOR_SHAPES
    void SetHlinkForObject( SdrObject* pObj, const rtl::OUString& rHlnk );
#endif

protected:
    ScViewData* GetViewData()   { return pViewData; }

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_DRAW_SHELL)

                    ScDrawShell(ScViewData* pData);
                    ~ScDrawShell();

    void    StateDisableItems( SfxItemSet &rSet );

    void    ExecDrawAttr(SfxRequest& rReq);
    void    GetDrawAttrState(SfxItemSet &rSet);
    void    GetAttrFuncState(SfxItemSet &rSet);

    void    ExecDrawFunc(SfxRequest& rReq);
    void    GetDrawFuncState(SfxItemSet &rSet);
    void    GetState(SfxItemSet &rSet);

    void    ExecFormText(SfxRequest& rReq);     // StarFontWork
    void    GetFormTextState(SfxItemSet& rSet);

    void    ExecuteHLink(SfxRequest& rReq);     // Hyperlink
    void    GetHLinkState(SfxItemSet& rSet);

    void    ExecFormatPaintbrush(SfxRequest& rReq);
    void    StateFormatPaintbrush(SfxItemSet& rSet);

    void    ExecuteMacroAssign( SdrObject* pObj, Window* pWin );
    void    ExecuteLineDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
    void    ExecuteAreaDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
    void    ExecuteTextAttrDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );

    ScDrawView* GetDrawView();

    BOOL    AreAllObjectsOnLayer(USHORT nLayerNo,const SdrMarkList& rMark);
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.9.240); FILE MERGED 2008/04/01 15:30:52 thb 1.9.240.2: #i85898# Stripping all external header guards 2008/03/31 17:15:40 rt 1.9.240.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: drawsh.hxx,v $
 * $Revision: 1.10 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_DRAWSH_HXX
#define SC_DRAWSH_HXX

#include <sfx2/shell.hxx>
#include "shellids.hxx"
#include <sfx2/module.hxx>
#include <svx/svdmark.hxx>
#include <tools/link.hxx>

class AbstractSvxNameDialog; //CHINA001 class SvxNameDialog;
class ScViewData;
class ScDrawView;

class ScDrawShell : public SfxShell
{
    ScViewData* pViewData;

    DECL_LINK( NameObjectHdl, AbstractSvxNameDialog* );

#ifdef ISSUE66550_HLINK_FOR_SHAPES
    void SetHlinkForObject( SdrObject* pObj, const rtl::OUString& rHlnk );
#endif

protected:
    ScViewData* GetViewData()   { return pViewData; }

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_DRAW_SHELL)

                    ScDrawShell(ScViewData* pData);
                    ~ScDrawShell();

    void    StateDisableItems( SfxItemSet &rSet );

    void    ExecDrawAttr(SfxRequest& rReq);
    void    GetDrawAttrState(SfxItemSet &rSet);
    void    GetAttrFuncState(SfxItemSet &rSet);

    void    ExecDrawFunc(SfxRequest& rReq);
    void    GetDrawFuncState(SfxItemSet &rSet);
    void    GetState(SfxItemSet &rSet);

    void    ExecFormText(SfxRequest& rReq);     // StarFontWork
    void    GetFormTextState(SfxItemSet& rSet);

    void    ExecuteHLink(SfxRequest& rReq);     // Hyperlink
    void    GetHLinkState(SfxItemSet& rSet);

    void    ExecFormatPaintbrush(SfxRequest& rReq);
    void    StateFormatPaintbrush(SfxItemSet& rSet);

    void    ExecuteMacroAssign( SdrObject* pObj, Window* pWin );
    void    ExecuteLineDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
    void    ExecuteAreaDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );
    void    ExecuteTextAttrDlg( SfxRequest& rReq, USHORT nTabPage = 0xffff );

    ScDrawView* GetDrawView();

    BOOL    AreAllObjectsOnLayer(USHORT nLayerNo,const SdrMarkList& rMark);
};

#endif

<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2013
  \file      new_model_dialog.cpp
  \author    Урусов Андрей (rdo@rk9.bmstu.ru)
  \date      04.01.2013
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include "utils/warning_disable.h"
#include <QDir>
#include <QFileDialog>
#include "utils/warning_enable.h"
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio/src/dialog/new_model_dialog.h"
// --------------------------------------------------------------------------------

NewModelDialog::NewModelDialog(QWidget* pParent)
	: QDialog(pParent, Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
{
	setupUi(this);

	layout()->setSizeConstraint(QLayout::SetFixedSize);

	m_font    = labelError->font();
	m_fontRed = m_font;
	m_fontRed.setBold(true);

	m_palette    = labelError->palette();
	m_paletteRed = m_palette;
	m_paletteRed.setColor(labelError->foregroundRole(), Qt::red);

	connect(modelName, SIGNAL(textChanged(const QString&)), this, SLOT(updateUI()));
	connect(modelPathButton, SIGNAL(clicked(bool)), this, SLOT(onPathButtonClicked()));

	setPath(QDir::homePath());
}

NewModelDialog::~NewModelDialog()
{}

void NewModelDialog::setPath(CREF(QString) path)
{
	QString normPath(path);
	if (!normPath.isEmpty())
	{
		if (normPath.at(normPath.length()-1) != QChar('/') && normPath.at(normPath.length()-1) != QChar('\\'))
		{
			normPath += "/";
		}
	}
	modelPath->setText(normPath);
	updateUI();
}

void NewModelDialog::updateUI()
{
	rbool error = true;
	if (modelName->text().isEmpty())
	{
		labelError->setText("Необходимо указать имя модели");
	}
	else
	{
		QString fullName(modelPath->text() + modelName->text());
		QFileInfo fileInfo(fullName);
		if (fileInfo.exists())
		{
			QString info = fileInfo.isDir()
				? "Такая директория уже существует: '%1'"
				: "Такой файл уже существует: '%1'";

			labelError->setText(info.arg(fullName));
		}
		else
		{
			labelError->setText(QString("Будет создана директория: '%1'").arg(fullName));
			error = false;
		}
	}

	buttonOk->setEnabled(!error);
	labelError->setFont   (error ? m_fontRed    : m_font   );
	labelError->setPalette(error ? m_paletteRed : m_palette);
}

void NewModelDialog::onPathButtonClicked()
{
	QString path = QFileDialog::getExistingDirectory(
		this,
		"Выбор директории для модели",
		modelPath->text(),
		QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
	);
	if (!path.isEmpty())
	{
		setPath(path);
	}
}

QString NewModelDialog::getModelName() const
{
	return modelName->text();
}

QString NewModelDialog::getModelPath() const
{
	return modelPath->text();
}

ruint NewModelDialog::getTemplateIndex() const
{
	ruint result = 0;
	if (template2->isChecked())
	{
		result = 2;
	}
	else if (template3->isChecked())
	{
		result = 4;
	}
	else if (template4->isChecked())
	{
		result = 6;
	}
	else
	{
		ASSERT(template1->isChecked());
		result = 0;
	}

	if (comments->isChecked())
	{
		++result;
	}

	return result;
}
<commit_msg> - для новой модели выбирается папка документы<commit_after>/*!
  \copyright (c) RDO-Team, 2013
  \file      new_model_dialog.cpp
  \author    Урусов Андрей (rdo@rk9.bmstu.ru)
  \date      04.01.2013
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include "utils/warning_disable.h"
#include <QDir>
#include <QFileDialog>
#include <QStandardPaths>
#include "utils/warning_enable.h"
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio/src/dialog/new_model_dialog.h"
// --------------------------------------------------------------------------------

NewModelDialog::NewModelDialog(QWidget* pParent)
	: QDialog(pParent, Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
{
	setupUi(this);

	layout()->setSizeConstraint(QLayout::SetFixedSize);

	m_font    = labelError->font();
	m_fontRed = m_font;
	m_fontRed.setBold(true);

	m_palette    = labelError->palette();
	m_paletteRed = m_palette;
	m_paletteRed.setColor(labelError->foregroundRole(), Qt::red);

	connect(modelName, SIGNAL(textChanged(const QString&)), this, SLOT(updateUI()));
	connect(modelPathButton, SIGNAL(clicked(bool)), this, SLOT(onPathButtonClicked()));

	QString path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
	if (path.isEmpty())
	{
		path = QDir::homePath();
	}
	setPath(path);
}

NewModelDialog::~NewModelDialog()
{}

void NewModelDialog::setPath(CREF(QString) path)
{
	QString normPath(path);
	if (!normPath.isEmpty())
	{
		if (normPath.at(normPath.length()-1) != QChar('/') && normPath.at(normPath.length()-1) != QChar('\\'))
		{
			normPath += "/";
		}
	}
	modelPath->setText(normPath);
	updateUI();
}

void NewModelDialog::updateUI()
{
	rbool error = true;
	if (modelName->text().isEmpty())
	{
		labelError->setText("Необходимо указать имя модели");
	}
	else
	{
		QString fullName(modelPath->text() + modelName->text());
		QFileInfo fileInfo(fullName);
		if (fileInfo.exists())
		{
			QString info = fileInfo.isDir()
				? "Такая директория уже существует: '%1'"
				: "Такой файл уже существует: '%1'";

			labelError->setText(info.arg(fullName));
		}
		else
		{
			labelError->setText(QString("Будет создана директория: '%1'").arg(fullName));
			error = false;
		}
	}

	buttonOk->setEnabled(!error);
	labelError->setFont   (error ? m_fontRed    : m_font   );
	labelError->setPalette(error ? m_paletteRed : m_palette);
}

void NewModelDialog::onPathButtonClicked()
{
	QString path = QFileDialog::getExistingDirectory(
		this,
		"Выбор директории для модели",
		modelPath->text(),
		QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
	);
	if (!path.isEmpty())
	{
		setPath(path);
	}
}

QString NewModelDialog::getModelName() const
{
	return modelName->text();
}

QString NewModelDialog::getModelPath() const
{
	return modelPath->text();
}

ruint NewModelDialog::getTemplateIndex() const
{
	ruint result = 0;
	if (template2->isChecked())
	{
		result = 2;
	}
	else if (template3->isChecked())
	{
		result = 4;
	}
	else if (template4->isChecked())
	{
		result = 6;
	}
	else
	{
		ASSERT(template1->isChecked());
		result = 0;
	}

	if (comments->isChecked())
	{
		++result;
	}

	return result;
}
<|endoftext|>


<commit_before>#pragma once
#include "types.h"
namespace mtao { namespace geometry {
    template <typename T, int D, int C>
    auto barycentric_weights(const ColVectors<T,D>& P, const mtao::Vector<int,C>& indices, const mtao::Vector<T,D>& p) const -> mtao::VectorX<T,C> {

        int cell_size = indices.rows();
        mtao::Vector<T,C> weights(cell_size);
        //Scalar weight_sum = 0;
        constexpr static T epsilon = 1e-3;
        using Vec = mtao::Vector<T,D>;

        auto boundary_dist = [&](auto&& a, auto&& b) -> T {
            auto pa = p-a;
            auto ba = (b-a).normalized().eval();
            return (pa - ba.dot(pa) * ba).norm();
        };
        auto cotangent = [](const Vec& a, const Vec& b, const Vec& c) -> T {
            auto&& ba = (a-b).normalized();
            auto&& bc = (c-b).normalized();
            auto&& dt = bc.dot(ba) ;
            return dt/std::sqrt(1-dt*dt);
        };

        for(int i = 0; i < cell_size; ++i) {
            int curr = indices(i);
            int ip1 = (i+1)%cell_size;
            int next = indices[ip1];
            auto&& q = P.col(curr);
            auto&& qn = P.col(next);
            auto err = epsilon * (qn-q).norm();
            if((p-q).norm() < err) {//Sits on this vertex
                return mtao::Vector<T,C>::Unit(cell_size,i);
            } else if(boundary_dist(q,qn) <= err) {//sits on an edge
                weights.setZero();
                Scalar dn = (p-qn).norm();
                Scalar d = (p-q).norm();
                weights(i) = dn/(d+dn);
                weights(ip1) = d/(d+dn);
                return weights;
            }
        }
        for(int i = 0; i < indices.size(); ++i) {
            int prev = indices((i+cell_size-1)%cell_size);
            int curr = indices(i);
            int next = indices((i+1)%indices.size());
            auto&& qp = P.col(prev);
            auto&& q = P.col(curr);
            auto&& qn = P.col(next);
            weights(i) = (cotangent(p,q,qp) + cotangent(p,q,qn)) / (p-q).squaredNorm();
        }
        return weights / weights.sum();

    }

}}
<commit_msg>namespace error<commit_after>#pragma once
#include "mtao/types.h"
namespace mtao { namespace geometry {
    template <typename T, int D, int C>
    auto barycentric_weights(const ColVectors<T,D>& P, const mtao::Vector<int,C>& indices, const mtao::Vector<T,D>& p) const -> mtao::VectorX<T,C> {

        int cell_size = indices.rows();
        mtao::Vector<T,C> weights(cell_size);
        //Scalar weight_sum = 0;
        constexpr static T epsilon = 1e-3;
        using Vec = mtao::Vector<T,D>;

        auto boundary_dist = [&](auto&& a, auto&& b) -> T {
            auto pa = p-a;
            auto ba = (b-a).normalized().eval();
            return (pa - ba.dot(pa) * ba).norm();
        };
        auto cotangent = [](const Vec& a, const Vec& b, const Vec& c) -> T {
            auto&& ba = (a-b).normalized();
            auto&& bc = (c-b).normalized();
            auto&& dt = bc.dot(ba) ;
            return dt/std::sqrt(1-dt*dt);
        };

        for(int i = 0; i < cell_size; ++i) {
            int curr = indices(i);
            int ip1 = (i+1)%cell_size;
            int next = indices[ip1];
            auto&& q = P.col(curr);
            auto&& qn = P.col(next);
            auto err = epsilon * (qn-q).norm();
            if((p-q).norm() < err) {//Sits on this vertex
                return mtao::Vector<T,C>::Unit(cell_size,i);
            } else if(boundary_dist(q,qn) <= err) {//sits on an edge
                weights.setZero();
                Scalar dn = (p-qn).norm();
                Scalar d = (p-q).norm();
                weights(i) = dn/(d+dn);
                weights(ip1) = d/(d+dn);
                return weights;
            }
        }
        for(int i = 0; i < indices.size(); ++i) {
            int prev = indices((i+cell_size-1)%cell_size);
            int curr = indices(i);
            int next = indices((i+1)%indices.size());
            auto&& qp = P.col(prev);
            auto&& q = P.col(curr);
            auto&& qn = P.col(next);
            weights(i) = (cotangent(p,q,qp) + cotangent(p,q,qn)) / (p-q).squaredNorm();
        }
        return weights / weights.sum();

    }

}}
<|endoftext|>


<commit_before>/* Copyright 2016 Carnegie Mellon University
 *
 * 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 "scanner/engine/sampling.h"

namespace scanner {

// Gets the list of work items for a sequence of rows in the job
RowIntervals slice_into_row_intervals(const JobMetadata& job,
                                      const std::vector<i64>& rows) {
  RowIntervals info;
  // Analyze rows and job to determine what item ids and offsets in them to
  // sample from
  i32 io_item_size = job.io_item_size();
  auto item_from_row = [io_item_size](i64 r) -> i32 {
    return r / io_item_size;
  };
  auto offset_from_row = [io_item_size](i64 r) -> i64 {
    return r % io_item_size;
  };

  assert(!rows.empty());
  i32 current_item = item_from_row(rows[0]);
  i64 item_start = offset_from_row(rows[0]);
  i64 item_end = item_start + 1;
  std::vector<i64> valid_offsets;
  for (i64 row : rows) {
    i32 item = item_from_row(row);
    i64 item_offset = offset_from_row(row);
    if (item != current_item) {
      // Start a new item and push the current one into the list
      info.item_ids.push_back(current_item);
      info.item_intervals.push_back(std::make_tuple(item_start, item_end));
      info.valid_offsets.push_back(valid_offsets);

      current_item = item;
      item_start = item_offset;
      item_end = item_offset + 1;
      valid_offsets.clear();
    }

    valid_offsets.push_back(item_offset);
    item_end = item_offset + 1;
  }
  info.item_ids.push_back(current_item);
  info.item_intervals.push_back(std::make_tuple(item_start, item_end));
  info.valid_offsets.push_back(valid_offsets);

  return info;
}

VideoIntervals slice_into_video_intervals(
    const std::vector<i64>& keyframe_positions,
    const std::vector<i64>& rows) {
  VideoIntervals info;
  assert(keyframe_positions.size() >= 2);
  size_t start_keyframe_index = 0;
  size_t end_keyframe_index = 1;
  i64 next_keyframe = keyframe_positions[end_keyframe_index];
  std::vector<i64> valid_frames;
  for (i64 row : rows) {
    if (row >= next_keyframe) {
      assert(end_keyframe_index < keyframe_positions.size() - 1);
      next_keyframe = keyframe_positions[end_keyframe_index + 1];
      if (row >= next_keyframe) {
        // Skipped a keyframe, so make a new interval
        info.keyframe_index_intervals.push_back(
            std::make_tuple(start_keyframe_index, end_keyframe_index));
        info.valid_frames.push_back(valid_frames);

        end_keyframe_index = end_keyframe_index + 1;
        while (row > keyframe_positions[end_keyframe_index]) {
          end_keyframe_index++;
        }
        valid_frames.clear();
        start_keyframe_index = end_keyframe_index - 1;
        next_keyframe = keyframe_positions[end_keyframe_index];
      } else {
        end_keyframe_index++;
      }
    }
    valid_frames.push_back(row);
  }
  info.keyframe_index_intervals.push_back(
      std::make_tuple(start_keyframe_index, end_keyframe_index));
  info.valid_frames.push_back(valid_frames);
  return info;
}

}
<commit_msg>Attempt to fix scanner sampling<commit_after>/* Copyright 2016 Carnegie Mellon University
 *
 * 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 "scanner/engine/sampling.h"

namespace scanner {

// Gets the list of work items for a sequence of rows in the job
RowIntervals slice_into_row_intervals(const JobMetadata& job,
                                      const std::vector<i64>& rows) {
  RowIntervals info;
  // Analyze rows and job to determine what item ids and offsets in them to
  // sample from
  i32 io_item_size = job.io_item_size();
  auto item_from_row = [io_item_size](i64 r) -> i32 {
    return r / io_item_size;
  };
  auto offset_from_row = [io_item_size](i64 r) -> i64 {
    return r % io_item_size;
  };

  assert(!rows.empty());
  i32 current_item = item_from_row(rows[0]);
  i64 item_start = offset_from_row(rows[0]);
  i64 item_end = item_start + 1;
  std::vector<i64> valid_offsets;
  for (i64 row : rows) {
    i32 item = item_from_row(row);
    i64 item_offset = offset_from_row(row);
    if (item != current_item) {
      // Start a new item and push the current one into the list
      info.item_ids.push_back(current_item);
      info.item_intervals.push_back(std::make_tuple(item_start, item_end));
      info.valid_offsets.push_back(valid_offsets);

      current_item = item;
      item_start = item_offset;
      item_end = item_offset + 1;
      valid_offsets.clear();
    }

    valid_offsets.push_back(item_offset);
    item_end = item_offset + 1;
  }
  info.item_ids.push_back(current_item);
  info.item_intervals.push_back(std::make_tuple(item_start, item_end));
  info.valid_offsets.push_back(valid_offsets);

  return info;
}

VideoIntervals slice_into_video_intervals(
    const std::vector<i64>& keyframe_positions,
    const std::vector<i64>& rows) {
  VideoIntervals info;
  assert(keyframe_positions.size() >= 2);
  size_t start_keyframe_index = 0;
  size_t end_keyframe_index = 1;
  i64 next_keyframe = keyframe_positions[end_keyframe_index];
  std::vector<i64> valid_frames;
  for (i64 row : rows) {
    if (row >= next_keyframe) {
      assert(end_keyframe_index < keyframe_positions.size() - 1);
      next_keyframe = keyframe_positions[++end_keyframe_index];
      if (row >= next_keyframe) {
        // Skipped a keyframe, so make a new interval
        if (!valid_frames.empty()) {
          info.keyframe_index_intervals.push_back(
              std::make_tuple(start_keyframe_index, end_keyframe_index - 1));
          info.valid_frames.push_back(valid_frames);
        }

        while (row >= keyframe_positions[end_keyframe_index]) {
          end_keyframe_index++;
          assert(end_keyframe_index < keyframe_positions.size());
        }
        valid_frames.clear();
        start_keyframe_index = end_keyframe_index - 1;
        next_keyframe = keyframe_positions[end_keyframe_index];
      }
    }
    valid_frames.push_back(row);
  }
  info.keyframe_index_intervals.push_back(
      std::make_tuple(start_keyframe_index, end_keyframe_index));
  info.valid_frames.push_back(valid_frames);
  return info;
}

}
<|endoftext|>


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

// appleseed.cli headers.
#include "commandlinehandler.h"

// appleseed.shared headers.
#include "application/application.h"
#include "application/superlogger.h"

// appleseed.renderer headers.
#include "renderer/api/frame.h"
#include "renderer/api/project.h"
#include "renderer/api/rendering.h"
#include "renderer/api/utility.h"

// appleseed.foundation headers.
#include "foundation/platform/path.h"
#include "foundation/platform/timer.h"
#include "foundation/utility/autoreleaseptr.h"
#include "foundation/utility/benchmark.h"
#include "foundation/utility/filter.h"
#include "foundation/utility/log.h"
#include "foundation/utility/settings.h"
#include "foundation/utility/stopwatch.h"
#include "foundation/utility/string.h"
#include "foundation/utility/test.h"

// appleseed.main headers.
#include "main/allocator.h"

// boost headers.
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"

// Standard headers.
#include <cstddef>
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>

using namespace appleseed::cli;
using namespace appleseed::shared;
using namespace boost;
using namespace foundation;
using namespace renderer;
using namespace std;

namespace
{
    CommandLineHandler  g_cl;
    ParamArray          g_settings;

    void load_settings(Logger& logger)
    {
        const filesystem::path root_path(Application::get_root_path());
        const filesystem::path settings_file_path = root_path / "settings/appleseed.cli.xml";
        const filesystem::path schema_file_path = root_path / "schemas/settings.xsd";

        SettingsFileReader reader(logger);
        reader.read(
            settings_file_path.file_string().c_str(),
            schema_file_path.file_string().c_str(),
            g_settings);
    }

    template <typename Result>
    void print_suite_case_result(Logger& logger, const Result& result)
    {
        const size_t suite_exec = result.get_suite_execution_count();
        const size_t suite_fail = result.get_suite_failure_count();
        const size_t case_exec = result.get_case_execution_count();
        const size_t case_fail = result.get_case_failure_count();

        LOG_INFO(
            logger,
            "  suites      : %s executed, %s failed (%s)\n"
            "  cases       : %s executed, %s failed (%s)\n",
            pretty_uint(suite_exec).c_str(),
            pretty_uint(suite_fail).c_str(),
            pretty_percent(suite_fail, suite_exec).c_str(),
            pretty_uint(case_exec).c_str(),
            pretty_uint(case_fail).c_str(),
            pretty_percent(case_fail, case_exec).c_str());
    }

    void print_unit_test_result(Logger& logger, const TestResult& result)
    {
        LOG_INFO(logger, "unit testing summary:\n");
        print_suite_case_result(logger, result);

        const size_t assert_exec = result.get_assertion_execution_count();
        const size_t assert_fail = result.get_assertion_failure_count();

        LOG_INFO(
            logger,
            "  assertions  : %s executed, %s failed (%s)\n",
            pretty_uint(assert_exec).c_str(),
            pretty_uint(assert_fail).c_str(),
            pretty_percent(assert_fail, assert_exec).c_str());
    }

    void print_unit_benchmark_result(Logger& logger, const BenchmarkResult& result)
    {
        LOG_INFO(logger, "unit benchmarking summary:\n");
        print_suite_case_result(logger, result);
    }

    void run_unit_tests(Logger& logger)
    {
        // Create a test listener that outputs to the logger.
        auto_release_ptr<ITestListener> listener(
            create_logger_test_listener(
                logger,
                g_cl.m_verbose_unit_tests.is_set()));

        TestResult result;

        const filesystem::path old_current_path =
            Application::change_current_directory_to_tests_root_path();

        // Run test suites.
        if (g_cl.m_run_unit_tests.values().empty())
            TestSuiteRepository::instance().run(listener.ref(), result);
        else
        {
            const char* regex = g_cl.m_run_unit_tests.values().front().c_str();
            const RegExFilter filter(regex, RegExFilter::CaseInsensitive);

            if (filter.is_valid())
                TestSuiteRepository::instance().run(filter, listener.ref(), result);
            else
            {
                LOG_ERROR(
                    logger,
                    "malformed regular expression '%s', disabling test filtering",
                    regex);
                TestSuiteRepository::instance().run(listener.ref(), result);
            }
        }

        // Restore the current directory.
        filesystem::current_path(old_current_path);

        print_unit_test_result(logger, result);
    }

    void run_unit_benchmarks(Logger& logger)
    {
        BenchmarkResult result;

        // Add a benchmark listener that outputs to the logger.
        auto_release_ptr<IBenchmarkListener>
            logger_listener(create_logger_benchmark_listener(logger));
        result.add_listener(logger_listener.get());

        // Try to add a benchmark listener that outputs to a XML file.
        auto_release_ptr<XMLFileBenchmarkListener> xmlfile_listener(
            create_xmlfile_benchmark_listener());
        const string xmlfile_name = "benchmark." + get_time_stamp_string() + ".xml";
        const filesystem::path xmlfile_path =
              filesystem::path(Application::get_tests_root_path())
            / "unit benchmarks/results/"
            / xmlfile_name;
        if (xmlfile_listener->open(xmlfile_path.string().c_str()))
            result.add_listener(xmlfile_listener.get());
        else
        {
            RENDERER_LOG_WARNING(
                "automatic benchmark results archiving to %s failed: i/o error",
                xmlfile_path.string().c_str());
        }

        const filesystem::path old_current_path =
            Application::change_current_directory_to_tests_root_path();

        // Run benchmark suites.
        if (g_cl.m_run_unit_benchmarks.values().empty())
            BenchmarkSuiteRepository::instance().run(result);
        else
        {
            const char* regex = g_cl.m_run_unit_benchmarks.values().front().c_str();
            const RegExFilter filter(regex, RegExFilter::CaseInsensitive);

            if (filter.is_valid())
                BenchmarkSuiteRepository::instance().run(filter, result);
            else
            {
                LOG_ERROR(
                    logger,
                    "malformed regular expression '%s', disabling benchmark filtering",
                    regex);
                BenchmarkSuiteRepository::instance().run(result);
            }
        }

        // Restore the current directory.
        filesystem::current_path(old_current_path);

        // Print results.
        print_unit_benchmark_result(logger, result);
    }

    void apply_command_line_options(ParamArray& params)
    {
        // Apply rendering threads option.
        if (g_cl.m_rendering_threads.is_set())
        {
            params.insert_path(
                "generic_frame_renderer.rendering_threads",
                g_cl.m_rendering_threads.string_values()[0].c_str());
        }

        // Apply window option.
        if (g_cl.m_window.is_set())
        {
            const string window =
                  g_cl.m_window.string_values()[0] + ' ' +
                  g_cl.m_window.string_values()[1] + ' ' +
                  g_cl.m_window.string_values()[2] + ' ' +
                  g_cl.m_window.string_values()[3];
            params.insert_path("generic_tile_renderer.crop_window", window);
        }

        // Apply samples option.
        if (g_cl.m_samples.is_set())
        {
            params.insert_path(
                "generic_tile_renderer.min_samples",
                g_cl.m_samples.string_values()[0].c_str());
            params.insert_path(
                "generic_tile_renderer.max_samples",
                g_cl.m_samples.string_values()[1].c_str());
        }

        // Apply shading override option.
        if (g_cl.m_override_shading.is_set())
        {
            params.insert_path(
                "shading_engine.override_shading.mode",
                g_cl.m_override_shading.string_values()[0].c_str());
        }

        // Apply custom parameters.
        for (size_t i = 0; i < g_cl.m_params.values().size(); ++i)
        {
            // Retrieve the assignment string (of the form name=value).
            const string& s = g_cl.m_params.values()[i];

            // Retrieve the name and the value of the parameter.
            const string::size_type equal_pos = s.find_first_of('=');
            const string path = s.substr(0, equal_pos);
            const string value = s.substr(equal_pos + 1);

            // Insert the parameter.
            params.insert_path(path, value);
        }
    }

    void apply_resolution_command_line_option(Project* project)
    {
        if (g_cl.m_resolution.is_set())
        {
            const string resolution =
                  g_cl.m_resolution.string_values()[0] + ' ' +
                  g_cl.m_resolution.string_values()[1];

            const Frame* frame = project->get_frame();
            assert(frame);

            ParamArray new_frame_params = frame->get_parameters();
            new_frame_params.insert("resolution", resolution);

            auto_release_ptr<Frame> new_frame(
                FrameFactory::create(frame->get_name(), new_frame_params));

            project->set_frame(new_frame);
        }
    }

#if defined __APPLE__ || defined _WIN32

    // Invoke a system command to open an image file.
    void display_frame(const string& path)
    {
        const string quoted_path = "\"" + path + "\"";

#if defined __APPLE__
        const string command = "open " + quoted_path;
#elif defined _WIN32
        const string command = quoted_path;
#else
#error Unsupported platform.
#endif

        RENDERER_LOG_DEBUG("executing '%s'", command.c_str());
        std::system(command.c_str());   // needs std:: qualifier
    }

#endif

    void render_frame(
        Project&            project,
        const ParamArray&   params)
    {
        RENDERER_LOG_INFO("rendering frame...");

        // Create the master renderer.
        DefaultRendererController renderer_controller;
        MasterRenderer renderer(
            project,
            params,
            &renderer_controller);

        // Render the frame.
        Stopwatch<DefaultWallclockTimer> stopwatch;
        stopwatch.start();
        renderer.render();
        stopwatch.measure();

        // Print rendering time.
        const double seconds = stopwatch.get_seconds();
        RENDERER_LOG_INFO(
            "rendering finished in %s",
            pretty_time(seconds, 3).c_str());

        // Construct the path to the archive directory.
        const filesystem::path autosave_path =
              filesystem::path(Application::get_root_path())
            / "images/autosave/";

        // Archive the frame to disk.
        RENDERER_LOG_INFO("archiving frame to disk...");
        char* archive_path;
        project.get_frame()->archive(
            autosave_path.directory_string().c_str(),
            &archive_path);

        // Write the frame to disk.
        if (g_cl.m_output.is_set())
        {
            RENDERER_LOG_INFO("writing frame to disk...");
            project.get_frame()->write(g_cl.m_output.values()[0].c_str());
        }

#if defined __APPLE__ || defined _WIN32

        // Display the output image.
        if (g_cl.m_display_output.is_set())
            display_frame(archive_path);

#endif

        // Deallocate the memory used by the path to the archived image.
        free_string(archive_path);
    }

    void render_project(const string& project_filename)
    {
        auto_release_ptr<Project> project;

        const string builtin_prefix = "builtin:";
        if (project_filename.substr(0, builtin_prefix.size()) == builtin_prefix)
        {
            // Load the built-in project.
            ProjectFileReader reader;
            const string name = project_filename.substr(builtin_prefix.size());
            project = reader.load_builtin(name.c_str());
        }
        else
        {
            // Construct the schema filename.
            const filesystem::path schema_path =
                  filesystem::path(Application::get_root_path())
                / "schemas/project.xsd";

            // Load the project from disk.
            ProjectFileReader reader;
            project =
                reader.read(
                    project_filename.c_str(),
                    schema_path.file_string().c_str());
        }

        // Skip this project if loading failed.
        if (project.get() == 0)
            return;

        // Retrieve the name of the configuration to use.
        const string config_name = g_cl.m_configuration.is_set()
            ? g_cl.m_configuration.values()[0]
            : "final";

        // Retrieve the configuration.
        const Configuration* configuration =
            project->configurations().get_by_name(config_name.c_str());
        if (configuration == 0)
        {
            RENDERER_LOG_ERROR(
                "the configuration \"%s\" does not exist",
                config_name.c_str());
            return;
        }

        // Retrieve the parameters from the configuration.
        ParamArray params;
        if (configuration->get_base())
            params = configuration->get_base()->get_parameters();
        params.merge(g_settings);
        params.merge(configuration->get_parameters());

        // Apply command line options.
        apply_command_line_options(params);
        apply_resolution_command_line_option(project.get());

        // Render one frame of the project.
        render_frame(*project, params);
    }
}

//
// Entry point of appleseed.cli.
//

int main(int argc, const char* argv[])
{
    start_memory_tracking();

    SuperLogger logger;

    Application::check_installation(logger);

    g_cl.parse(argc, argv, logger);

    // Read the application's settings from disk.
    load_settings(logger);

    if (g_settings.get_optional<bool>("message_coloring", false))
        logger.enable_message_coloring();

    // Run unit tests.
    if (g_cl.m_run_unit_tests.is_set())
        run_unit_tests(logger);

    // Run unit benchmarks.
    if (g_cl.m_run_unit_benchmarks.is_set())
        run_unit_benchmarks(logger);

    global_logger().add_target(&logger.get_log_target());

    // Render the specified project.
    if (!g_cl.m_filenames.values().empty())
        render_project(g_cl.m_filenames.values().front());

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

// appleseed.cli headers.
#include "commandlinehandler.h"

// appleseed.shared headers.
#include "application/application.h"
#include "application/superlogger.h"

// appleseed.renderer headers.
#include "renderer/api/frame.h"
#include "renderer/api/project.h"
#include "renderer/api/rendering.h"
#include "renderer/api/utility.h"

// appleseed.foundation headers.
#include "foundation/platform/path.h"
#include "foundation/platform/timer.h"
#include "foundation/utility/autoreleaseptr.h"
#include "foundation/utility/benchmark.h"
#include "foundation/utility/filter.h"
#include "foundation/utility/log.h"
#include "foundation/utility/settings.h"
#include "foundation/utility/stopwatch.h"
#include "foundation/utility/string.h"
#include "foundation/utility/test.h"

// appleseed.main headers.
#include "main/allocator.h"

// boost headers.
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"

// Standard headers.
#include <cstddef>
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>

using namespace appleseed::cli;
using namespace appleseed::shared;
using namespace boost;
using namespace foundation;
using namespace renderer;
using namespace std;

namespace
{
    CommandLineHandler  g_cl;
    ParamArray          g_settings;

    void load_settings(Logger& logger)
    {
        const filesystem::path root_path(Application::get_root_path());
        const filesystem::path settings_file_path = root_path / "settings/appleseed.cli.xml";
        const filesystem::path schema_file_path = root_path / "schemas/settings.xsd";

        SettingsFileReader reader(logger);
        reader.read(
            settings_file_path.file_string().c_str(),
            schema_file_path.file_string().c_str(),
            g_settings);
    }

    template <typename Result>
    void print_suite_case_result(Logger& logger, const Result& result)
    {
        const size_t suite_exec = result.get_suite_execution_count();
        const size_t suite_fail = result.get_suite_failure_count();
        const size_t case_exec = result.get_case_execution_count();
        const size_t case_fail = result.get_case_failure_count();

        LOG_INFO(
            logger,
            "  suites      : %s executed, %s failed (%s)\n"
            "  cases       : %s executed, %s failed (%s)\n",
            pretty_uint(suite_exec).c_str(),
            pretty_uint(suite_fail).c_str(),
            pretty_percent(suite_fail, suite_exec).c_str(),
            pretty_uint(case_exec).c_str(),
            pretty_uint(case_fail).c_str(),
            pretty_percent(case_fail, case_exec).c_str());
    }

    void print_unit_test_result(Logger& logger, const TestResult& result)
    {
        LOG_INFO(logger, "unit testing summary:\n");
        print_suite_case_result(logger, result);

        const size_t assert_exec = result.get_assertion_execution_count();
        const size_t assert_fail = result.get_assertion_failure_count();

        LOG_INFO(
            logger,
            "  assertions  : %s executed, %s failed (%s)\n",
            pretty_uint(assert_exec).c_str(),
            pretty_uint(assert_fail).c_str(),
            pretty_percent(assert_fail, assert_exec).c_str());
    }

    void print_unit_benchmark_result(Logger& logger, const BenchmarkResult& result)
    {
        LOG_INFO(logger, "unit benchmarking summary:\n");
        print_suite_case_result(logger, result);
    }

    void run_unit_tests(Logger& logger)
    {
        // Create a test listener that outputs to the logger.
        auto_release_ptr<ITestListener> listener(
            create_logger_test_listener(
                logger,
                g_cl.m_verbose_unit_tests.is_set()));

        TestResult result;

        const filesystem::path old_current_path =
            Application::change_current_directory_to_tests_root_path();

        // Run test suites.
        if (g_cl.m_run_unit_tests.values().empty())
            TestSuiteRepository::instance().run(listener.ref(), result);
        else
        {
            const char* regex = g_cl.m_run_unit_tests.values().front().c_str();
            const RegExFilter filter(regex, RegExFilter::CaseInsensitive);

            if (filter.is_valid())
                TestSuiteRepository::instance().run(filter, listener.ref(), result);
            else
            {
                LOG_ERROR(
                    logger,
                    "malformed regular expression '%s', disabling test filtering",
                    regex);
                TestSuiteRepository::instance().run(listener.ref(), result);
            }
        }

        // Restore the current directory.
        filesystem::current_path(old_current_path);

        print_unit_test_result(logger, result);
    }

    void run_unit_benchmarks(Logger& logger)
    {
        BenchmarkResult result;

        // Add a benchmark listener that outputs to the logger.
        auto_release_ptr<IBenchmarkListener>
            logger_listener(create_logger_benchmark_listener(logger));
        result.add_listener(logger_listener.get());

        // Try to add a benchmark listener that outputs to a XML file.
        auto_release_ptr<XMLFileBenchmarkListener> xmlfile_listener(
            create_xmlfile_benchmark_listener());
        const string xmlfile_name = "benchmark." + get_time_stamp_string() + ".xml";
        const filesystem::path xmlfile_path =
              filesystem::path(Application::get_tests_root_path())
            / "unit benchmarks/results/"
            / xmlfile_name;
        if (xmlfile_listener->open(xmlfile_path.string().c_str()))
            result.add_listener(xmlfile_listener.get());
        else
        {
            RENDERER_LOG_WARNING(
                "automatic benchmark results archiving to %s failed: i/o error",
                xmlfile_path.native_file_string().c_str());
        }

        const filesystem::path old_current_path =
            Application::change_current_directory_to_tests_root_path();

        // Run benchmark suites.
        if (g_cl.m_run_unit_benchmarks.values().empty())
            BenchmarkSuiteRepository::instance().run(result);
        else
        {
            const char* regex = g_cl.m_run_unit_benchmarks.values().front().c_str();
            const RegExFilter filter(regex, RegExFilter::CaseInsensitive);

            if (filter.is_valid())
                BenchmarkSuiteRepository::instance().run(filter, result);
            else
            {
                LOG_ERROR(
                    logger,
                    "malformed regular expression '%s', disabling benchmark filtering",
                    regex);
                BenchmarkSuiteRepository::instance().run(result);
            }
        }

        // Restore the current directory.
        filesystem::current_path(old_current_path);

        // Print results.
        print_unit_benchmark_result(logger, result);
    }

    void apply_command_line_options(ParamArray& params)
    {
        // Apply rendering threads option.
        if (g_cl.m_rendering_threads.is_set())
        {
            params.insert_path(
                "generic_frame_renderer.rendering_threads",
                g_cl.m_rendering_threads.string_values()[0].c_str());
        }

        // Apply window option.
        if (g_cl.m_window.is_set())
        {
            const string window =
                  g_cl.m_window.string_values()[0] + ' ' +
                  g_cl.m_window.string_values()[1] + ' ' +
                  g_cl.m_window.string_values()[2] + ' ' +
                  g_cl.m_window.string_values()[3];
            params.insert_path("generic_tile_renderer.crop_window", window);
        }

        // Apply samples option.
        if (g_cl.m_samples.is_set())
        {
            params.insert_path(
                "generic_tile_renderer.min_samples",
                g_cl.m_samples.string_values()[0].c_str());
            params.insert_path(
                "generic_tile_renderer.max_samples",
                g_cl.m_samples.string_values()[1].c_str());
        }

        // Apply shading override option.
        if (g_cl.m_override_shading.is_set())
        {
            params.insert_path(
                "shading_engine.override_shading.mode",
                g_cl.m_override_shading.string_values()[0].c_str());
        }

        // Apply custom parameters.
        for (size_t i = 0; i < g_cl.m_params.values().size(); ++i)
        {
            // Retrieve the assignment string (of the form name=value).
            const string& s = g_cl.m_params.values()[i];

            // Retrieve the name and the value of the parameter.
            const string::size_type equal_pos = s.find_first_of('=');
            const string path = s.substr(0, equal_pos);
            const string value = s.substr(equal_pos + 1);

            // Insert the parameter.
            params.insert_path(path, value);
        }
    }

    void apply_resolution_command_line_option(Project* project)
    {
        if (g_cl.m_resolution.is_set())
        {
            const string resolution =
                  g_cl.m_resolution.string_values()[0] + ' ' +
                  g_cl.m_resolution.string_values()[1];

            const Frame* frame = project->get_frame();
            assert(frame);

            ParamArray new_frame_params = frame->get_parameters();
            new_frame_params.insert("resolution", resolution);

            auto_release_ptr<Frame> new_frame(
                FrameFactory::create(frame->get_name(), new_frame_params));

            project->set_frame(new_frame);
        }
    }

#if defined __APPLE__ || defined _WIN32

    // Invoke a system command to open an image file.
    void display_frame(const string& path)
    {
        const string quoted_path = "\"" + path + "\"";

#if defined __APPLE__
        const string command = "open " + quoted_path;
#elif defined _WIN32
        const string command = quoted_path;
#else
#error Unsupported platform.
#endif

        RENDERER_LOG_DEBUG("executing '%s'", command.c_str());
        std::system(command.c_str());   // needs std:: qualifier
    }

#endif

    void render_frame(
        Project&            project,
        const ParamArray&   params)
    {
        RENDERER_LOG_INFO("rendering frame...");

        // Create the master renderer.
        DefaultRendererController renderer_controller;
        MasterRenderer renderer(
            project,
            params,
            &renderer_controller);

        // Render the frame.
        Stopwatch<DefaultWallclockTimer> stopwatch;
        stopwatch.start();
        renderer.render();
        stopwatch.measure();

        // Print rendering time.
        const double seconds = stopwatch.get_seconds();
        RENDERER_LOG_INFO(
            "rendering finished in %s",
            pretty_time(seconds, 3).c_str());

        // Construct the path to the archive directory.
        const filesystem::path autosave_path =
              filesystem::path(Application::get_root_path())
            / "images/autosave/";

        // Archive the frame to disk.
        RENDERER_LOG_INFO("archiving frame to disk...");
        char* archive_path;
        project.get_frame()->archive(
            autosave_path.directory_string().c_str(),
            &archive_path);

        // Write the frame to disk.
        if (g_cl.m_output.is_set())
        {
            RENDERER_LOG_INFO("writing frame to disk...");
            project.get_frame()->write(g_cl.m_output.values()[0].c_str());
        }

#if defined __APPLE__ || defined _WIN32

        // Display the output image.
        if (g_cl.m_display_output.is_set())
            display_frame(archive_path);

#endif

        // Deallocate the memory used by the path to the archived image.
        free_string(archive_path);
    }

    void render_project(const string& project_filename)
    {
        auto_release_ptr<Project> project;

        const string builtin_prefix = "builtin:";
        if (project_filename.substr(0, builtin_prefix.size()) == builtin_prefix)
        {
            // Load the built-in project.
            ProjectFileReader reader;
            const string name = project_filename.substr(builtin_prefix.size());
            project = reader.load_builtin(name.c_str());
        }
        else
        {
            // Construct the schema filename.
            const filesystem::path schema_path =
                  filesystem::path(Application::get_root_path())
                / "schemas/project.xsd";

            // Load the project from disk.
            ProjectFileReader reader;
            project =
                reader.read(
                    project_filename.c_str(),
                    schema_path.file_string().c_str());
        }

        // Skip this project if loading failed.
        if (project.get() == 0)
            return;

        // Retrieve the name of the configuration to use.
        const string config_name = g_cl.m_configuration.is_set()
            ? g_cl.m_configuration.values()[0]
            : "final";

        // Retrieve the configuration.
        const Configuration* configuration =
            project->configurations().get_by_name(config_name.c_str());
        if (configuration == 0)
        {
            RENDERER_LOG_ERROR(
                "the configuration \"%s\" does not exist",
                config_name.c_str());
            return;
        }

        // Retrieve the parameters from the configuration.
        ParamArray params;
        if (configuration->get_base())
            params = configuration->get_base()->get_parameters();
        params.merge(g_settings);
        params.merge(configuration->get_parameters());

        // Apply command line options.
        apply_command_line_options(params);
        apply_resolution_command_line_option(project.get());

        // Render one frame of the project.
        render_frame(*project, params);
    }
}

//
// Entry point of appleseed.cli.
//

int main(int argc, const char* argv[])
{
    start_memory_tracking();

    SuperLogger logger;

    Application::check_installation(logger);

    g_cl.parse(argc, argv, logger);

    // Read the application's settings from disk.
    load_settings(logger);

    if (g_settings.get_optional<bool>("message_coloring", false))
        logger.enable_message_coloring();

    // Run unit tests.
    if (g_cl.m_run_unit_tests.is_set())
        run_unit_tests(logger);

    // Run unit benchmarks.
    if (g_cl.m_run_unit_benchmarks.is_set())
        run_unit_benchmarks(logger);

    global_logger().add_target(&logger.get_log_target());

    // Render the specified project.
    if (!g_cl.m_filenames.values().empty())
        render_project(g_cl.m_filenames.values().front());

    return 0;
}
<|endoftext|>


<commit_before>#pragma once

namespace rc {
namespace detail {

template <typename... Types>
struct IndexHelper;

template <>
struct IndexHelper<> {
  template <typename T>
  static constexpr std::size_t indexOf() {
    return 0;
  }
};

template <typename First, typename... Types>
struct IndexHelper<First, Types...> {
  template <typename T>
  static constexpr std::size_t indexOf() {
    return std::is_same<First, T>::value
        ? 0
        : IndexHelper<Types...>::template indexOf<T>() + 1;
  }
};

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...>::Variant(T &&value) noexcept(
    std::is_nothrow_constructible<Decay<T>, T &&>::value)
    : m_typeIndex(indexOfType<Decay<T>>()) {
  static_assert(isValidType<Decay<T>>(),
                "T is not a valid type of this variant");

  new (&m_storage) Decay<T>(std::forward<T>(value));
}

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(const T &value) noexcept {
  static_assert(isValidType<T>(), "T is not a valid type of this variant");

  const auto newIndex = indexOfType<T>();
  if (newIndex == m_typeIndex) {
    *reinterpret_cast<T *>(&m_storage) = value;
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = newIndex;
    new (&m_storage) T(value);
  }
  return *this;
}

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(T &&value) noexcept {
  static_assert(isValidType<T>(), "T is not a valid type of this variant");

  const auto newIndex = indexOfType<T>();
  if (newIndex == m_typeIndex) {
    *reinterpret_cast<T *>(&m_storage) = std::move(value);
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = newIndex;
    new (&m_storage) T(std::move(value));
  }
  return *this;
}

template <typename Type, typename... Types>
template <typename T>
T &Variant<Type, Types...>::get() & {
  assert(indexOfType<T>() == m_typeIndex);
  return *reinterpret_cast<T *>(&m_storage);
}

template <typename Type, typename... Types>
template <typename T>
const T &Variant<Type, Types...>::get() const & {
  assert(indexOfType<T>() == m_typeIndex);
  return *reinterpret_cast<const T *>(&m_storage);
}

template <typename Type, typename... Types>
template <typename T>
T &&Variant<Type, Types...>::get() && {
  return std::move(get<T>());
}

// TODO this would be more fun with varargs and lambdas
template <typename Type, typename... Types>
template <typename T>
bool Variant<Type, Types...>::match(T &value) const {
  if (!is<T>()) {
    return false;
  }

  value = *reinterpret_cast<const T *>(&m_storage);
  return true;
}

template <typename Type, typename... Types>
template <typename T>
bool Variant<Type, Types...>::is() const {
  static_assert(isValidType<Decay<T>>(),
                "T is not a valid type of this variant");
  return m_typeIndex == indexOfType<T>();
}

template <typename T>
bool variantEqualsImpl(const void *lhs, const void *rhs) {
  return *static_cast<const T *>(lhs) == *static_cast<const T *>(rhs);
}

template <typename Type, typename... Types>
bool Variant<Type, Types...>::operator==(const Variant &rhs) const {
  if (m_typeIndex != rhs.m_typeIndex) {
    return false;
  }

  constexpr bool (*const equalsFuncs[])(const void *, const void *) = {
      &variantEqualsImpl<Type>, &variantEqualsImpl<Types>...};

  return equalsFuncs[m_typeIndex](&m_storage, &rhs.m_storage);
}

template <typename T>
void variantPrintToImpl(std::ostream &os, const void *storage) {
  os << *static_cast<const T *>(storage);
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::printTo(std::ostream &os) const {
  constexpr void (*printToFuncs[])(std::ostream &, const void *) = {
      &variantPrintToImpl<Type>, &variantPrintToImpl<Types>...};

  printToFuncs[m_typeIndex](os, &m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...>::Variant(const Variant &other) noexcept(
    AllIs<std::is_nothrow_copy_constructible, Type, Types...>::value)
    : m_typeIndex(other.m_typeIndex) {
  copy(m_typeIndex, &m_storage, &other.m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...>::Variant(Variant &&other) noexcept(
    AllIs<std::is_nothrow_move_constructible, Type, Types...>::value)
    : m_typeIndex(other.m_typeIndex) {
  move(m_typeIndex, &m_storage, &other.m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(const Variant &rhs) noexcept(
    AllIs<std::is_nothrow_copy_constructible, Type, Types...>::value
        &&AllIs<std::is_nothrow_copy_assignable, Type, Types...>::value) {
  static_assert(
      AllIs<std::is_nothrow_move_constructible, Type, Types...>::value,
      "AllIs types must be nothrow move-constructible to use copy assignment");

  if (m_typeIndex == rhs.m_typeIndex) {
    copyAssign(m_typeIndex, &m_storage, &rhs.m_storage);
  } else {
    Storage tmp;
    copy(rhs.m_typeIndex, &tmp, &rhs.m_storage);
    destroy(m_typeIndex, &m_storage);
    move(rhs.m_typeIndex, &m_storage, &tmp);
    m_typeIndex = rhs.m_typeIndex;
  }

  return *this;
}

template <typename Type, typename... Types>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(Variant &&rhs) noexcept(
    AllIs<std::is_nothrow_move_assignable, Type, Types...>::value) {
  static_assert(
      AllIs<std::is_nothrow_move_constructible, Type, Types...>::value,
      "AllIs types must be nothrow move-constructible to use copy assignment");

  if (m_typeIndex == rhs.m_typeIndex) {
    moveAssign(m_typeIndex, &m_storage, &rhs.m_storage);
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = rhs.m_typeIndex;
    move(m_typeIndex, &m_storage, &rhs.m_storage);
  }

  return *this;
}

template <typename Type, typename... Types>
Variant<Type, Types...>::~Variant() noexcept {
  destroy(m_typeIndex, &m_storage);
}

template <typename T>
void variantCopyAssign(void *to, const void *from) {
  *static_cast<T *>(to) = *static_cast<const T *>(from);
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::copyAssign(std::size_t index,
                                         void *to,
                                         const void *from) {
  constexpr void (*const copyAssignFuncs[])(void *, const void *) = {
      &variantCopyAssign<Type>, &variantCopyAssign<Types>...};

  copyAssignFuncs[index](to, from);
}

template <typename T>
void variantMoveAssign(void *to, void *from) {
  *static_cast<T *>(to) = std::move(*static_cast<T *>(from));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::moveAssign(std::size_t index,
                                         void *to,
                                         void *from) {
  constexpr void (*const moveAssignFuncs[])(void *, void *) = {
      &variantMoveAssign<Type>, &variantMoveAssign<Types>...};

  moveAssignFuncs[index](to, from);
}

template <typename T>
void variantCopy(void *to, const void *from) {
  new (to) T(*static_cast<const T *>(from));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::copy(std::size_t index,
                                   void *to,
                                   const void *from) {
  constexpr void (*const copyFuncs[])(void *, const void *) = {
      &variantCopy<Type>, &variantCopy<Types>...};

  copyFuncs[index](to, from);
}

template <typename T>
void variantMove(void *to, void *from) {
  new (to) T(std::move(*static_cast<T *>(from)));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::move(std::size_t index, void *to, void *from) {
  constexpr void (*const moveFuncs[])(void *, void *) = {
      &variantMove<Type>, &variantMove<Types>...};

  moveFuncs[index](to, from);
}

template <typename T>
void variantDestroy(void *storage) {
  static_cast<T *>(storage)->~T();
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::destroy(std::size_t index,
                                      void *storage) noexcept {
  constexpr void (*const destroyFuncs[])(void *) = {&variantDestroy<Type>,
                                                    &variantDestroy<Types>...};

  destroyFuncs[index](storage);
}

template <typename Type, typename... Types>
template <typename T>
constexpr std::size_t Variant<Type, Types...>::indexOfType() {
  return IndexHelper<Type, Types...>::template indexOf<T>();
}

template <typename Type, typename... Types>
template <typename T>
constexpr bool Variant<Type, Types...>::isValidType() {
  return indexOfType<T>() < (sizeof...(Types) + 1);
}

template <typename Type, typename... Types>
bool operator!=(const Variant<Type, Types...> &lhs,
                const Variant<Type, Types...> &rhs) {
  return !(lhs == rhs);
}

template <typename Type, typename... Types, typename>
std::ostream &operator<<(std::ostream &os,
                         const Variant<Type, Types...> &value) {
  value.printTo(os);
  return os;
}

} // namespace detail
} // namespace rc
<commit_msg>constexpr -> static for jump tables in Variant<commit_after>#pragma once

namespace rc {
namespace detail {

template <typename... Types>
struct IndexHelper;

template <>
struct IndexHelper<> {
  template <typename T>
  static constexpr std::size_t indexOf() {
    return 0;
  }
};

template <typename First, typename... Types>
struct IndexHelper<First, Types...> {
  template <typename T>
  static constexpr std::size_t indexOf() {
    return std::is_same<First, T>::value
        ? 0
        : IndexHelper<Types...>::template indexOf<T>() + 1;
  }
};

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...>::Variant(T &&value) noexcept(
    std::is_nothrow_constructible<Decay<T>, T &&>::value)
    : m_typeIndex(indexOfType<Decay<T>>()) {
  static_assert(isValidType<Decay<T>>(),
                "T is not a valid type of this variant");

  new (&m_storage) Decay<T>(std::forward<T>(value));
}

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(const T &value) noexcept {
  static_assert(isValidType<T>(), "T is not a valid type of this variant");

  const auto newIndex = indexOfType<T>();
  if (newIndex == m_typeIndex) {
    *reinterpret_cast<T *>(&m_storage) = value;
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = newIndex;
    new (&m_storage) T(value);
  }
  return *this;
}

template <typename Type, typename... Types>
template <typename T, typename>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(T &&value) noexcept {
  static_assert(isValidType<T>(), "T is not a valid type of this variant");

  const auto newIndex = indexOfType<T>();
  if (newIndex == m_typeIndex) {
    *reinterpret_cast<T *>(&m_storage) = std::move(value);
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = newIndex;
    new (&m_storage) T(std::move(value));
  }
  return *this;
}

template <typename Type, typename... Types>
template <typename T>
T &Variant<Type, Types...>::get() & {
  assert(indexOfType<T>() == m_typeIndex);
  return *reinterpret_cast<T *>(&m_storage);
}

template <typename Type, typename... Types>
template <typename T>
const T &Variant<Type, Types...>::get() const & {
  assert(indexOfType<T>() == m_typeIndex);
  return *reinterpret_cast<const T *>(&m_storage);
}

template <typename Type, typename... Types>
template <typename T>
T &&Variant<Type, Types...>::get() && {
  return std::move(get<T>());
}

// TODO this would be more fun with varargs and lambdas
template <typename Type, typename... Types>
template <typename T>
bool Variant<Type, Types...>::match(T &value) const {
  if (!is<T>()) {
    return false;
  }

  value = *reinterpret_cast<const T *>(&m_storage);
  return true;
}

template <typename Type, typename... Types>
template <typename T>
bool Variant<Type, Types...>::is() const {
  static_assert(isValidType<Decay<T>>(),
                "T is not a valid type of this variant");
  return m_typeIndex == indexOfType<T>();
}

template <typename T>
bool variantEqualsImpl(const void *lhs, const void *rhs) {
  return *static_cast<const T *>(lhs) == *static_cast<const T *>(rhs);
}

template <typename Type, typename... Types>
bool Variant<Type, Types...>::operator==(const Variant &rhs) const {
  if (m_typeIndex != rhs.m_typeIndex) {
    return false;
  }

  static bool (*const equalsFuncs[])(const void *, const void *) = {
      &variantEqualsImpl<Type>, &variantEqualsImpl<Types>...};

  return equalsFuncs[m_typeIndex](&m_storage, &rhs.m_storage);
}

template <typename T>
void variantPrintToImpl(std::ostream &os, const void *storage) {
  os << *static_cast<const T *>(storage);
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::printTo(std::ostream &os) const {
  static void (*printToFuncs[])(std::ostream &, const void *) = {
      &variantPrintToImpl<Type>, &variantPrintToImpl<Types>...};

  printToFuncs[m_typeIndex](os, &m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...>::Variant(const Variant &other) noexcept(
    AllIs<std::is_nothrow_copy_constructible, Type, Types...>::value)
    : m_typeIndex(other.m_typeIndex) {
  copy(m_typeIndex, &m_storage, &other.m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...>::Variant(Variant &&other) noexcept(
    AllIs<std::is_nothrow_move_constructible, Type, Types...>::value)
    : m_typeIndex(other.m_typeIndex) {
  move(m_typeIndex, &m_storage, &other.m_storage);
}

template <typename Type, typename... Types>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(const Variant &rhs) noexcept(
    AllIs<std::is_nothrow_copy_constructible, Type, Types...>::value
        &&AllIs<std::is_nothrow_copy_assignable, Type, Types...>::value) {
  static_assert(
      AllIs<std::is_nothrow_move_constructible, Type, Types...>::value,
      "AllIs types must be nothrow move-constructible to use copy assignment");

  if (m_typeIndex == rhs.m_typeIndex) {
    copyAssign(m_typeIndex, &m_storage, &rhs.m_storage);
  } else {
    Storage tmp;
    copy(rhs.m_typeIndex, &tmp, &rhs.m_storage);
    destroy(m_typeIndex, &m_storage);
    move(rhs.m_typeIndex, &m_storage, &tmp);
    m_typeIndex = rhs.m_typeIndex;
  }

  return *this;
}

template <typename Type, typename... Types>
Variant<Type, Types...> &Variant<Type, Types...>::
operator=(Variant &&rhs) noexcept(
    AllIs<std::is_nothrow_move_assignable, Type, Types...>::value) {
  static_assert(
      AllIs<std::is_nothrow_move_constructible, Type, Types...>::value,
      "AllIs types must be nothrow move-constructible to use copy assignment");

  if (m_typeIndex == rhs.m_typeIndex) {
    moveAssign(m_typeIndex, &m_storage, &rhs.m_storage);
  } else {
    destroy(m_typeIndex, &m_storage);
    m_typeIndex = rhs.m_typeIndex;
    move(m_typeIndex, &m_storage, &rhs.m_storage);
  }

  return *this;
}

template <typename Type, typename... Types>
Variant<Type, Types...>::~Variant() noexcept {
  destroy(m_typeIndex, &m_storage);
}

template <typename T>
void variantCopyAssign(void *to, const void *from) {
  *static_cast<T *>(to) = *static_cast<const T *>(from);
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::copyAssign(std::size_t index,
                                         void *to,
                                         const void *from) {
  static void (*const copyAssignFuncs[])(void *, const void *) = {
      &variantCopyAssign<Type>, &variantCopyAssign<Types>...};

  copyAssignFuncs[index](to, from);
}

template <typename T>
void variantMoveAssign(void *to, void *from) {
  *static_cast<T *>(to) = std::move(*static_cast<T *>(from));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::moveAssign(std::size_t index,
                                         void *to,
                                         void *from) {
  static void (*const moveAssignFuncs[])(void *, void *) = {
      &variantMoveAssign<Type>, &variantMoveAssign<Types>...};

  moveAssignFuncs[index](to, from);
}

template <typename T>
void variantCopy(void *to, const void *from) {
  new (to) T(*static_cast<const T *>(from));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::copy(std::size_t index,
                                   void *to,
                                   const void *from) {
  static void (*const copyFuncs[])(void *, const void *) = {
      &variantCopy<Type>, &variantCopy<Types>...};

  copyFuncs[index](to, from);
}

template <typename T>
void variantMove(void *to, void *from) {
  new (to) T(std::move(*static_cast<T *>(from)));
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::move(std::size_t index, void *to, void *from) {
  static void (*const moveFuncs[])(void *, void *) = {&variantMove<Type>,
                                                      &variantMove<Types>...};

  moveFuncs[index](to, from);
}

template <typename T>
void variantDestroy(void *storage) {
  static_cast<T *>(storage)->~T();
}

template <typename Type, typename... Types>
void Variant<Type, Types...>::destroy(std::size_t index,
                                      void *storage) noexcept {
  static void (*const destroyFuncs[])(void *) = {&variantDestroy<Type>,
                                                 &variantDestroy<Types>...};

  destroyFuncs[index](storage);
}

template <typename Type, typename... Types>
template <typename T>
constexpr std::size_t Variant<Type, Types...>::indexOfType() {
  return IndexHelper<Type, Types...>::template indexOf<T>();
}

template <typename Type, typename... Types>
template <typename T>
constexpr bool Variant<Type, Types...>::isValidType() {
  return indexOfType<T>() < (sizeof...(Types) + 1);
}

template <typename Type, typename... Types>
bool operator!=(const Variant<Type, Types...> &lhs,
                const Variant<Type, Types...> &rhs) {
  return !(lhs == rhs);
}

template <typename Type, typename... Types, typename>
std::ostream &operator<<(std::ostream &os,
                         const Variant<Type, Types...> &value) {
  value.printTo(os);
  return os;
}

} // namespace detail
} // namespace rc
<|endoftext|>