<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

/*
  MUONCheckMisAligner:

  This macro performs the misalignment on an existing muon arm geometry
  based on the standard definition of the detector elements in
  $ALICE_ROOT/MUON/data

  It uses AliMUONGeometryAligner :
  --> creates a new AliMUONGeometryTransformer and AliMUONGeometryAligner
  --> reads the transformations in from the transform.dat file (make sure that
  this file is the _standard_ one by comparing it to the one in CVS)
  --> creates a second AliMUONGeometryTransformer by misaligning the existing
  one using AliMUONAligner::MisAlign
  --> User has to specify the magnitude of the alignments, in the Cartesian
  co-ordiantes (which are used to apply translation misalignments) and in the
  spherical co-ordinates (which are used to apply angular displacements)
  --> User can also set misalignment ranges by hand using the methods :
  SetMaxCartMisAlig, SetMaxAngMisAlig, SetXYAngMisAligFactor
  (last method takes account of the fact that the misalingment is greatest in
  the XY plane, since the detection elements are fixed to a support structure
  in this plane. Misalignments in the XZ and YZ plane will be very small
  compared to those in the XY plane, which are small already - of the order
  of microns)
  --> Default behavior generates a "residual" misalignment using gaussian
  distributions. Uniform distributions can still be used, see
  AliMUONGeometryAligner.
  Note : If the detection elements are allowed to be misaligned in all
  directions, this has consequences for the alignment algorithm, which
  needs to know the number of free parameters. Eric only allowed 3 :
  x,y,theta_xy, but in principle z and the other two angles are alignable
  as well.

// Author:Bruce Becker

*/

void MUONCheckMisAligner(Double_t xcartmisaligm = 0.0, Double_t xcartmisaligw = 0.004,
			 Double_t ycartmisaligm = 0.0, Double_t ycartmisaligw = 0.003,
			 Double_t angmisaligm = 0.0, Double_t angmisaligw = 0.0023)
{

  AliMUONGeometryTransformer *transform = new AliMUONGeometryTransformer(true);
  transform->ReadGeometryData("volpath.dat", "transform.dat");

  AliMUONGeometryMisAligner misAligner(xcartmisaligm,xcartmisaligw,
                                       ycartmisaligm,ycartmisaligw,
				       angmisaligm,angmisaligw);

  // Generate mis alignment data
  AliMUONGeometryTransformer *newTransform = misAligner.MisAlign(transform,true);
  newTransform->WriteTransformations("transform2.dat");
  newTransform->WriteMisAlignmentData("misalign.root");

  // Apply misAlignment via AliRoot framework
  TGeoManager::Import("geometry.root");
  AliRun::ApplyAlignObjsToGeom(
     const_cast<TClonesArray*>(newTransform->GetMisAlignmentData()));
  // Save new geometry file
  gGeoManager->Export("geometry2.root");

  // Extract new transformations
  AliMUONGeometryTransformer* transform3 = new AliMUONGeometryTransformer(true);
  transform3->ReadGeometryData("volpath.dat", "geometry2.root");
  transform3->WriteTransformations("transform3.dat");
               // Check that transform3.dat is equal to transform2.dat

  // Generate misaligned data in local cdb
  TClonesArray* array = newTransform->GetMisAlignmentData();

  // CDB manager
  AliCDBManager* cdbManager = AliCDBManager::Instance();
  cdbManager->SetDefaultStorage("local://ResMisAlignCDB");

  AliCDBMetaData* cdbData = new AliCDBMetaData();
  cdbData->SetResponsible("Dimuon Offline project");
  cdbData->SetComment("MUON alignment objects with residual misalignment");
  AliCDBId id("MUON/Align/Data", 0, 0);
  cdbManager->Put(array, id, cdbData);

  // To run simulation with misaligned geometry, you have to set
  // the Align option in Config.C:
  // MUON->SetAlign("transform2.dat");
}

<commit_msg>Adding nameCDB  argument; updated for modifs in STEER (Javier)<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

/*
  MUONCheckMisAligner:

  This macro performs the misalignment on an existing muon arm geometry
  based on the standard definition of the detector elements in
  $ALICE_ROOT/MUON/data

  It uses AliMUONGeometryAligner :
  --> creates a new AliMUONGeometryTransformer and AliMUONGeometryAligner
  --> reads the transformations in from the transform.dat file (make sure that
  this file is the _standard_ one by comparing it to the one in CVS)
  --> creates a second AliMUONGeometryTransformer by misaligning the existing
  one using AliMUONAligner::MisAlign
  --> User has to specify the magnitude of the alignments, in the Cartesian
  co-ordiantes (which are used to apply translation misalignments) and in the
  spherical co-ordinates (which are used to apply angular displacements)
  --> User can also set misalignment ranges by hand using the methods :
  SetMaxCartMisAlig, SetMaxAngMisAlig, SetXYAngMisAligFactor
  (last method takes account of the fact that the misalingment is greatest in
  the XY plane, since the detection elements are fixed to a support structure
  in this plane. Misalignments in the XZ and YZ plane will be very small
  compared to those in the XY plane, which are small already - of the order
  of microns)
  --> Default behavior generates a "residual" misalignment using gaussian
  distributions. Uniform distributions can still be used, see
  AliMUONGeometryAligner.
  Note : If the detection elements are allowed to be misaligned in all
  directions, this has consequences for the alignment algorithm, which
  needs to know the number of free parameters. Eric only allowed 3 :
  x,y,theta_xy, but in principle z and the other two angles are alignable
  as well.

// Author:Bruce Becker

*/

void MUONCheckMisAligner(Double_t xcartmisaligm = 0.0, Double_t xcartmisaligw = 0.004,
			 Double_t ycartmisaligm = 0.0, Double_t ycartmisaligw = 0.003,
			 Double_t angmisaligm = 0.0, Double_t angmisaligw = 0.0023,
			 TString nameCDB = "ResMisAlignCDB")
{

  AliMUONGeometryTransformer *transform = new AliMUONGeometryTransformer(true);
  transform->ReadGeometryData("volpath.dat", "transform.dat");
  if (gSystem->AccessPathName("geometry.root",kFileExists))
    gGeoManager->Export("geometry.root");
  AliMUONGeometryMisAligner misAligner(xcartmisaligm,xcartmisaligw,
                                       ycartmisaligm,ycartmisaligw,
				       angmisaligm,angmisaligw);

  // Generate mis alignment data
  AliMUONGeometryTransformer *newTransform = misAligner.MisAlign(transform,true);
  newTransform->WriteTransformations("transform2.dat");
  newTransform->WriteMisAlignmentData("misalign.root");

  // Apply misAlignment via AliRoot framework
  TGeoManager::Import("geometry.root");
  AliSimulation::ApplyAlignObjsToGeom(
     const_cast<TClonesArray*>(newTransform->GetMisAlignmentData()));
  // Save new geometry file
  gGeoManager->Export("geometry2.root");

  // Extract new transformations
  AliMUONGeometryTransformer* transform3 = new AliMUONGeometryTransformer(true);
  transform3->ReadGeometryData("volpath.dat", "geometry2.root");
  transform3->WriteTransformations("transform3.dat");
               // Check that transform3.dat is equal to transform2.dat

  // Generate misaligned data in local cdb
  TClonesArray* array = newTransform->GetMisAlignmentData();

  TString sLocCDB("local://");
  sLocCDB += nameCDB;
  // CDB manager
  AliCDBManager* cdbManager = AliCDBManager::Instance();
  cdbManager->SetDefaultStorage(sLocCDB.Data());

  AliCDBMetaData* cdbData = new AliCDBMetaData();
  cdbData->SetResponsible("Dimuon Offline project");
  cdbData->SetComment("MUON alignment objects with residual misalignment");
  AliCDBId id("MUON/Align/Data", 0, 0);
  cdbManager->Put(array, id, cdbData);

  // To run simulation with misaligned geometry, you have to set
  // the Align option in Config.C:
  // MUON->SetAlign("transform2.dat");
}

<|endoftext|>


<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/utils/https_client.h"
#include "src/config.h"

#ifdef MSC_WITH_CURL
#include <curl/curl.h>
#endif

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>

#include <fstream>
#include <iostream>

#include "modsecurity/modsecurity.h"
#include "src/unique_id.h"

namespace modsecurity {
namespace Utils {

size_t HttpsClient::handle(char * data, size_t size, size_t nmemb, void * p) {
    return static_cast<HttpsClient*>(p)->handle_impl(data, size, nmemb);
}

size_t HttpsClient::handle_impl(char* data, size_t size, size_t nmemb) {
    content.append(data, size * nmemb);
    return size * nmemb;
}

void HttpsClient::setKey(const std::string& key) {
    m_key = "ModSec-key: " + key;
}

void HttpsClient::setRequestBody(const std::string& requestType) {
    m_requestBody = requestType;
}

void HttpsClient::setRequestType(const std::string& requestType) {
    m_requestType = requestType;
}

#ifdef MSC_WITH_CURL
bool HttpsClient::download(const std::string &uri) {
    CURL *curl;
    CURLcode res;
    std::string uniqueId = "ModSec-unique-id: " + UniqueId::uniqueId();
    std::string status = "ModSec-status: " + std::to_string(MODSECURITY_VERSION_NUM);

    curl = curl_easy_init();
    if (!curl) {
        error = "Not able to initialize libcurl";
        return false;
    }

    struct curl_slist *headers_chunk = NULL;
    curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());

    headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str());
    headers_chunk = curl_slist_append(headers_chunk, status.c_str());

    if (m_requestType.empty() == false) {
        std::string hdr = "Content-Type: " + m_requestType;
        headers_chunk = curl_slist_append(headers_chunk, hdr.c_str());
    }

    if (m_key.empty() == false) {
        headers_chunk = curl_slist_append(headers_chunk, m_key.c_str());
    }

    /* Make it TLS 1.x only. */
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

    /* those are the default options, but lets make sure */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);

    /* send all data to this function  */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle);

    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "ModSecurity3");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk);

    /* We want Curl to return error in case there is an HTTP error code */
    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);

    if (m_requestBody.empty() == false) {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, m_requestBody.c_str());
    }

    res = curl_easy_perform(curl);

    curl_slist_free_all(headers_chunk);

    if (res != CURLE_OK) {
        error = curl_easy_strerror(res);
    }

    curl_easy_cleanup(curl);

    return res == CURLE_OK;
}
#else
bool HttpsClient::download(const std::string &uri) {
    error = "Not compiled with libcurl support";
    return false;
}
#endif

}  // namespace Utils
}  // namespace modsecurity

<commit_msg>Confusing variable name in setRequestBody method<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "src/utils/https_client.h"
#include "src/config.h"

#ifdef MSC_WITH_CURL
#include <curl/curl.h>
#endif

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>

#include <fstream>
#include <iostream>

#include "modsecurity/modsecurity.h"
#include "src/unique_id.h"

namespace modsecurity {
namespace Utils {

size_t HttpsClient::handle(char * data, size_t size, size_t nmemb, void * p) {
    return static_cast<HttpsClient*>(p)->handle_impl(data, size, nmemb);
}

size_t HttpsClient::handle_impl(char* data, size_t size, size_t nmemb) {
    content.append(data, size * nmemb);
    return size * nmemb;
}

void HttpsClient::setKey(const std::string& key) {
    m_key = "ModSec-key: " + key;
}

void HttpsClient::setRequestBody(const std::string& requestBody) {
    m_requestBody = requestBody;
}

void HttpsClient::setRequestType(const std::string& requestType) {
    m_requestType = requestType;
}

#ifdef MSC_WITH_CURL
bool HttpsClient::download(const std::string &uri) {
    CURL *curl;
    CURLcode res;
    std::string uniqueId = "ModSec-unique-id: " + UniqueId::uniqueId();
    std::string status = "ModSec-status: " + std::to_string(MODSECURITY_VERSION_NUM);

    curl = curl_easy_init();
    if (!curl) {
        error = "Not able to initialize libcurl";
        return false;
    }

    struct curl_slist *headers_chunk = NULL;
    curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());

    headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str());
    headers_chunk = curl_slist_append(headers_chunk, status.c_str());

    if (m_requestType.empty() == false) {
        std::string hdr = "Content-Type: " + m_requestType;
        headers_chunk = curl_slist_append(headers_chunk, hdr.c_str());
    }

    if (m_key.empty() == false) {
        headers_chunk = curl_slist_append(headers_chunk, m_key.c_str());
    }

    /* Make it TLS 1.x only. */
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

    /* those are the default options, but lets make sure */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);

    /* send all data to this function  */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle);

    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "ModSecurity3");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk);

    /* We want Curl to return error in case there is an HTTP error code */
    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);

    if (m_requestBody.empty() == false) {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, m_requestBody.c_str());
    }

    res = curl_easy_perform(curl);

    curl_slist_free_all(headers_chunk);

    if (res != CURLE_OK) {
        error = curl_easy_strerror(res);
    }

    curl_easy_cleanup(curl);

    return res == CURLE_OK;
}
#else
bool HttpsClient::download(const std::string &uri) {
    error = "Not compiled with libcurl support";
    return false;
}
#endif

}  // namespace Utils
}  // namespace modsecurity

<|endoftext|>


<commit_before>#include <hop_bits/optimisationProblem/benchmark/blackBoxOptimisationBenchmark2013/linearSlope.hpp>

// Cereal
#include <cereal/archives/json.hpp>
#include <cereal/types/polymorphic.hpp>

namespace hop {
  namespace bbob2013 {
    LinearSlope::LinearSlope(
        const unsigned int& numberOfDimensions) noexcept
      : BlackBoxOptimisationBenchmark2013(numberOfDimensions) {
      setOne(one_);
    }

    void LinearSlope::setOne(const arma::Col<double>& one) {
      // TODO Add exception
      one_ = one;
      xOpt_ = 5.0 * one_;
      scaling_ = arma::sign(one_) % getScaling(10);
      partiallyObjectiveValue_ = 5.0 * arma::accu(arma::abs(scaling_));
    }

    double LinearSlope::getObjectiveValueImplementation(
        const arma::Col<double>& parameter) const noexcept {
      arma::Col<double> z = parameter;

      arma::Col<arma::uword> outOfBound = arma::find(xOpt_ % z >= 25.0);
      z.elem(outOfBound) = xOpt_.elem(outOfBound);

      return partiallyObjectiveValue_ - arma::dot(scaling_, z);
    }

    std::string LinearSlope::to_string() const noexcept {
      return "LinearSlope";
    }
  }
}

CEREAL_REGISTER_TYPE(hop::bbob2013::LinearSlope)
<commit_msg>devel: Check number of dimensions of randomly signed  one vector<commit_after>#include <hop_bits/optimisationProblem/benchmark/blackBoxOptimisationBenchmark2013/linearSlope.hpp>

// Cereal
#include <cereal/archives/json.hpp>
#include <cereal/types/polymorphic.hpp>

namespace hop {
  namespace bbob2013 {
    LinearSlope::LinearSlope(
        const unsigned int& numberOfDimensions) noexcept
      : BlackBoxOptimisationBenchmark2013(numberOfDimensions) {
      setOne(one_);
    }

    void LinearSlope::setOne(const arma::Col<double>& one) {
      if (one.n_elem != numberOfDimensions_) {
        throw std::logic_error("The number of dimensions of the one vector (" + std::to_string(one.n_elem) + ") must match the number of dimensions of the optimisation problem (" + std::to_string(numberOfDimensions_) + ").");
      }

      one_ = one;
      xOpt_ = 5.0 * one_;
      scaling_ = arma::sign(one_) % getScaling(10);
      partiallyObjectiveValue_ = 5.0 * arma::accu(arma::abs(scaling_));
    }

    double LinearSlope::getObjectiveValueImplementation(
        const arma::Col<double>& parameter) const noexcept {
      arma::Col<double> z = parameter;

      arma::Col<arma::uword> outOfBound = arma::find(xOpt_ % z >= 25.0);
      z.elem(outOfBound) = xOpt_.elem(outOfBound);

      return partiallyObjectiveValue_ - arma::dot(scaling_, z);
    }

    std::string LinearSlope::to_string() const noexcept {
      return "LinearSlope";
    }
  }
}

CEREAL_REGISTER_TYPE(hop::bbob2013::LinearSlope)
<|endoftext|>


<commit_before>/*************************************************************************/
/*  canvas_layer.cpp                                                     */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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.                */
/*************************************************************************/

#include "canvas_layer.h"
#include "viewport.h"

void CanvasLayer::set_layer(int p_xform) {

	layer = p_xform;
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
}

int CanvasLayer::get_layer() const {

	return layer;
}

void CanvasLayer::set_transform(const Transform2D &p_xform) {

	transform = p_xform;
	locrotscale_dirty = true;
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
}

Transform2D CanvasLayer::get_transform() const {

	return transform;
}

void CanvasLayer::_update_xform() {

	transform.set_rotation_and_scale(rot, scale);
	transform.set_origin(ofs);
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
}

void CanvasLayer::_update_locrotscale() {

	ofs = transform.elements[2];
	rot = transform.get_rotation();
	scale = transform.get_scale();
	locrotscale_dirty = false;
}

void CanvasLayer::set_offset(const Vector2 &p_offset) {

	if (locrotscale_dirty)
		_update_locrotscale();

	ofs = p_offset;
	_update_xform();
}

Vector2 CanvasLayer::get_offset() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return ofs;
}

void CanvasLayer::set_rotation(real_t p_radians) {

	if (locrotscale_dirty)
		_update_locrotscale();

	rot = p_radians;
	_update_xform();
}

real_t CanvasLayer::get_rotation() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return rot;
}

void CanvasLayer::set_rotation_degrees(real_t p_degrees) {

	set_rotation(Math::deg2rad(p_degrees));
}

real_t CanvasLayer::get_rotation_degrees() const {

	return Math::rad2deg(get_rotation());
}

void CanvasLayer::set_scale(const Vector2 &p_scale) {

	if (locrotscale_dirty)
		_update_locrotscale();

	scale = p_scale;
	_update_xform();
}

Vector2 CanvasLayer::get_scale() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return scale;
}

void CanvasLayer::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {

				vp = custom_viewport;
			} else {
				vp = Node::get_viewport();
			}
			ERR_FAIL_COND(!vp);

			vp->_canvas_layer_add(this);
			viewport = vp->get_viewport_rid();

			VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
			VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
			VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);

		} break;
		case NOTIFICATION_EXIT_TREE: {

			vp->_canvas_layer_remove(this);
			VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
			viewport = RID();

		} break;
		case NOTIFICATION_MOVED_IN_PARENT: {

			VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
		} break;
	}
}

Size2 CanvasLayer::get_viewport_size() const {

	if (!is_inside_tree())
		return Size2(1, 1);

	Rect2 r = vp->get_visible_rect();
	return r.size;
}

RID CanvasLayer::get_viewport() const {

	return viewport;
}

void CanvasLayer::set_custom_viewport(Node *p_viewport) {
	ERR_FAIL_NULL(p_viewport);
	if (is_inside_tree()) {
		vp->_canvas_layer_remove(this);
		VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
		viewport = RID();
	}

	custom_viewport = Object::cast_to<Viewport>(p_viewport);

	if (custom_viewport) {
		custom_viewport_id = custom_viewport->get_instance_id();
	} else {
		custom_viewport_id = 0;
	}

	if (is_inside_tree()) {

		if (custom_viewport)
			vp = custom_viewport;
		else
			vp = Node::get_viewport();

		vp->_canvas_layer_add(this);
		viewport = vp->get_viewport_rid();

		VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
		VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
	}
}

Node *CanvasLayer::get_custom_viewport() const {

	return custom_viewport;
}

void CanvasLayer::reset_sort_index() {
	sort_index = 0;
}

int CanvasLayer::get_sort_index() {

	return sort_index++;
}

RID CanvasLayer::get_canvas() const {

	return canvas;
}
void CanvasLayer::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
	ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);

	ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform);
	ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform);

	ClassDB::bind_method(D_METHOD("set_offset", "offset"), &CanvasLayer::set_offset);
	ClassDB::bind_method(D_METHOD("get_offset"), &CanvasLayer::get_offset);

	ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &CanvasLayer::set_rotation);
	ClassDB::bind_method(D_METHOD("get_rotation"), &CanvasLayer::get_rotation);

	ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &CanvasLayer::set_rotation_degrees);
	ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &CanvasLayer::get_rotation_degrees);

	ClassDB::bind_method(D_METHOD("set_scale", "scale"), &CanvasLayer::set_scale);
	ClassDB::bind_method(D_METHOD("get_scale"), &CanvasLayer::get_scale);

	ClassDB::bind_method(D_METHOD("set_custom_viewport", "viewport"), &CanvasLayer::set_custom_viewport);
	ClassDB::bind_method(D_METHOD("get_custom_viewport"), &CanvasLayer::get_custom_viewport);

	ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasLayer::get_canvas);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
	ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
}

CanvasLayer::CanvasLayer() {

	vp = NULL;
	scale = Vector2(1, 1);
	rot = 0;
	locrotscale_dirty = false;
	layer = 1;
	canvas = VS::get_singleton()->canvas_create();
	custom_viewport = NULL;
	custom_viewport_id = 0;
	sort_index = 0;
}

CanvasLayer::~CanvasLayer() {

	VS::get_singleton()->free(canvas);
}
<commit_msg>Fix CanvasLayer trying to re-stack while out of tree<commit_after>/*************************************************************************/
/*  canvas_layer.cpp                                                     */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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.                */
/*************************************************************************/

#include "canvas_layer.h"
#include "viewport.h"

void CanvasLayer::set_layer(int p_xform) {

	layer = p_xform;
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
}

int CanvasLayer::get_layer() const {

	return layer;
}

void CanvasLayer::set_transform(const Transform2D &p_xform) {

	transform = p_xform;
	locrotscale_dirty = true;
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
}

Transform2D CanvasLayer::get_transform() const {

	return transform;
}

void CanvasLayer::_update_xform() {

	transform.set_rotation_and_scale(rot, scale);
	transform.set_origin(ofs);
	if (viewport.is_valid())
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
}

void CanvasLayer::_update_locrotscale() {

	ofs = transform.elements[2];
	rot = transform.get_rotation();
	scale = transform.get_scale();
	locrotscale_dirty = false;
}

void CanvasLayer::set_offset(const Vector2 &p_offset) {

	if (locrotscale_dirty)
		_update_locrotscale();

	ofs = p_offset;
	_update_xform();
}

Vector2 CanvasLayer::get_offset() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return ofs;
}

void CanvasLayer::set_rotation(real_t p_radians) {

	if (locrotscale_dirty)
		_update_locrotscale();

	rot = p_radians;
	_update_xform();
}

real_t CanvasLayer::get_rotation() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return rot;
}

void CanvasLayer::set_rotation_degrees(real_t p_degrees) {

	set_rotation(Math::deg2rad(p_degrees));
}

real_t CanvasLayer::get_rotation_degrees() const {

	return Math::rad2deg(get_rotation());
}

void CanvasLayer::set_scale(const Vector2 &p_scale) {

	if (locrotscale_dirty)
		_update_locrotscale();

	scale = p_scale;
	_update_xform();
}

Vector2 CanvasLayer::get_scale() const {

	if (locrotscale_dirty)
		const_cast<CanvasLayer *>(this)->_update_locrotscale();

	return scale;
}

void CanvasLayer::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {

				vp = custom_viewport;
			} else {
				vp = Node::get_viewport();
			}
			ERR_FAIL_COND(!vp);

			vp->_canvas_layer_add(this);
			viewport = vp->get_viewport_rid();

			VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
			VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
			VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);

		} break;
		case NOTIFICATION_EXIT_TREE: {

			vp->_canvas_layer_remove(this);
			VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
			viewport = RID();

		} break;
		case NOTIFICATION_MOVED_IN_PARENT: {

			if (is_inside_tree())
				VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());

		} break;
	}
}

Size2 CanvasLayer::get_viewport_size() const {

	if (!is_inside_tree())
		return Size2(1, 1);

	Rect2 r = vp->get_visible_rect();
	return r.size;
}

RID CanvasLayer::get_viewport() const {

	return viewport;
}

void CanvasLayer::set_custom_viewport(Node *p_viewport) {
	ERR_FAIL_NULL(p_viewport);
	if (is_inside_tree()) {
		vp->_canvas_layer_remove(this);
		VisualServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
		viewport = RID();
	}

	custom_viewport = Object::cast_to<Viewport>(p_viewport);

	if (custom_viewport) {
		custom_viewport_id = custom_viewport->get_instance_id();
	} else {
		custom_viewport_id = 0;
	}

	if (is_inside_tree()) {

		if (custom_viewport)
			vp = custom_viewport;
		else
			vp = Node::get_viewport();

		vp->_canvas_layer_add(this);
		viewport = vp->get_viewport_rid();

		VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
		VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
		VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
	}
}

Node *CanvasLayer::get_custom_viewport() const {

	return custom_viewport;
}

void CanvasLayer::reset_sort_index() {
	sort_index = 0;
}

int CanvasLayer::get_sort_index() {

	return sort_index++;
}

RID CanvasLayer::get_canvas() const {

	return canvas;
}
void CanvasLayer::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
	ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);

	ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform);
	ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform);

	ClassDB::bind_method(D_METHOD("set_offset", "offset"), &CanvasLayer::set_offset);
	ClassDB::bind_method(D_METHOD("get_offset"), &CanvasLayer::get_offset);

	ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &CanvasLayer::set_rotation);
	ClassDB::bind_method(D_METHOD("get_rotation"), &CanvasLayer::get_rotation);

	ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &CanvasLayer::set_rotation_degrees);
	ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &CanvasLayer::get_rotation_degrees);

	ClassDB::bind_method(D_METHOD("set_scale", "scale"), &CanvasLayer::set_scale);
	ClassDB::bind_method(D_METHOD("get_scale"), &CanvasLayer::get_scale);

	ClassDB::bind_method(D_METHOD("set_custom_viewport", "viewport"), &CanvasLayer::set_custom_viewport);
	ClassDB::bind_method(D_METHOD("get_custom_viewport"), &CanvasLayer::get_custom_viewport);

	ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasLayer::get_canvas);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
	ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
}

CanvasLayer::CanvasLayer() {

	vp = NULL;
	scale = Vector2(1, 1);
	rot = 0;
	locrotscale_dirty = false;
	layer = 1;
	canvas = VS::get_singleton()->canvas_create();
	custom_viewport = NULL;
	custom_viewport_id = 0;
	sort_index = 0;
}

CanvasLayer::~CanvasLayer() {

	VS::get_singleton()->free(canvas);
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_INL
#define SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_INL

#include <SofaEngine/TransformEngine.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/helper/rmath.h> //M_PI

namespace sofa
{

namespace component
{

namespace engine
{

template <class DataTypes>
TransformEngine<DataTypes>::TransformEngine()
    : f_inputX ( initData (&f_inputX, "input_position", "input array of 3d points") )
    , f_outputX( initData (&f_outputX, "output_position", "output array of 3d points") )
    , translation(initData(&translation, defaulttype::Vector3(0,0,0),"translation", "translation vector ") )
    , rotation(initData(&rotation, defaulttype::Vector3(0,0,0), "rotation", "rotation vector ") )
    , quaternion(initData(&quaternion, defaulttype::Quaternion(0,0,0,1), "quaternion", "rotation quaternion ") )
    , scale(initData(&scale, defaulttype::Vector3(1,1,1),"scale", "scale factor") )
    , inverse(initData(&inverse, false, "inverse", "true to apply inverse transformation"))
{
}

template <class DataTypes>
void TransformEngine<DataTypes>::init()
{
    addInput(&f_inputX);
    addInput(&translation);
    addInput(&rotation);
    addInput(&quaternion);
    addInput(&scale);
    addInput(&inverse);
    addOutput(&f_outputX);
    setDirtyValue();
}

template <class DataTypes>
void TransformEngine<DataTypes>::reinit()
{
    update();
}

//Declare a TransformOperation class able to do an operation on a Coord
template <class DataTypes>
struct TransformOperation
{
    virtual ~TransformOperation() {}
    virtual void execute(typename DataTypes::Coord &v) const =0;
};

//*****************************************************************
//Scale Operation
template <class DataTypes>
struct Scale : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;
    Scale():sx(0),sy(0),sz(0) {}

    void execute(typename DataTypes::Coord &p) const
    {
        Real x,y,z;
        DataTypes::get(x,y,z,p);
        DataTypes::set(p,x*sx,y*sy,z*sz);
    }

    void configure(const defaulttype::Vector3 &s, bool inverse)
    {
        if (inverse)
        {
            sx=(Real)(1.0/s[0]); sy=(Real)(1.0/s[1]); sz=(Real)(1.0/s[2]);
        }
        else
        {
            sx=(Real)s[0]; sy=(Real)s[1]; sz=(Real)s[2];
        }
    }
private:
    Real sx,sy,sz;
};

//*****************************************************************
//Rotation Operation
template <class DataTypes, int N, bool isVector>
struct RotationSpecialized : public TransformOperation<DataTypes>
{
	typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
        defaulttype::Vector3 pos;
        DataTypes::get(pos[0],pos[1],pos[2],p);
        pos=q.rotate(pos);
        DataTypes::set(p,pos[0],pos[1],pos[2]);
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
        if (inverse)
            q = q.inverse();
    }

    void configure(const defaulttype::Quaternion &qi, bool inverse)
    {
        q=qi;
        if (inverse)
            q = q.inverse();
    }

private:
    defaulttype::Quaternion q;
};

template <class DataTypes>
struct RotationSpecialized<DataTypes, 2, false> : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
        defaulttype::Vector3 pos;
        DataTypes::get(pos[0],pos[1],pos[2],p);
        pos=q.rotate(pos);
        DataTypes::set(p,pos[0],pos[1],pos[2]);

		p.getOrientation() += rotZ;
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
		rotZ = static_cast<Real>(r.z() * (M_PI/180.0f));
        if (inverse)
            rotZ = -rotZ;
    }
private:
    Real rotZ;
	defaulttype::Quaternion q;
};

template <class DataTypes>
struct RotationSpecialized<DataTypes, 3, false> : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
		p.getCenter() = q.rotate(p.getCenter());
		p.getOrientation() = q*p.getOrientation();
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
        if (inverse)
            q = q.inverse();
    }
private:
	defaulttype::Quaternion q;
};

template <class DataTypes>
struct Rotation : public RotationSpecialized<DataTypes, DataTypes::spatial_dimensions, DataTypes::coord_total_size == DataTypes::spatial_dimensions>
{ };

//*****************************************************************
//Translation Operation
template <class DataTypes>
struct Translation : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;
    Translation():tx(0),ty(0),tz(0) {}
    void execute(typename DataTypes::Coord &p) const
    {
        Real x,y,z;
        DataTypes::get(x,y,z,p);
        DataTypes::set(p,x+tx,y+ty,z+tz);
    }
    void configure(const defaulttype::Vector3 &t, bool inverse)
    {
        if (inverse)
        {
            tx=(Real)-t[0]; ty=(Real)-t[1]; tz=(Real)-t[2];
        }
        else
        {
            tx=(Real)t[0]; ty=(Real)t[1]; tz=(Real)t[2];
        }
    }
private:
    Real tx,ty,tz;
};

//*****************************************************************
//Functor to apply the operations wanted
template <class DataTypes>
struct Transform
{
    typedef TransformOperation<DataTypes> Op;

    template <class  Operation>
    Operation* add(Operation *op, bool inverse)
    {
//     Operation *op=new Operation();
        if (inverse)
            list.push_front(op);
        else
            list.push_back(op);
        return op;
    }

    std::list< Op* > &getOperations() {return list;}

    void operator()(typename DataTypes::Coord &v) const
    {
        for (typename std::list< Op* >::const_iterator it=list.begin(); it != list.end() ; ++it)
        {
            (*it)->execute(v);
        }
    }
private:
    std::list< Op* > list;
};

template <class DataTypes>
void TransformEngine<DataTypes>::update()
{
    cleanDirty();

    const defaulttype::Vector3 &s=scale.getValue();
    const defaulttype::Vector3 &r=rotation.getValue();
    const defaulttype::Vector3 &t=translation.getValue();
    const defaulttype::Quaternion &q=quaternion.getValue();

    //Create the object responsible for the transformations
    Transform<DataTypes> transformation;
    const bool inv = inverse.getValue();
    if (s != defaulttype::Vector3(1,1,1))
        transformation.add(new Scale<DataTypes>, inv)->configure(s, inv);

    if (r != defaulttype::Vector3(0,0,0))
        transformation.add(new Rotation<DataTypes>, inv)->configure(r, inv);

    if (q != defaulttype::Quaternion(0,0,0,1))
        transformation.add(new Rotation<DataTypes>, inv)->configure(q, inv);

    if (t != defaulttype::Vector3(0,0,0))
        transformation.add(new Translation<DataTypes>, inv)->configure(t, inv);

    //Get input
    const VecCoord& in = f_inputX.getValue();
    VecCoord& out = *(f_outputX.beginEdit());

    //Set Output
    out.resize(in.size());
    //Set the output to the input
    std::copy(in.begin(),in.end(), out.begin());
    //Apply the transformation of the output
    std::for_each(out.begin(), out.end(), transformation);

    //Deleting operations
    std::list< TransformOperation<DataTypes>* > operations=transformation.getOperations();
    while (!operations.empty())
    {
        delete operations.back();
        operations.pop_back();
    }

    f_outputX.endEdit();
}

} // namespace engine

} // namespace component

} // namespace sofa

#endif
<commit_msg>FIX: for each possible instanciation of template RotationSpecialized<>, created a compute() method taking a quaternion parameter<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_INL
#define SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_INL

#include <sofa/core/objectmodel/Base.h>
#include <SofaEngine/TransformEngine.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/helper/rmath.h> //M_PI

#include <cassert>

namespace sofa
{

namespace component
{

namespace engine
{

template <class DataTypes>
TransformEngine<DataTypes>::TransformEngine()
    : f_inputX ( initData (&f_inputX, "input_position", "input array of 3d points") )
    , f_outputX( initData (&f_outputX, "output_position", "output array of 3d points") )
    , translation(initData(&translation, defaulttype::Vector3(0,0,0),"translation", "translation vector ") )
    , rotation(initData(&rotation, defaulttype::Vector3(0,0,0), "rotation", "rotation vector ") )
    , quaternion(initData(&quaternion, defaulttype::Quaternion(0,0,0,1), "quaternion", "rotation quaternion ") )
    , scale(initData(&scale, defaulttype::Vector3(1,1,1),"scale", "scale factor") )
    , inverse(initData(&inverse, false, "inverse", "true to apply inverse transformation"))
{
}

template <class DataTypes>
void TransformEngine<DataTypes>::init()
{
    addInput(&f_inputX);
    addInput(&translation);
    addInput(&rotation);
    addInput(&quaternion);
    addInput(&scale);
    addInput(&inverse);
    addOutput(&f_outputX);
    setDirtyValue();
}

template <class DataTypes>
void TransformEngine<DataTypes>::reinit()
{
    update();
}

//Declare a TransformOperation class able to do an operation on a Coord
template <class DataTypes>
struct TransformOperation
{
    virtual ~TransformOperation() {}
    virtual void execute(typename DataTypes::Coord &v) const =0;
};

//*****************************************************************
//Scale Operation
template <class DataTypes>
struct Scale : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;
    Scale():sx(0),sy(0),sz(0) {}

    void execute(typename DataTypes::Coord &p) const
    {
        Real x,y,z;
        DataTypes::get(x,y,z,p);
        DataTypes::set(p,x*sx,y*sy,z*sz);
    }

    void configure(const defaulttype::Vector3 &s, bool inverse)
    {
        if (inverse)
        {
            sx=(Real)(1.0/s[0]); sy=(Real)(1.0/s[1]); sz=(Real)(1.0/s[2]);
        }
        else
        {
            sx=(Real)s[0]; sy=(Real)s[1]; sz=(Real)s[2];
        }
    }
private:
    Real sx,sy,sz;
};

//*****************************************************************
//Rotation Operation
template <class DataTypes, int N, bool isVector>
struct RotationSpecialized : public TransformOperation<DataTypes>
{
	typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
        defaulttype::Vector3 pos;
        DataTypes::get(pos[0],pos[1],pos[2],p);
        pos=q.rotate(pos);
        DataTypes::set(p,pos[0],pos[1],pos[2]);
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
        if (inverse)
            q = q.inverse();
    }

    void configure(const defaulttype::Quaternion &qi, bool inverse, sofa::core::objectmodel::Base*)
    {
        q=qi;
        if (inverse)
            q = q.inverse();
    }

private:
    defaulttype::Quaternion q;
};

template <class DataTypes>
struct RotationSpecialized<DataTypes, 2, false> : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
        defaulttype::Vector3 pos;
        DataTypes::get(pos[0],pos[1],pos[2],p);
        pos=q.rotate(pos);
        DataTypes::set(p,pos[0],pos[1],pos[2]);

		p.getOrientation() += rotZ;
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
		rotZ = static_cast<Real>(r.z() * (M_PI/180.0f));
        if (inverse)
            rotZ = -rotZ;
    }

    void configure(const defaulttype::Quaternion &qi, bool inverse, sofa::core::objectmodel::Base* pBase)
    {
        assert(pBase);
        pBase->serr << "'void RotationSpecialized::configure(const defaulttype::Quaternion &qi, bool inverse)' is not implemented for two-dimensional data types" << pBase->sendl;
        assert(false && "This method should not be called without been implemented");
    }

private:
    Real rotZ;
	defaulttype::Quaternion q;
};

template <class DataTypes>
struct RotationSpecialized<DataTypes, 3, false> : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;

    void execute(typename DataTypes::Coord &p) const
    {
		p.getCenter() = q.rotate(p.getCenter());
		p.getOrientation() = q*p.getOrientation();
    }

    void configure(const defaulttype::Vector3 &r, bool inverse)
    {
        q=helper::Quater<Real>::createQuaterFromEuler( r*(M_PI/180.0));
        if (inverse)
            q = q.inverse();
    }

    void configure(const defaulttype::Quaternion &qi, bool inverse, sofa::core::objectmodel::Base*)
    {
        q=qi;
        if (inverse)
            q = q.inverse();
    }
private:
	defaulttype::Quaternion q;
};

template <class DataTypes>
struct Rotation : public RotationSpecialized<DataTypes, DataTypes::spatial_dimensions, DataTypes::coord_total_size == DataTypes::spatial_dimensions>
{ };

//*****************************************************************
//Translation Operation
template <class DataTypes>
struct Translation : public TransformOperation<DataTypes>
{
    typedef typename DataTypes::Real Real;
    Translation():tx(0),ty(0),tz(0) {}
    void execute(typename DataTypes::Coord &p) const
    {
        Real x,y,z;
        DataTypes::get(x,y,z,p);
        DataTypes::set(p,x+tx,y+ty,z+tz);
    }
    void configure(const defaulttype::Vector3 &t, bool inverse)
    {
        if (inverse)
        {
            tx=(Real)-t[0]; ty=(Real)-t[1]; tz=(Real)-t[2];
        }
        else
        {
            tx=(Real)t[0]; ty=(Real)t[1]; tz=(Real)t[2];
        }
    }
private:
    Real tx,ty,tz;
};

//*****************************************************************
//Functor to apply the operations wanted
template <class DataTypes>
struct Transform
{
    typedef TransformOperation<DataTypes> Op;

    template <class  Operation>
    Operation* add(Operation *op, bool inverse)
    {
//     Operation *op=new Operation();
        if (inverse)
            list.push_front(op);
        else
            list.push_back(op);
        return op;
    }

    std::list< Op* > &getOperations() {return list;}

    void operator()(typename DataTypes::Coord &v) const
    {
        for (typename std::list< Op* >::const_iterator it=list.begin(); it != list.end() ; ++it)
        {
            (*it)->execute(v);
        }
    }
private:
    std::list< Op* > list;
};

template <class DataTypes>
void TransformEngine<DataTypes>::update()
{
    cleanDirty();

    const defaulttype::Vector3 &s=scale.getValue();
    const defaulttype::Vector3 &r=rotation.getValue();
    const defaulttype::Vector3 &t=translation.getValue();
    const defaulttype::Quaternion &q=quaternion.getValue();

    //Create the object responsible for the transformations
    Transform<DataTypes> transformation;
    const bool inv = inverse.getValue();
    if (s != defaulttype::Vector3(1,1,1))
        transformation.add(new Scale<DataTypes>, inv)->configure(s, inv);

    if (r != defaulttype::Vector3(0,0,0))
        transformation.add(new Rotation<DataTypes>, inv)->configure(r, inv);

    if (q != defaulttype::Quaternion(0,0,0,1))
        transformation.add(new Rotation<DataTypes>, inv)->configure(q, inv, this);

    if (t != defaulttype::Vector3(0,0,0))
        transformation.add(new Translation<DataTypes>, inv)->configure(t, inv);

    //Get input
    const VecCoord& in = f_inputX.getValue();
    VecCoord& out = *(f_outputX.beginEdit());

    //Set Output
    out.resize(in.size());
    //Set the output to the input
    std::copy(in.begin(),in.end(), out.begin());
    //Apply the transformation of the output
    std::for_each(out.begin(), out.end(), transformation);

    //Deleting operations
    std::list< TransformOperation<DataTypes>* > operations=transformation.getOperations();
    while (!operations.empty())
    {
        delete operations.back();
        operations.pop_back();
    }

    f_outputX.endEdit();
}

} // namespace engine

} // namespace component

} // namespace sofa

#endif
<|endoftext|>


<commit_before>#ifdef COMPONENT_PARSER_H
// do not include this file directly.
// use parser.h instead.

// include the implementation of classes:
//     Variable, VariableScope, Function
#include "variables.cpp"

/*************************************
* Implementation: class Parser
*************************************/

// Construction, and setup.
Parser::Parser(Lexer *ref, String args) {
	this->lexer = ref;
	this->status = PARSE_PENDING;
}

Parser::~Parser() {
	functions.clear();
	errors.clear();
	output.clear();
}

/*** Parser Interface ***/
bool Parser::sendError(Error e) {
	this->errors.pushback(e);
	if (e.severity() == ERROR_FATAL) {
		// a fatal error, so stop parsing further.
		this->status = PARSE_FAILED;
	}
	return true;
}

bool Parser::showErrors(ostream& out, bool clearAfterDisplay) {
	if (this->errors.size() > 0) {
		for (__SIZETYPE i = 0; i < errors.size(); i++) {
			out << errors[i].message() << endl;
		}
		if (clearAfterDisplay) errors.clear();
		return true;
	}
	return false;
}

Function Parser::getFunction(String id) {
	Function f;
	for (__SIZETYPE i = 0; i < this->functions.size(); i++) {
		f = this->functions[i];
		if (f.id() == id) return f;
	}
	return f;
}
RPN getOutput() { return this->output; }

/**** Parsing Procedures ****/
bool Parser::parseSource() {
	// some error checks before proceeding:
	Vector<Error> lexerErrors = this->lexer->getErrors();
	for (__SIZETYPE i = 0; i < lexerErrors.size(); i++) this->sendError(lexerErrors[i]);
	if (this->showErrors(cerr)) {
		this->status = PARSE_FAILED;
		return false;
	}

	// Actual parsing:
	Token tok = this->lexer->getToken();
	if (tok.value() == "$eof") {
		// no code??
		this->status = PARSE_SUCCESS;
		return true;
	}
	this->lexer->putbackToken(tok);

	this->output = expressionToRPN(this->lexer->getTokensTill("$eof"));
	if (this->showErrors(cerr)) {
		this->status = PARSE_FAILED;
		return false;
	}

	this->status = PARSE_SUCCESS;
	return true;
}

RPN Parser::parseBlock(bufferIndex depth) {
	// parses a block of the given depth.
	return RPN();
}
RPN Parser::parseDeclaration(tokenType type) {
	// procedure to parse array and hash table primitives.
	// errors can be directly caught. carefully call converting to RPN.
	return RPN();
}
RPN Parser::parseFunction() {
	return RPN();

}
/**** Static Parsing Procedures ****/
RPN Parser::expressionToRPN(Infix args) {
	if (args.empty()) return RPN();

	RPN output;
	RPN preChange, postChange;
	Token current, prevtok;
	Stack<Token> operstack;

	static Token subscriptOp = Lexer::toToken("[]"),
	             ternaryOp = Token("?:", OPERATOR, MULTINARYOP),
	             statementEnd = Lexer::toToken(";"),
	             pluseqTok = Lexer::toToken("+="),
	             minuseqTok = Lexer::toToken("-="),
	             oneTok = Lexer::toToken("1");

	static Token funcInvoke = Token("@invoke", DIRECTIVE, FUNCTION);

	args.push(statementEnd);
	Stack<__SIZETYPE> funcarglist;

	while (args.pop(current)) {
		// DEBUG(current.value())
		if (current.value() == "$endline" || current.value() == ";") {
			while (operstack.pop(current)) {
				// check for unbalanced ( and [
				if (current.value() == "(" || current.value() == "[") this->sendError(Error("p1", current.value(), current.lineNumber()));
				output.push(current);
			}
			current = statementEnd;
			output.push(statementEnd);
		}

		if (current.type() == IDENTIFIER) {
			// check whether it is a function:
			if (!args.empty() && args.front().value() == "(") {
				current.setSubtype(FUNCTION);
			} else { // is a variable/property
				output.push(current);
			}
		}
		if (current.subtype() == FUNCTION) {
			operstack.push(current);
			Token tmp;
			if (!args.pop(tmp) || tmp.value() != "(") this->sendError(Error("p3.1", "", current.lineNumber())); // function call should be succeeded by a (
			operstack.push(tmp);

			if (!args.empty() && args.front().value() == ")") {
				// zero argument function call:
				funcarglist.push(0);
			} else {
				funcarglist.push(1);
			}
		}

		if (current.type() == PUNCTUATOR) {
			Token tmp;

			if (current.value() == "(" || current.value() == "[") {
				operstack.push(current);
			}
			else if (current.value() == ")") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "(") {
						if (!operstack.empty() && operstack.top().subtype() == FUNCTION) {
							Token func;
							operstack.pop(func);
							output.push(func);

							__SIZETYPE argnum;
							if (funcarglist.pop(argnum)) output.push(toArgsToken(argnum));
							else {
								// unable to find number of arguments: arglist is empty.
								// should not happen.
								this->sendError(Error("p3.2", "@args", tmp.lineNumber()));
							}

							if (!operstack.empty() && operstack.top().value() == ".") {
								// dereference the method.
								Token deref;
								operstack.pop(deref);
								output.push(deref);
							}
							output.push(funcInvoke);
						}
						break;
					}
					output.push(tmp);
				}
				if (tmp.value() != "(") {
					this->sendError(Error("p1", ")", tmp.lineNumber())); // unbalanced )
					DEBUG(tmp.value());
				}
			}
			else if (current.value() == "]") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "[") break;
					output.push(tmp);
				}
				if (tmp.value() != "[") this->sendError(Error("p1", "]", tmp.lineNumber())); // unbalanced ]
				output.push(subscriptOp);
			}
			else if (current.value() == ",") {
				while (!operstack.empty()) {
					if (operstack.top().value() == "(") break;
					operstack.pop(tmp);
					output.push(tmp);
				}
				if (!funcarglist.empty()) funcarglist.top()++;
			}
			else if (current.value() == ":") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "?") break;
					output.push(tmp);
				}
				if (tmp.value() != "?") this->sendError(Error("p2", ": without a ?", tmp.lineNumber())); // unexpected : without a ?
				operstack.pop();
				operstack.push(ternaryOp);
			}
		}
		if (current.type() == OPERATOR) {
			if (current.value() == "-") { // check for unary minus
				if (!prevtok.value() || prevtok.value() == "(" || prevtok.value() == ";") {
					current.setSubtype(UNARYOP);
				}
			}

			if (current.value() == "++" || current.value() == "--") {
				// this is kindof problematic, coz `a[i]++` is a valid expression.
				// support for these operators will be added later. as of now ignore them.
				this->sendError(Error("ns", current.value(), current.lineNumber()));
			}
			else {
				Token oper, tval;
				while (!operstack.empty()) {
					tval = operstack.top();
					if (tval.value() == "(" || tval.value() == "[") break;
					if (Operations::comparePriority(tval, current) >= 0) {
						operstack.pop(oper);
						output.push(oper);
					}
					else break;
				}
				operstack.push(current);
			}
		}
		if (current.type() == LITERAL) {
			output.push(current);
		}
		prevtok = current;
	}

	// finally, after parsing the infix buffer, append the pre and post RPN.
	RPN finalOutput;
	while (preChange.pop(current)) finalOutput.push(current);
	while (output.pop(current)) finalOutput.push(current);
	while (postChange.pop(current)) finalOutput.push(current);

	return finalOutput;
}

Token Parser::toArgsToken(__SIZETYPE num) {
	String s = "@args|";
	s += integerToString(num);
	return Token(s, DIRECTIVE, FUNCTION);
}
/*** END implementation: class Parser ***/
#endif
<commit_msg>define parser member in proper scope<commit_after>#ifdef COMPONENT_PARSER_H
// do not include this file directly.
// use parser.h instead.

// include the implementation of classes:
//     Variable, VariableScope, Function
#include "variables.cpp"

/*************************************
* Implementation: class Parser
*************************************/

// Construction, and setup.
Parser::Parser(Lexer *ref, String args) {
	this->lexer = ref;
	this->status = PARSE_PENDING;
}

Parser::~Parser() {
	functions.clear();
	errors.clear();
	output.clear();
}

/*** Parser Interface ***/
bool Parser::sendError(Error e) {
	this->errors.pushback(e);
	if (e.severity() == ERROR_FATAL) {
		// a fatal error, so stop parsing further.
		this->status = PARSE_FAILED;
	}
	return true;
}

bool Parser::showErrors(ostream& out, bool clearAfterDisplay) {
	if (this->errors.size() > 0) {
		for (__SIZETYPE i = 0; i < errors.size(); i++) {
			out << errors[i].message() << endl;
		}
		if (clearAfterDisplay) errors.clear();
		return true;
	}
	return false;
}

Function Parser::getFunction(String id) {
	Function f;
	for (__SIZETYPE i = 0; i < this->functions.size(); i++) {
		f = this->functions[i];
		if (f.id() == id) return f;
	}
	return f;
}
RPN Parser::getOutput() { return this->output; }

/**** Parsing Procedures ****/
bool Parser::parseSource() {
	// some error checks before proceeding:
	Vector<Error> lexerErrors = this->lexer->getErrors();
	for (__SIZETYPE i = 0; i < lexerErrors.size(); i++) this->sendError(lexerErrors[i]);
	if (this->showErrors(cerr)) {
		this->status = PARSE_FAILED;
		return false;
	}

	// Actual parsing:
	Token tok = this->lexer->getToken();
	if (tok.value() == "$eof") {
		// no code??
		this->status = PARSE_SUCCESS;
		return true;
	}
	this->lexer->putbackToken(tok);

	this->output = expressionToRPN(this->lexer->getTokensTill("$eof"));
	if (this->showErrors(cerr)) {
		this->status = PARSE_FAILED;
		return false;
	}

	this->status = PARSE_SUCCESS;
	return true;
}

RPN Parser::parseBlock(bufferIndex depth) {
	// parses a block of the given depth.
	return RPN();
}
RPN Parser::parseDeclaration(tokenType type) {
	// procedure to parse array and hash table primitives.
	// errors can be directly caught. carefully call converting to RPN.
	return RPN();
}
RPN Parser::parseFunction() {
	return RPN();

}
/**** Static Parsing Procedures ****/
RPN Parser::expressionToRPN(Infix args) {
	if (args.empty()) return RPN();

	RPN output;
	RPN preChange, postChange;
	Token current, prevtok;
	Stack<Token> operstack;

	static Token subscriptOp = Lexer::toToken("[]"),
	             ternaryOp = Token("?:", OPERATOR, MULTINARYOP),
	             statementEnd = Lexer::toToken(";"),
	             pluseqTok = Lexer::toToken("+="),
	             minuseqTok = Lexer::toToken("-="),
	             oneTok = Lexer::toToken("1");

	static Token funcInvoke = Token("@invoke", DIRECTIVE, FUNCTION);

	args.push(statementEnd);
	Stack<__SIZETYPE> funcarglist;

	while (args.pop(current)) {
		// DEBUG(current.value())
		if (current.value() == "$endline" || current.value() == ";") {
			while (operstack.pop(current)) {
				// check for unbalanced ( and [
				if (current.value() == "(" || current.value() == "[") this->sendError(Error("p1", current.value(), current.lineNumber()));
				output.push(current);
			}
			current = statementEnd;
			output.push(statementEnd);
		}

		if (current.type() == IDENTIFIER) {
			// check whether it is a function:
			if (!args.empty() && args.front().value() == "(") {
				current.setSubtype(FUNCTION);
			} else { // is a variable/property
				output.push(current);
			}
		}
		if (current.subtype() == FUNCTION) {
			operstack.push(current);
			Token tmp;
			if (!args.pop(tmp) || tmp.value() != "(") this->sendError(Error("p3.1", "", current.lineNumber())); // function call should be succeeded by a (
			operstack.push(tmp);

			if (!args.empty() && args.front().value() == ")") {
				// zero argument function call:
				funcarglist.push(0);
			} else {
				funcarglist.push(1);
			}
		}

		if (current.type() == PUNCTUATOR) {
			Token tmp;

			if (current.value() == "(" || current.value() == "[") {
				operstack.push(current);
			}
			else if (current.value() == ")") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "(") {
						if (!operstack.empty() && operstack.top().subtype() == FUNCTION) {
							Token func;
							operstack.pop(func);
							output.push(func);

							__SIZETYPE argnum;
							if (funcarglist.pop(argnum)) output.push(toArgsToken(argnum));
							else {
								// unable to find number of arguments: arglist is empty.
								// should not happen.
								this->sendError(Error("p3.2", "@args", tmp.lineNumber()));
							}

							if (!operstack.empty() && operstack.top().value() == ".") {
								// dereference the method.
								Token deref;
								operstack.pop(deref);
								output.push(deref);
							}
							output.push(funcInvoke);
						}
						break;
					}
					output.push(tmp);
				}
				if (tmp.value() != "(") {
					this->sendError(Error("p1", ")", tmp.lineNumber())); // unbalanced )
					DEBUG(tmp.value());
				}
			}
			else if (current.value() == "]") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "[") break;
					output.push(tmp);
				}
				if (tmp.value() != "[") this->sendError(Error("p1", "]", tmp.lineNumber())); // unbalanced ]
				output.push(subscriptOp);
			}
			else if (current.value() == ",") {
				while (!operstack.empty()) {
					if (operstack.top().value() == "(") break;
					operstack.pop(tmp);
					output.push(tmp);
				}
				if (!funcarglist.empty()) funcarglist.top()++;
			}
			else if (current.value() == ":") {
				while (operstack.pop(tmp)) {
					if (tmp.value() == "?") break;
					output.push(tmp);
				}
				if (tmp.value() != "?") this->sendError(Error("p2", ": without a ?", tmp.lineNumber())); // unexpected : without a ?
				operstack.pop();
				operstack.push(ternaryOp);
			}
		}
		if (current.type() == OPERATOR) {
			if (current.value() == "-") { // check for unary minus
				if (!prevtok.value() || prevtok.value() == "(" || prevtok.value() == ";") {
					current.setSubtype(UNARYOP);
				}
			}

			if (current.value() == "++" || current.value() == "--") {
				// this is kindof problematic, coz `a[i]++` is a valid expression.
				// support for these operators will be added later. as of now ignore them.
				this->sendError(Error("ns", current.value(), current.lineNumber()));
			}
			else {
				Token oper, tval;
				while (!operstack.empty()) {
					tval = operstack.top();
					if (tval.value() == "(" || tval.value() == "[") break;
					if (Operations::comparePriority(tval, current) >= 0) {
						operstack.pop(oper);
						output.push(oper);
					}
					else break;
				}
				operstack.push(current);
			}
		}
		if (current.type() == LITERAL) {
			output.push(current);
		}
		prevtok = current;
	}

	// finally, after parsing the infix buffer, append the pre and post RPN.
	RPN finalOutput;
	while (preChange.pop(current)) finalOutput.push(current);
	while (output.pop(current)) finalOutput.push(current);
	while (postChange.pop(current)) finalOutput.push(current);

	return finalOutput;
}

Token Parser::toArgsToken(__SIZETYPE num) {
	String s = "@args|";
	s += integerToString(num);
	return Token(s, DIRECTIVE, FUNCTION);
}
/*** END implementation: class Parser ***/
#endif
<|endoftext|>


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

/**
 * @file
 **/

#include "modules/planning/lattice/behavior/signal_light_scenario.h"

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

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  auto signals_from_map = FindValidSignalLightFromMap(reference_line_info);
  if (signals_from_map.empty()) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  auto detected_signals = GetPerceptionDetectedSignals();

  StopPoint stop_point;
  stop_point.set_s(std::numeric_limits<double>::max());
  stop_point.set_type(StopPoint::HARD);
  for (const auto signal_from_map : signals_from_map) {
    auto it_signal = detected_signals.find(signal_from_map->object_id);
    if (it_signal == detected_signals.end()) {
      AWARN << "Cannot detect signal which is marked on the map; signal id: "
            << signal_from_map->object_id;
      continue;
    }

    if (signal_from_map->start_s < stop_point.s()) {
      stop_point.set_s(signal_from_map->start_s);
      if (it_signal->second->color() == TrafficLight::RED) {
        stop_point.set_type(StopPoint::HARD);
      } else if (it_signal->second->color() == TrafficLight::YELLOW) {
        stop_point.set_type(StopPoint::SOFT);
      }
    }
  }

  if (stop_point.s() < std::numeric_limits<double>::max()) {
    planning_target->mutable_stop_point()->set_s(stop_point.s());
    planning_target->mutable_stop_point()->set_type(stop_point.type());
  }

  return 0;
}

std::vector<const hdmap::PathOverlap*>
SignalLightScenario::FindValidSignalLightFromMap(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() == 0) {
    ADEBUG << "No signal lights from reference line.";
    return std::vector<const hdmap::PathOverlap*>();
  }
  ADEBUG << "Found signal_lights size=" << signal_lights.size();

  std::vector<const hdmap::PathOverlap*> signal_lights_along_reference_line;
  for (const auto& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line;
}

std::unordered_map<std::string, const TrafficLight*>
SignalLightScenario::GetPerceptionDetectedSignals() {
  if (AdapterManager::GetTrafficLightDetection()->Empty() ||
      (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
       FLAGS_signal_expire_time_sec)) {
    ADEBUG << "traffic light signals msg is either empty or outdated.";
    return std::unordered_map<std::string, const TrafficLight*>();
  }

  std::unordered_map<std::string, const TrafficLight*> detected_signals;
  const auto& signal_msg =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();

  for (int j = 0; j < signal_msg.traffic_light_size(); ++j) {
    const auto& signal = signal_msg.traffic_light(j);
    detected_signals[signal.id()] = &signal;
  }
  return detected_signals;
}

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

/**
 * @file
 **/

#include "modules/planning/lattice/behavior/signal_light_scenario.h"

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

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  auto signals_from_map = FindValidSignalLightFromMap(reference_line_info);
  if (signals_from_map.empty()) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  auto detected_signals = GetPerceptionDetectedSignals();

  StopPoint stop_point;
  stop_point.set_s(std::numeric_limits<double>::max());
  stop_point.set_type(StopPoint::HARD);
  for (const auto signal_from_map : signals_from_map) {
    auto it_signal = detected_signals.find(signal_from_map->object_id);
    if (it_signal == detected_signals.end()) {
      AWARN << "Cannot detect signal which is marked on the map; signal id: "
            << signal_from_map->object_id;
      continue;
    }

    if (signal_from_map->start_s < stop_point.s()) {
      stop_point.set_s(signal_from_map->start_s);
      if (it_signal->second->color() == TrafficLight::RED) {
        stop_point.set_type(StopPoint::HARD);
      } else if (it_signal->second->color() == TrafficLight::YELLOW) {
        stop_point.set_type(StopPoint::SOFT);
      }
    }
  }

  if (stop_point.s() < std::numeric_limits<double>::max() &&
      stop_point.has_type()) {
    planning_target->mutable_stop_point()->set_s(stop_point.s());
    planning_target->mutable_stop_point()->set_type(stop_point.type());
  }

  return 0;
}

std::vector<const hdmap::PathOverlap*>
SignalLightScenario::FindValidSignalLightFromMap(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() == 0) {
    ADEBUG << "No signal lights from reference line.";
    return std::vector<const hdmap::PathOverlap*>();
  }
  ADEBUG << "Found signal_lights size=" << signal_lights.size();

  std::vector<const hdmap::PathOverlap*> signal_lights_along_reference_line;
  for (const auto& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line;
}

std::unordered_map<std::string, const TrafficLight*>
SignalLightScenario::GetPerceptionDetectedSignals() {
  if (AdapterManager::GetTrafficLightDetection()->Empty() ||
      (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
       FLAGS_signal_expire_time_sec)) {
    ADEBUG << "traffic light signals msg is either empty or outdated.";
    return std::unordered_map<std::string, const TrafficLight*>();
  }

  std::unordered_map<std::string, const TrafficLight*> detected_signals;
  const auto& signal_msg =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();

  for (int j = 0; j < signal_msg.traffic_light_size(); ++j) {
    const auto& signal = signal_msg.traffic_light(j);
    detected_signals[signal.id()] = &signal;
  }
  return detected_signals;
}

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