<commit_before>/*
 * RewriteLink.cc
 *
 * Copyright (C) 2017 Nil Geisweiller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the
 * exceptions at http://opencog.org/wiki/Licenses
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <string>

#include <opencog/util/mt19937ar.h>
#include <opencog/util/random.h>
#include <opencog/util/Logger.h>
#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/core/TypeNode.h>
#include <opencog/atomutils/TypeUtils.h>
#include <opencog/atomutils/FindUtils.h>

#include "LambdaLink.h"
#include "RewriteLink.h"

using namespace opencog;

void RewriteLink::init(void)
{
	Type t = get_type();
	if (not classserver().isA(t, REWRITE_LINK))
	{
		const std::string& tname = classserver().getTypeName(t);
		throw InvalidParamException(TRACE_INFO,
			"Expecting a RewriteLink, got %s", tname.c_str());
	}
}

RewriteLink::RewriteLink(const Handle& vars, const Handle& body)
	: ScopeLink(HandleSeq({vars, body}), REWRITE_LINK), _silent(false)
{
	init();
}

RewriteLink::RewriteLink(const HandleSeq& oset, Type t)
	: ScopeLink(oset, t), _silent(false)
{
	if (skip_init(t)) return;
	init();
}

RewriteLink::RewriteLink(const Link &l)
	: ScopeLink(l), _silent(false)
{
	if (skip_init(l.get_type())) return;
	init();
}

/* ================================================================= */

inline Handle append_rand_str(const Handle& var)
{
	std::string new_var_name = randstr(var->get_name() + "-");
	return createNode(VARIABLE_NODE, new_var_name);
}

inline HandleSeq append_rand_str(const HandleSeq& vars)
{
	HandleSeq new_vars;
	for (const Handle& h : vars)
		new_vars.push_back(append_rand_str(h));
	return new_vars;
}

Handle RewriteLink::alpha_convert() const
{
	HandleSeq vars = append_rand_str(_varlist.varseq);
	return alpha_convert(vars);
}

Handle RewriteLink::alpha_convert(const HandleSeq& vars) const
{
	// Perform alpha conversion
	HandleSeq hs;
	for (size_t i = 0; i < get_arity(); ++i)
		hs.push_back(_varlist.substitute_nocheck(getOutgoingAtom(i), vars, _silent));

	// Create the alpha converted scope link
	return createLink(hs, get_type());
}

Handle RewriteLink::alpha_convert(const HandleMap& vsmap) const
{
	HandleSeq vars;
	for (const Handle& var : _varlist.varseq) {
		auto it = vsmap.find(var);
		vars.push_back(it == vsmap.end() ? append_rand_str(var) : it->second);
	}
	return alpha_convert(vars);
}

/* ================================================================= */

Handle RewriteLink::beta_reduce(const HandleMap& vm) const
{
	// Perform substitution over the variable declaration
	Handle nvardecl = substitute_vardecl(vm);

	// Perform substitution over the bodies
	HandleSeq hs = substitute_bodies(nvardecl, vm);

	// Filter vardecl
	nvardecl = filter_vardecl(nvardecl, hs);

	// Insert vardecl in the outgoing set, if defined
	if (nvardecl)
	{
		hs.insert(hs.begin(), nvardecl);
	}
	else
	{
		// Its illegal to create a PutLink that is not in the
		// form of a redex, i.e. doesn't have variable declarations
		// in it. So we must not call createLink(), below.
		Type t = get_type();
		if (PUT_LINK == t)
			return hs[0];
	}

	// Create the substituted scope.  I suspect that this is a bad
	// idea, when nvardecl==nullptr, I mean, its just gonna be weird,
	// and cause issues thhrought the code ... but ... whatever.
	return createLink(hs, get_type());
}

Handle RewriteLink::beta_reduce(const HandleSeq& vals) const
{
	const Variables& vars = get_variables();
	if (vals.size() != vars.size())
	{
		if (1 != vals.size() or LAMBDA_LINK != vals[0]->get_type())
		{
			if (_silent) return Handle::UNDEFINED;

			throw SyntaxException(TRACE_INFO,
				"RewriteLink has mismatched arity, expecting %lu == %lu",
				vars.size(), vals.size());
		}

		// Verify that eta reduction is possible...
		LambdaLinkPtr lam(LambdaLinkCast(vals[0]));
		const Handle& body = lam->get_body();
		if (body->get_arity() != vars.size())
		{
			if (_silent) return Handle::UNDEFINED;

			throw SyntaxException(TRACE_INFO,
				"RewriteLink has mismatched eta, expecting %lu == %lu",
				vars.size(), body->get_arity());
		}

	}

	if (1 == vals.size() and LAMBDA_LINK == vals[0]->get_type())
	{
		// Perform a very simple-minded eta reduction.
		LambdaLinkPtr lam(LambdaLinkCast(vals[0]));
		const Handle& body = lam->get_body();
		const HandleSeq& eta = body->getOutgoingSet();
		HandleMap vm;

		for (size_t i=0; i<eta.size(); i++)
			vm.insert({vars.varseq[i], eta[i]});
		return beta_reduce(vm);
	}

	HandleMap vm;
	for (size_t i=0; i<vals.size(); i++)
	{
		vm.insert({vars.varseq[i], vals[i]});
	}
	return beta_reduce(vm);
}

HandleSeq RewriteLink::substitute_bodies(const Handle& nvardecl,
                                         const HandleMap& vm) const
{
	const Variables& variables = get_variables();
	return beta_reduce_bodies(nvardecl, variables.make_sequence(vm));
}

HandleSeq RewriteLink::beta_reduce_bodies(const Handle& nvardecl,
                                         const HandleSeq& values) const
{
	HandleSeq hs;
	for (size_t i = (get_vardecl() ? 1 : 0); i < get_arity(); ++i)
	{
		const Handle& h = getOutgoingAtom(i);
		hs.push_back(substitute_body(nvardecl, h, values));
	}
	return hs;
}

Handle RewriteLink::substitute_body(const Handle& nvardecl,
                                    const Handle& body,
                                    const HandleSeq& values) const
{
	Handle nbody = get_variables().substitute(body, values, _silent);
	nbody = consume_ill_quotations(nvardecl, nbody);
	return nbody;
}

Handle RewriteLink::substitute_vardecl(const HandleMap& vm) const
{
	if (not get_vardecl())
		return Handle::UNDEFINED;

	return substitute_vardecl(get_vardecl(), vm);
}

Handle RewriteLink::substitute_vardecl(const Handle& vardecl,
                                       const HandleMap& vm)
{
	Type t = vardecl->get_type();

	// Base cases

	if (t == VARIABLE_NODE)
	{
		auto it = vm.find(vardecl);

		// Only substitute if the variable is substituted by another variable
		if (it == vm.end())
			return vardecl;
		if (it->second->get_type() == VARIABLE_NODE)
			return it->second;
		return Handle::UNDEFINED;
	}

	// Recursive cases

	HandleSeq oset;

	if (t == VARIABLE_LIST)
	{
		for (const Handle& h : vardecl->getOutgoingSet())
		{
			Handle nh = substitute_vardecl(h, vm);
			if (nh)
				oset.push_back(nh);
		}
		if (oset.empty())
			return Handle::UNDEFINED;
	}
	else if (t == TYPED_VARIABLE_LINK)
	{
		Handle new_var = substitute_vardecl(vardecl->getOutgoingAtom(0), vm);
		if (new_var)
		{
			oset.push_back(new_var);
			oset.push_back(vardecl->getOutgoingAtom(1));
		}
		else
			return Handle::UNDEFINED;
	}
	else
	{
		OC_ASSERT(false, "Not implemented");
	}
	return createLink(oset, t);
}

Handle RewriteLink::consume_ill_quotations() const
{
	Handle vardecl = get_vardecl();
	const Variables& variables = get_variables();
	HandleSeq nouts;
	for (size_t i = (get_vardecl() ? 1 : 0); i < get_arity(); ++i)
	{
		Handle nbody = consume_ill_quotations(variables, getOutgoingAtom(i));
		nouts.push_back(nbody);
		// If the new body has terms with free variables but no
		// vardecl it means that some quotations are missing. Rather
		// than adding them we set vardecl to an empty VariableList.
		if (not vardecl and not get_free_variables(nbody).empty())
			vardecl = Handle(createVariableList(HandleSeq{}));
	}

	if (vardecl)
		nouts.insert(nouts.begin(), vardecl);

	// Recreate the scope
	return createLink(nouts, get_type());
}

Handle RewriteLink::consume_ill_quotations(const Handle& vardecl,
                                           const Handle& h)
{
	return consume_ill_quotations(gen_variables(h, vardecl), h);
}

Handle RewriteLink::consume_ill_quotations(const Variables& variables, Handle h,
                                           Quotation quotation, bool escape)
{
	// Base case
	if (h->is_node())
		return h;

	// Recursive cases
	Type t = h->get_type();
	if (quotation.consumable(t)) {
		if (t == QUOTE_LINK) {
			Handle qh = h->getOutgoingAtom(0);
			// If it's a scope, check whether its vardecl is bound to
			// itself rather than the ancestor scope, if so the Quote
			// is harmful, consume it. Otherwise, for other quoted
			// link types, do not consume the quote and the subsequent
			// unquotes.
			if (classserver().isA(qh->get_type(), SCOPE_LINK) and
			    not is_bound_to_ancestor(variables, qh))
			{
				quotation.update(t);
				return consume_ill_quotations(variables, qh, quotation);
			} else {
				escape = true;
			}
		} else if (t == UNQUOTE_LINK) {
			Handle uh = h->getOutgoingAtom(0);
			// Either remove subsequent unquote associated by a
			// removed quote, or useless unquote because there are no
			// free variables to unquote
			if (not escape or get_free_variables(uh).empty()) {
				quotation.update(t);
				return consume_ill_quotations(variables, h->getOutgoingAtom(0),
				                              quotation);
			}
		}
		// Ignore LocalQuotes as they supposedly used only to quote
		// pattern matcher connectors.
	}

	quotation.update(t);
	HandleSeq consumed;
	for (const Handle outh : h->getOutgoingSet())
		consumed.push_back(consume_ill_quotations(variables, outh, quotation,
		                                          escape));

	return createLink(consumed, t);
}

bool RewriteLink::is_bound_to_ancestor(const Variables& variables,
                                       const Handle& local_scope)
{
	Handle unquote = local_scope->getOutgoingAtom(0);
	if (unquote->get_type() == UNQUOTE_LINK) {
		Handle var = unquote->getOutgoingAtom(0);
		return variables.is_in_varset(var);
	}
	return false;
}

/* ================================================================= */

DEFINE_LINK_FACTORY(RewriteLink, REWRITE_LINK);

/* ===================== END OF FILE ===================== */
<commit_msg>Whoops, should not have done that!<commit_after>/*
 * RewriteLink.cc
 *
 * Copyright (C) 2017 Nil Geisweiller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the
 * exceptions at http://opencog.org/wiki/Licenses
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <string>

#include <opencog/util/mt19937ar.h>
#include <opencog/util/random.h>
#include <opencog/util/Logger.h>
#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/core/TypeNode.h>
#include <opencog/atomutils/TypeUtils.h>
#include <opencog/atomutils/FindUtils.h>

#include "LambdaLink.h"
#include "RewriteLink.h"

using namespace opencog;

void RewriteLink::init(void)
{
	Type t = get_type();
	if (not classserver().isA(t, REWRITE_LINK))
	{
		const std::string& tname = classserver().getTypeName(t);
		throw InvalidParamException(TRACE_INFO,
			"Expecting a RewriteLink, got %s", tname.c_str());
	}
}

RewriteLink::RewriteLink(const Handle& vars, const Handle& body)
	: ScopeLink(HandleSeq({vars, body}), REWRITE_LINK), _silent(false)
{
	init();
}

RewriteLink::RewriteLink(const HandleSeq& oset, Type t)
	: ScopeLink(oset, t), _silent(false)
{
	if (skip_init(t)) return;
	init();
}

RewriteLink::RewriteLink(const Link &l)
	: ScopeLink(l), _silent(false)
{
	if (skip_init(l.get_type())) return;
	init();
}

/* ================================================================= */

inline Handle append_rand_str(const Handle& var)
{
	std::string new_var_name = randstr(var->get_name() + "-");
	return createNode(VARIABLE_NODE, new_var_name);
}

inline HandleSeq append_rand_str(const HandleSeq& vars)
{
	HandleSeq new_vars;
	for (const Handle& h : vars)
		new_vars.push_back(append_rand_str(h));
	return new_vars;
}

Handle RewriteLink::alpha_convert() const
{
	HandleSeq vars = append_rand_str(_varlist.varseq);
	return alpha_convert(vars);
}

Handle RewriteLink::alpha_convert(const HandleSeq& vars) const
{
	// Perform alpha conversion
	HandleSeq hs;
	for (size_t i = 0; i < get_arity(); ++i)
		hs.push_back(_varlist.substitute_nocheck(getOutgoingAtom(i), vars, _silent));

	// Create the alpha converted scope link
	return createLink(hs, get_type());
}

Handle RewriteLink::alpha_convert(const HandleMap& vsmap) const
{
	HandleSeq vars;
	for (const Handle& var : _varlist.varseq) {
		auto it = vsmap.find(var);
		vars.push_back(it == vsmap.end() ? append_rand_str(var) : it->second);
	}
	return alpha_convert(vars);
}

/* ================================================================= */

Handle RewriteLink::beta_reduce(const HandleMap& vm) const
{
	// Perform substitution over the variable declaration
	Handle nvardecl = substitute_vardecl(vm);

	// Perform substitution over the bodies
	HandleSeq hs = substitute_bodies(nvardecl, vm);

	// Filter vardecl
	nvardecl = filter_vardecl(nvardecl, hs);

	// Insert vardecl in the outgoing set, if defined
	if (nvardecl)
	{
		hs.insert(hs.begin(), nvardecl);
	}
	else
	{
		// Its illegal to create a PutLink that is not in the
		// form of a redex, i.e. doesn't have variable declarations
		// in it. So we must not call createLink(), below.
		Type t = get_type();
		if (PUT_LINK == t or LAMBDA_LINK == t)
			return hs[0];
	}

	// Create the substituted scope.  I suspect that this is a bad
	// idea, when nvardecl==nullptr, I mean, its just gonna be weird,
	// and cause issues thhrought the code ... but ... whatever.
	return createLink(hs, get_type());
}

Handle RewriteLink::beta_reduce(const HandleSeq& vals) const
{
	const Variables& vars = get_variables();
	if (vals.size() != vars.size())
	{
		if (1 != vals.size() or LAMBDA_LINK != vals[0]->get_type())
		{
			if (_silent) return Handle::UNDEFINED;

			throw SyntaxException(TRACE_INFO,
				"RewriteLink has mismatched arity, expecting %lu == %lu",
				vars.size(), vals.size());
		}

		// Verify that eta reduction is possible...
		LambdaLinkPtr lam(LambdaLinkCast(vals[0]));
		const Handle& body = lam->get_body();
		if (body->get_arity() != vars.size())
		{
			if (_silent) return Handle::UNDEFINED;

			throw SyntaxException(TRACE_INFO,
				"RewriteLink has mismatched eta, expecting %lu == %lu",
				vars.size(), body->get_arity());
		}

	}

	if (1 == vals.size() and LAMBDA_LINK == vals[0]->get_type())
	{
		// Perform a very simple-minded eta reduction.
		LambdaLinkPtr lam(LambdaLinkCast(vals[0]));
		const Handle& body = lam->get_body();
		const HandleSeq& eta = body->getOutgoingSet();
		HandleMap vm;

		for (size_t i=0; i<eta.size(); i++)
			vm.insert({vars.varseq[i], eta[i]});
		return beta_reduce(vm);
	}

	HandleMap vm;
	for (size_t i=0; i<vals.size(); i++)
	{
		vm.insert({vars.varseq[i], vals[i]});
	}
	return beta_reduce(vm);
}

HandleSeq RewriteLink::substitute_bodies(const Handle& nvardecl,
                                         const HandleMap& vm) const
{
	const Variables& variables = get_variables();
	return beta_reduce_bodies(nvardecl, variables.make_sequence(vm));
}

HandleSeq RewriteLink::beta_reduce_bodies(const Handle& nvardecl,
                                         const HandleSeq& values) const
{
	HandleSeq hs;
	for (size_t i = (get_vardecl() ? 1 : 0); i < get_arity(); ++i)
	{
		const Handle& h = getOutgoingAtom(i);
		hs.push_back(substitute_body(nvardecl, h, values));
	}
	return hs;
}

Handle RewriteLink::substitute_body(const Handle& nvardecl,
                                    const Handle& body,
                                    const HandleSeq& values) const
{
	Handle nbody = get_variables().substitute(body, values, _silent);
	nbody = consume_ill_quotations(nvardecl, nbody);
	return nbody;
}

Handle RewriteLink::substitute_vardecl(const HandleMap& vm) const
{
	if (not get_vardecl())
		return Handle::UNDEFINED;

	return substitute_vardecl(get_vardecl(), vm);
}

Handle RewriteLink::substitute_vardecl(const Handle& vardecl,
                                       const HandleMap& vm)
{
	Type t = vardecl->get_type();

	// Base cases

	if (t == VARIABLE_NODE)
	{
		auto it = vm.find(vardecl);

		// Only substitute if the variable is substituted by another variable
		if (it == vm.end())
			return vardecl;
		if (it->second->get_type() == VARIABLE_NODE)
			return it->second;
		return Handle::UNDEFINED;
	}

	// Recursive cases

	HandleSeq oset;

	if (t == VARIABLE_LIST)
	{
		for (const Handle& h : vardecl->getOutgoingSet())
		{
			Handle nh = substitute_vardecl(h, vm);
			if (nh)
				oset.push_back(nh);
		}
		if (oset.empty())
			return Handle::UNDEFINED;
	}
	else if (t == TYPED_VARIABLE_LINK)
	{
		Handle new_var = substitute_vardecl(vardecl->getOutgoingAtom(0), vm);
		if (new_var)
		{
			oset.push_back(new_var);
			oset.push_back(vardecl->getOutgoingAtom(1));
		}
		else
			return Handle::UNDEFINED;
	}
	else
	{
		OC_ASSERT(false, "Not implemented");
	}
	return createLink(oset, t);
}

Handle RewriteLink::consume_ill_quotations() const
{
	Handle vardecl = get_vardecl();
	const Variables& variables = get_variables();
	HandleSeq nouts;
	for (size_t i = (get_vardecl() ? 1 : 0); i < get_arity(); ++i)
	{
		Handle nbody = consume_ill_quotations(variables, getOutgoingAtom(i));
		nouts.push_back(nbody);
		// If the new body has terms with free variables but no
		// vardecl it means that some quotations are missing. Rather
		// than adding them we set vardecl to an empty VariableList.
		if (not vardecl and not get_free_variables(nbody).empty())
			vardecl = Handle(createVariableList(HandleSeq{}));
	}

	if (vardecl)
		nouts.insert(nouts.begin(), vardecl);

	// Recreate the scope
	return createLink(nouts, get_type());
}

Handle RewriteLink::consume_ill_quotations(const Handle& vardecl,
                                           const Handle& h)
{
	return consume_ill_quotations(gen_variables(h, vardecl), h);
}

Handle RewriteLink::consume_ill_quotations(const Variables& variables, Handle h,
                                           Quotation quotation, bool escape)
{
	// Base case
	if (h->is_node())
		return h;

	// Recursive cases
	Type t = h->get_type();
	if (quotation.consumable(t)) {
		if (t == QUOTE_LINK) {
			Handle qh = h->getOutgoingAtom(0);
			// If it's a scope, check whether its vardecl is bound to
			// itself rather than the ancestor scope, if so the Quote
			// is harmful, consume it. Otherwise, for other quoted
			// link types, do not consume the quote and the subsequent
			// unquotes.
			if (classserver().isA(qh->get_type(), SCOPE_LINK) and
			    not is_bound_to_ancestor(variables, qh))
			{
				quotation.update(t);
				return consume_ill_quotations(variables, qh, quotation);
			} else {
				escape = true;
			}
		} else if (t == UNQUOTE_LINK) {
			Handle uh = h->getOutgoingAtom(0);
			// Either remove subsequent unquote associated by a
			// removed quote, or useless unquote because there are no
			// free variables to unquote
			if (not escape or get_free_variables(uh).empty()) {
				quotation.update(t);
				return consume_ill_quotations(variables, h->getOutgoingAtom(0),
				                              quotation);
			}
		}
		// Ignore LocalQuotes as they supposedly used only to quote
		// pattern matcher connectors.
	}

	quotation.update(t);
	HandleSeq consumed;
	for (const Handle outh : h->getOutgoingSet())
		consumed.push_back(consume_ill_quotations(variables, outh, quotation,
		                                          escape));

	return createLink(consumed, t);
}

bool RewriteLink::is_bound_to_ancestor(const Variables& variables,
                                       const Handle& local_scope)
{
	Handle unquote = local_scope->getOutgoingAtom(0);
	if (unquote->get_type() == UNQUOTE_LINK) {
		Handle var = unquote->getOutgoingAtom(0);
		return variables.is_in_varset(var);
	}
	return false;
}

/* ================================================================= */

DEFINE_LINK_FACTORY(RewriteLink, REWRITE_LINK);

/* ===================== END OF FILE ===================== */
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/pcl_tests.h>

using namespace pcl;
using namespace pcl::test;

PointCloud<PointXYZ> cloud;
const size_t size = 10 * 480;

TEST (PointCloud, size)
{
  EXPECT_EQ(cloud.points.size (), cloud.size ());
}

TEST (PointCloud, sq_brackets_wrapper)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points[i].getVector3fMap (),
                       cloud[i].getVector3fMap ());
}

TEST (PointCloud, at)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points.at (i).getVector3fMap (),
                       cloud.at (i).getVector3fMap ());
}

TEST (PointCloud, front)
{
  EXPECT_EQ_VECTORS (cloud.points.front ().getVector3fMap (),
                     cloud.front ().getVector3fMap ());
}

TEST (PointCloud, back)
{
  EXPECT_EQ_VECTORS (cloud.points.back ().getVector3fMap (),
                     cloud.back ().getVector3fMap ());
}

TEST (PointCloud, constructor_with_allocation)
{
  PointCloud<PointXYZ> cloud2 (5, 80);
  EXPECT_EQ (cloud2.width, 5);
  EXPECT_EQ (cloud2.height, 80);
  EXPECT_EQ (cloud2.size (), 5*80);
}

TEST (PointCloud, insert_range)
{
  PointCloud<PointXYZ> cloud2 (10, 1);
  for (uint32_t i = 0; i < 10; ++i)
    cloud2[i] = PointXYZ (5*i+0,5*i+1,5*i+2);

  uint32_t old_size = cloud.size ();
  cloud.insert (cloud.begin (), cloud2.begin (), cloud2.end ());
  EXPECT_EQ (cloud.width, cloud.size ());
  EXPECT_EQ (cloud.height, 1);
  EXPECT_EQ (cloud.width, old_size + cloud2.size ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::const_iterator pit2 = cloud2.begin ();
  for (; pit2 < cloud2.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

int
main (int argc, char** argv)
{
  cloud.width = 10;
  cloud.height = 480;
  for (uint32_t i = 0; i < size; ++i)
    cloud.points.push_back (PointXYZ (3*i+0,3*i+1,3*i+2));

  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
<commit_msg>Add a test case for iterators<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/pcl_tests.h>

using namespace pcl;
using namespace pcl::test;

PointCloud<PointXYZ> cloud;
const size_t size = 10 * 480;

TEST (PointCloud, size)
{
  EXPECT_EQ(cloud.points.size (), cloud.size ());
}

TEST (PointCloud, sq_brackets_wrapper)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points[i].getVector3fMap (),
                       cloud[i].getVector3fMap ());
}

TEST (PointCloud, at)
{
  for (uint32_t i = 0; i < size; ++i)
    EXPECT_EQ_VECTORS (cloud.points.at (i).getVector3fMap (),
                       cloud.at (i).getVector3fMap ());
}

TEST (PointCloud, front)
{
  EXPECT_EQ_VECTORS (cloud.points.front ().getVector3fMap (),
                     cloud.front ().getVector3fMap ());
}

TEST (PointCloud, back)
{
  EXPECT_EQ_VECTORS (cloud.points.back ().getVector3fMap (),
                     cloud.back ().getVector3fMap ());
}

TEST (PointCloud, constructor_with_allocation)
{
  PointCloud<PointXYZ> cloud2 (5, 80);
  EXPECT_EQ (cloud2.width, 5);
  EXPECT_EQ (cloud2.height, 80);
  EXPECT_EQ (cloud2.size (), 5*80);
}

TEST (PointCloud, iterators)
{
  EXPECT_EQ_VECTORS (cloud.begin ()->getVector3fMap (),
                     cloud.points.begin ()->getVector3fMap ());
  EXPECT_EQ_VECTORS (cloud.end ()->getVector3fMap (),
                     cloud.points.end ()->getVector3fMap ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::VectorType::const_iterator pit2 = cloud.points.begin ();
  for (; pit < cloud.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

TEST (PointCloud, insert_range)
{
  PointCloud<PointXYZ> cloud2 (10, 1);
  for (uint32_t i = 0; i < 10; ++i)
    cloud2[i] = PointXYZ (5*i+0,5*i+1,5*i+2);

  uint32_t old_size = cloud.size ();
  cloud.insert (cloud.begin (), cloud2.begin (), cloud2.end ());
  EXPECT_EQ (cloud.width, cloud.size ());
  EXPECT_EQ (cloud.height, 1);
  EXPECT_EQ (cloud.width, old_size + cloud2.size ());
  PointCloud<PointXYZ>::const_iterator pit = cloud.begin ();
  PointCloud<PointXYZ>::const_iterator pit2 = cloud2.begin ();
  for (; pit2 < cloud2.end (); ++pit2, ++pit)
    EXPECT_EQ_VECTORS (pit->getVector3fMap (), pit2->getVector3fMap ());
}

int
main (int argc, char** argv)
{
  cloud.width = 10;
  cloud.height = 480;
  for (uint32_t i = 0; i < size; ++i)
    cloud.points.push_back (PointXYZ (3*i+0,3*i+1,3*i+2));

  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
#include <tf/transform_listener.h>
#include <Eigen/Dense>

ros::Publisher pub;

double height;
Eigen::Vector3d normal;

void callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::fromROSMsg(*msg, *cloud);

	for (size_t i = 0; i < cloud->size(); ++i) {

	}

	sensor_msgs::PointCloud2 msg_cloud;
    pcl::toROSMsg(voxel_cloud, msg_cloud);
	msg_cloud.header.frame_id = msg->header.frame_id;

	pub.publish(msg_cloud);
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "subsample_cloud");
	ros::NodeHandle n;

	ros::NodeHandle pn("~");
    // topic of input cloud
    if (!pn.hasParam("input")) {
        ROS_ERROR("Could not find parameter input.");
        return -1;
    }
    std::string input;
    pn.getParam("input", input);

    // topic of output cloud
    if (!pn.hasParam("obstacle_output")) {
        ROS_ERROR("Could not find parameter obstacle_output.");
        return -1;
    }
    std::string obstacle_output;
    pn.getParam("obstacle_output", obstacle_output);

    // topic of output cloud
    if (!pn.hasParam("camera_frame")) {
        ROS_ERROR("Could not find parameter camera_frame.");
        return -1;
    }
    std::string camera_frame;
    pn.getParam("camera_frame", camera_frame);

    // topic of output cloud
    if (!pn.hasParam("floor_output")) {
        ROS_ERROR("Could not find parameter floor_output.");
        return -1;
    }
    std::string floor_output;
    pn.getParam("floor_output", floor_output);

	ros::Subscriber sub = n.subscribe(input, 1, callback);
    pub = n.advertise<sensor_msgs::PointCloud2>(output, 1);

    tf::TransformListener listener;
    geometry_msgs::PointStamped pout;
    geometry_msgs::PointStamped pin;
    pin.point.x = 0; pin.point.y = 0; pin.point.z = 0;
    geometry_msgs::Vector3Stamped vout;
    geometry_msgs::Vector3Stamped vin;
    vin.vector.x = 0; vin.vector.y = 0; vin.vector.z = 1;

    ros::Rate rate(0.05); // updating at 5 hz, slightly faster than move_base
    while (n.ok()) {
        tf::StampedTransform transform;
        try {
            listener.lookupTransform("/base_link", camera_frame, ros::Time(0), transform);
            transform.transformPoint(camera_frame, ros::Time(0), pin, "/base_link", pout);
            height = pout.point.z;
            transform.transformVector3(camera_frame, ros::Time(0), vin, "/base_link", vout);
            normal = Eigen::Vector3d(vout.vector.x, vout.vector.y, vout.vector.z);
        }
        catch (tf::TransformException ex) {
            ROS_ERROR("%s",ex.what());
        }
        rate.sleep();
        ros::spinOnce();
    }

	return 0;
}
<commit_msg>Got the transforms working<commit_after>#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
#include <tf/transform_listener.h>
#include <Eigen/Dense>

ros::Publisher pub;

double height;
Eigen::Vector3d normal;

void callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::fromROSMsg(*msg, *cloud);

	for (size_t i = 0; i < cloud->size(); ++i) {

	}

	sensor_msgs::PointCloud2 msg_cloud;
    //pcl::toROSMsg(voxel_cloud, msg_cloud);
	msg_cloud.header.frame_id = msg->header.frame_id;

	pub.publish(msg_cloud);
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "subsample_cloud");
	ros::NodeHandle n;

	ros::NodeHandle pn("~");
    // topic of input cloud
    if (!pn.hasParam("input")) {
        ROS_ERROR("Could not find parameter input.");
        return -1;
    }
    std::string input;
    pn.getParam("input", input);

    // topic of output cloud
    if (!pn.hasParam("obstacle_output")) {
        ROS_ERROR("Could not find parameter obstacle_output.");
        return -1;
    }
    std::string obstacle_output;
    pn.getParam("obstacle_output", obstacle_output);

    // topic of output cloud
    if (!pn.hasParam("camera_frame")) {
        ROS_ERROR("Could not find parameter camera_frame.");
        return -1;
    }
    std::string camera_frame;
    pn.getParam("camera_frame", camera_frame);

    // topic of output cloud
    if (!pn.hasParam("floor_output")) {
        ROS_ERROR("Could not find parameter floor_output.");
        return -1;
    }
    std::string floor_output;
    pn.getParam("floor_output", floor_output);

	ros::Subscriber sub = n.subscribe(input, 1, callback);
    pub = n.advertise<sensor_msgs::PointCloud2>(obstacle_output, 1);

    std::string base_frame("map");//"base_link");
    tf::TransformListener listener;
    geometry_msgs::PointStamped pout;
    geometry_msgs::PointStamped pin;
    pin.header.frame_id = base_frame;
    pin.point.x = 0; pin.point.y = 0; pin.point.z = 0;
    geometry_msgs::Vector3Stamped vout;
    geometry_msgs::Vector3Stamped vin;
    vin.header.frame_id = base_frame;
    vin.vector.x = 0; vin.vector.y = 0; vin.vector.z = 1;

    ros::Rate rate(5); // updating at 5 hz, slightly faster than move_base
    while (n.ok()) {
        tf::StampedTransform transform;
        try {
            //listener.lookupTransform(camera_frame, "base_link", ros::Time(0), transform);
            listener.transformPoint(camera_frame, ros::Time(0), pin, base_frame, pout);
            height = pout.point.z;
            listener.transformVector(camera_frame, ros::Time(0), vin, base_frame, vout);
            normal = Eigen::Vector3d(vout.vector.x, vout.vector.y, vout.vector.z);
            //std::cout << transform << std::endl;
        }
        catch (tf::TransformException ex) {
            ROS_ERROR("%s",ex.what());
        }
        std::cout << height << std::endl;
        std::cout << normal.transpose() << std::endl;
        rate.sleep();
        ros::spinOnce();
    }

	return 0;
}
<|endoftext|>


<commit_before>#include "Accumulate.h"
#include "../Data.h"

VariableAccumulate::VariableAccumulate(const Options& iOptions, const Data& iData) : Variable(iOptions, iData),
      mTimeWindow(Global::MV) {
   // Which base variable should be accumulated?
   iOptions.getRequiredValue("baseVariable", mBaseVariable);
   //! Over how many hours should the variable be accumulated?
   //! Defaults to the beginning of the forecast period
   iOptions.getValue("timeWindow", mTimeWindow);

   loadOptionsFromBaseVariable();
   iOptions.check();
}

float VariableAccumulate::computeCore(int iDate,
                    int iInit,
                    float iOffset,
                    const Location& iLocation,
                    const Member& iMember,
                    Input::Type iType) const {

   float total = 0;
   ///////////////////////////////
   // Accumulating observations //
   ///////////////////////////////
   // When accumulating observations, we are allowed to look at yesterday's values.
   // This can happen for low offsets, where the accumulation window crosses into yesterday
   if(iType == Input::typeObservation) {
      float startOffset = iOffset - mTimeWindow; // Allowed to be negative
      std::string dataset = iMember.getDataset();
      std::vector<float> offsets = mData.getInput(dataset)->getOffsets();
      for(int i = 0; i < offsets.size(); i++) {
         float offset = offsets[i];
         if(offset < 24) { // Observations should never have offsets above 24, but just in case
            // Use a value from today
            if(offset > startOffset && offset <= iOffset) {
               float value = mData.getValue(iDate, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
            // Use a value from yesterday
            else if(offset > startOffset+24 && offset <= iOffset + 24) {
               int date = Global::getDate(iDate, -24); // yesterday
               float value = mData.getValue(date, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
         }
      }
   }
   ////////////////////////////
   // Accumulating forecasts //
   ////////////////////////////
   // Only accumulate values for forecasts valid at this initialization date/time
   else {
      if(Global::isValid(mTimeWindow) && iOffset > mTimeWindow) {
         // Do a regular sum between start and end offsets
         float startOffset = iOffset - mTimeWindow;
         std::string dataset = iMember.getDataset();
         std::vector<float> offsets = mData.getInput(dataset)->getOffsets();
         for(int i = 0; i < offsets.size(); i++) {
            float offset = offsets[i];
            if(offset > startOffset && offset <= iOffset) {
               float value = mData.getValue(iDate, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
         }
      }
      else {
         return Global::MV;
      }
   }

   return total;
}

std::string VariableAccumulate::getBaseVariable() const {
   // TODO:
   std::stringstream ss;
   if(Global::isValid(mTimeWindow))
      ss << mBaseVariable << "_" << (int) mTimeWindow;
   else
      ss << mBaseVariable << "_Acc";
   return ss.str();
}
<commit_msg>Fixed bug when accumulating<commit_after>#include "Accumulate.h"
#include "../Data.h"

VariableAccumulate::VariableAccumulate(const Options& iOptions, const Data& iData) : Variable(iOptions, iData),
      mTimeWindow(Global::MV) {
   // Which base variable should be accumulated?
   iOptions.getRequiredValue("baseVariable", mBaseVariable);
   //! Over how many hours should the variable be accumulated?
   //! Defaults to the beginning of the forecast period
   iOptions.getValue("timeWindow", mTimeWindow);

   loadOptionsFromBaseVariable();
   iOptions.check();
}

float VariableAccumulate::computeCore(int iDate,
                    int iInit,
                    float iOffset,
                    const Location& iLocation,
                    const Member& iMember,
                    Input::Type iType) const {

   float total = 0;
   ///////////////////////////////
   // Accumulating observations //
   ///////////////////////////////
   // When accumulating observations, we are allowed to look at yesterday's values.
   // This can happen for low offsets, where the accumulation window crosses into yesterday
   if(iType == Input::typeObservation) {
      float startOffset = iOffset - mTimeWindow; // Allowed to be negative
      std::string dataset = iMember.getDataset();
      std::vector<float> offsets = mData.getInput(dataset)->getOffsets();
      for(int i = 0; i < offsets.size(); i++) {
         float offset = offsets[i];
         if(offset < 24) { // Observations should never have offsets above 24, but just in case
            // Use a value from today
            if(offset > startOffset && offset <= iOffset) {
               float value = mData.getValue(iDate, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
            // Use a value from yesterday
            else if(offset > startOffset+24 && offset <= iOffset + 24) {
               int date = Global::getDate(iDate, -24); // yesterday
               float value = mData.getValue(date, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
         }
      }
   }
   ////////////////////////////
   // Accumulating forecasts //
   ////////////////////////////
   // Only accumulate values for forecasts valid at this initialization date/time
   else {
      if(Global::isValid(mTimeWindow) && iOffset >= mTimeWindow) {
         // Do a regular sum between start and end offsets
         float startOffset = iOffset - mTimeWindow;
         std::string dataset = iMember.getDataset();
         std::vector<float> offsets = mData.getInput(dataset)->getOffsets();
         for(int i = 0; i < offsets.size(); i++) {
            float offset = offsets[i];
            if(offset > startOffset && offset <= iOffset) {
               float value = mData.getValue(iDate, iInit, offset, iLocation, iMember, mBaseVariable);
               if(Global::isValid(value))
                  total += value;
               else
                  return Global::MV;
            }
         }
      }
      else {
         return Global::MV;
      }
   }

   return total;
}

std::string VariableAccumulate::getBaseVariable() const {
   // TODO:
   std::stringstream ss;
   if(Global::isValid(mTimeWindow))
      ss << mBaseVariable << "_" << (int) mTimeWindow;
   else
      ss << mBaseVariable << "_Acc";
   return ss.str();
}
<|endoftext|>


<commit_before>#include <coffee/core/plat/linking/libraries.h>

#include <coffee/core/coffee_strings.h>

#if defined(COFFEE_LINUX)
#include <dlfcn.h>
#elif defined(COFFEE_WINDOWS)
#include <Windows.h>
#endif

namespace Coffee{
namespace CLibraryLoader{

#if defined(COFFEE_LINUX)
struct CNativeObject
{
    void* handle;
    void* funptr;
};

void* _coffee_dlopen(cstring fname)
{
    void* handle = dlopen(fname,RTLD_NOW);
    if(!handle)
    {
        cLog(__FILE__,__LINE__,"CObjectLoader",CFStrings::Lib_load_error_format,fname);
    }
    return handle;
}

CNativeObject* _coffee_get_library(cstring file, cstring loaderFunction,
                                   const _cbasic_version<int32> *libver)
{
    CNativeObject *e = new CNativeObject;

    CString plat_file_name = "lib";
    plat_file_name += file;
    plat_file_name += ".so";

    e->handle = _coffee_dlopen(plat_file_name.c_str());

    if(libver&&!e->handle)
    {
        plat_file_name.append(cStringFormat(
                    ".{0}.{1}.{2}",
                    libver->major,
                    libver->minor,
                    libver->revision));
        e->handle = _coffee_dlopen(plat_file_name.c_str());
    }

    if(!e->handle)
    {
        delete e;
        return nullptr;
    }

    cstring error = nullptr;
    e->funptr = dlsym(e->handle,loaderFunction);
    if((error = dlerror()) != NULL)
    {
        cLog(__FILE__,__LINE__,CFStrings::Lib_Identifier,
             CFStrings::Lib_symb_error_format,error);
        _coffee_close_library(e);
        return nullptr;
    }

    return e;
}

void _coffee_close_library(CNativeObject* object)
{
    if(object->handle)
        dlclose(object->handle);
    delete object;
}

void* _coffee_get_funptr(CNativeObject* object)
{
    return object->funptr;
}
#endif

#if defined(COFFEE_WINDOWS)

struct CNativeObject
{
    HINSTANCE hinstLib;
    void* procedure;
};

CNativeObject* _coffee_get_library(cstring file, cstring loaderFunction,
                                   const _cbasic_version<int32> *libver)
{
    CNativeObject* e = new CNativeObject;

    CString plat_file_name = file;
    plat_file_name += ".dll";

    e->hinstLib = LoadLibrary(plat_file_name.c_str());

    if(!e->hinstLib)
    {
        cWarning(CFStrings::Lib_load_error_format,plat_file_name.c_str());
        _coffee_close_library(e);
        return nullptr;
    }

    e->procedure = GetProcAddress(e->hinstLib,loaderFunction);

    if(!e->procedure)
    {
        cWarning(CFStrings::Lib_symb_error_format,plat_file_name.c_str());
        _coffee_close_library(e);
        return nullptr;
    }

    return e;
}

void _coffee_close_library(CNativeObject* library)
{
    if(library->hinstLib)
        FreeLibrary(library->hinstLib);
    delete library;
}

void* _coffee_get_funptr(CNativeObject *object)
{
    return object->procedure;
}
#endif

}
}
<commit_msg> - Cast library pointer<commit_after>#include <coffee/core/plat/linking/libraries.h>

#include <coffee/core/coffee_strings.h>

#if defined(COFFEE_LINUX)
#include <dlfcn.h>
#elif defined(COFFEE_WINDOWS)
#include <Windows.h>
#endif

namespace Coffee{
namespace CLibraryLoader{

#if defined(COFFEE_LINUX)
struct CNativeObject
{
    void* handle;
    void* funptr;
};

void* _coffee_dlopen(cstring fname)
{
    void* handle = dlopen(fname,RTLD_NOW);
    if(!handle)
    {
        cLog(__FILE__,__LINE__,"CObjectLoader",CFStrings::Lib_load_error_format,fname);
    }
    return handle;
}

CNativeObject* _coffee_get_library(cstring file, cstring loaderFunction,
                                   const _cbasic_version<int32> *libver)
{
    CNativeObject *e = new CNativeObject;

    CString plat_file_name = "lib";
    plat_file_name += file;
    plat_file_name += ".so";

    e->handle = _coffee_dlopen(plat_file_name.c_str());

    if(libver&&!e->handle)
    {
        plat_file_name.append(cStringFormat(
                    ".{0}.{1}.{2}",
                    libver->major,
                    libver->minor,
                    libver->revision));
        e->handle = _coffee_dlopen(plat_file_name.c_str());
    }

    if(!e->handle)
    {
        delete e;
        return nullptr;
    }

    cstring error = nullptr;
    e->funptr = dlsym(e->handle,loaderFunction);
    if((error = dlerror()) != NULL)
    {
        cLog(__FILE__,__LINE__,CFStrings::Lib_Identifier,
             CFStrings::Lib_symb_error_format,error);
        _coffee_close_library(e);
        return nullptr;
    }

    return e;
}

void _coffee_close_library(CNativeObject* object)
{
    if(object->handle)
        dlclose(object->handle);
    delete object;
}

void* _coffee_get_funptr(CNativeObject* object)
{
    return object->funptr;
}
#endif

#if defined(COFFEE_WINDOWS)

struct CNativeObject
{
    HINSTANCE hinstLib;
    void* procedure;
};

CNativeObject* _coffee_get_library(cstring file, cstring loaderFunction,
                                   const _cbasic_version<int32> *libver)
{
    CNativeObject* e = new CNativeObject;

    CString plat_file_name = file;
    plat_file_name += ".dll";

    e->hinstLib = LoadLibrary(plat_file_name.c_str());

    if(!e->hinstLib)
    {
        cWarning(CFStrings::Lib_load_error_format,plat_file_name.c_str());
        _coffee_close_library(e);
        return nullptr;
    }

    e->procedure = (void*)GetProcAddress(e->hinstLib,loaderFunction);

    if(!e->procedure)
    {
        cWarning(CFStrings::Lib_symb_error_format,plat_file_name.c_str());
        _coffee_close_library(e);
        return nullptr;
    }

    return e;
}

void _coffee_close_library(CNativeObject* library)
{
    if(library->hinstLib)
        FreeLibrary(library->hinstLib);
    delete library;
}

void* _coffee_get_funptr(CNativeObject *object)
{
    return object->procedure;
}
#endif

}
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "amr_includes.H"
#include "no_solver_user.H"

#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif

void no_solver_linker(fclaw2d_domain_t* domain)
{
    link_problem_setup(domain,no_solver_setprob);

    /* Initialize data but don't do anything */

    fclaw2d_solver_functions_t* sf = get_solver_functions(domain);
    sf->f_patch_initialize = &no_solver_patch_initialize;
    sf->f_patch_single_step_update = &no_solver_update;

    fclaw2d_output_functions* of = get_output_functions(domain);
    of->f_patch_write_header = &matlab_parallel_write_header;
    of->f_patch_write_output = &matlab_parallel_write_output;

    link_regrid_functions(domain,no_solver_patch_tag4refinement,
                          no_solver_patch_tag4coarsening);
}

void no_solver_setprob(fclaw2d_domain_t* domain)
{
    set_maptype_();
}

void no_solver_patch_initialize(fclaw2d_domain_t *domain,
                                fclaw2d_patch_t *this_patch,
                                int this_block_idx,
                                int this_patch_idx)
{

    set_block_(&this_block_idx);

    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    // Parameters specific to this patch
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    // Pointers needed for the fortran
    double* q = cp->q();

    int mpirank = domain->mpirank;

    initialize_(mx,my,meqn,mbc,xlower,ylower,dx,dy,q,mpirank);
}

double no_solver_update(fclaw2d_domain_t *domain,
                        fclaw2d_patch_t *this_patch,
                        int this_block_idx,
                        int this_patch_idx,
                        double t,
                        double dt)
{
    ClawPatch *cp = get_clawpatch(this_patch);

    // save the current time step for time interpolation.  Otherwise, we get
    // unitialized values.
    cp->save_current_step();  // Save for time interpolation

    // Reinitialize with new proc data
    /*
    no_solver_patch_initialize(domain,this_patch, this_block_idx,this_patch_idx);
    */

    return 1.0;
}

/* -----------------------------------------------------------------
   Default routine for tagging patches for refinement and coarsening
   ----------------------------------------------------------------- */
fclaw_bool no_solver_patch_tag4refinement(fclaw2d_domain_t *domain,
                                          fclaw2d_patch_t *this_patch,
                                          int this_block_idx, int this_patch_idx,
                                          int initflag)
{
    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* q = cp->q();

    int tag_patch;  // == 0 or 1
    no_solver_tag4refinement_(mx,my,mbc,meqn,xlower,ylower,dx,dy,q,initflag,tag_patch);
    return tag_patch == 1;
}

fclaw_bool no_solver_patch_tag4coarsening(fclaw2d_domain_t *domain,
                                          fclaw2d_patch_t *this_patch,
                                          int blockno,
                                          int patchno)
{
    // This might come in handy if we want to debug a coarsening routine without
    // worrying about solvers.

    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* qcoarse = cp->q();

    int tag_patch;  // == 0 or 1
    no_solver_tag4coarsening_(mx,my,mbc,meqn,xlower,ylower,dx,dy,qcoarse,tag_patch);
    return tag_patch == 0;
}

void matlab_parallel_write_header(fclaw2d_domain_t* domain, int iframe, int ngrids)
{
    const amr_options_t *gparms = get_domain_parms(domain);
    double time = get_domain_time(domain);

    printf("Matlab output Frame %d  at time %16.8e\n\n",iframe,time);

    // Write out header file containing global information for 'iframe'
    int meqn = gparms->meqn;
    int maux = 0;
    write_tfile_(iframe,time,meqn,ngrids,maux);

    // This opens file 'fort.qXXXX' for replace (where XXXX = <zero padding><iframe>, e.g. 0001,
    // 0010, 0114), and closes the file.
    new_qfile_(iframe);
}

void matlab_parallel_write_output(fclaw2d_domain_t *domain, fclaw2d_patch_t *this_patch,
                                  int this_block_idx, int this_patch_idx,
                                  int iframe,int num,int level)
{
    // In case this is needed by the setaux routine
    set_block_(&this_block_idx);

    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* q = cp->q();

    // Other input arguments
    int maxmx = mx;
    int maxmy = my;

    /* ------------------------------------------------------------- */
    // This opens a file for append.  Now, the style is in the 'clawout' style.
    int matlab_level = level + 1;

    write_qfile_(maxmx,maxmy,meqn,mbc,mx,my,xlower,ylower,dx,dy,q,
                 iframe,num,matlab_level,this_block_idx);
}

#ifdef __cplusplus
#if 0
{
#endif
}
#endif
<commit_msg>Return desired_cfl guarantees time step will never change throughout run<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "amr_includes.H"
#include "no_solver_user.H"

#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif

void no_solver_linker(fclaw2d_domain_t* domain)
{
    link_problem_setup(domain,no_solver_setprob);

    /* Initialize data but don't do anything */

    fclaw2d_solver_functions_t* sf = get_solver_functions(domain);
    sf->f_patch_initialize = &no_solver_patch_initialize;
    sf->f_patch_single_step_update = &no_solver_update;

    fclaw2d_output_functions* of = get_output_functions(domain);
    of->f_patch_write_header = &matlab_parallel_write_header;
    of->f_patch_write_output = &matlab_parallel_write_output;

    link_regrid_functions(domain,no_solver_patch_tag4refinement,
                          no_solver_patch_tag4coarsening);
}

void no_solver_setprob(fclaw2d_domain_t* domain)
{
    set_maptype_();
}

void no_solver_patch_initialize(fclaw2d_domain_t *domain,
                                fclaw2d_patch_t *this_patch,
                                int this_block_idx,
                                int this_patch_idx)
{

    set_block_(&this_block_idx);

    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    // Parameters specific to this patch
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    // Pointers needed for the fortran
    double* q = cp->q();

    int mpirank = domain->mpirank;

    initialize_(mx,my,meqn,mbc,xlower,ylower,dx,dy,q,mpirank);
}

double no_solver_update(fclaw2d_domain_t *domain,
                        fclaw2d_patch_t *this_patch,
                        int this_block_idx,
                        int this_patch_idx,
                        double t,
                        double dt)
{
    const amr_options_t *gparms = get_domain_parms(domain);
    ClawPatch *cp = get_clawpatch(this_patch);

    // save the current time step for time interpolation.  Otherwise, we get
    // unitialized values.
    cp->save_current_step();  // Save for time interpolation

    // Reinitialize with new proc data
    /*
    no_solver_patch_initialize(domain,this_patch, this_block_idx,this_patch_idx);
    */

    return gparms->desired_cfl;
}

/* -----------------------------------------------------------------
   Default routine for tagging patches for refinement and coarsening
   ----------------------------------------------------------------- */
fclaw_bool no_solver_patch_tag4refinement(fclaw2d_domain_t *domain,
                                          fclaw2d_patch_t *this_patch,
                                          int this_block_idx, int this_patch_idx,
                                          int initflag)
{
    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* q = cp->q();

    int tag_patch;  // == 0 or 1
    no_solver_tag4refinement_(mx,my,mbc,meqn,xlower,ylower,dx,dy,q,initflag,tag_patch);
    return tag_patch == 1;
}

fclaw_bool no_solver_patch_tag4coarsening(fclaw2d_domain_t *domain,
                                          fclaw2d_patch_t *this_patch,
                                          int blockno,
                                          int patchno)
{
    // This might come in handy if we want to debug a coarsening routine without
    // worrying about solvers.

    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* qcoarse = cp->q();

    int tag_patch;  // == 0 or 1
    no_solver_tag4coarsening_(mx,my,mbc,meqn,xlower,ylower,dx,dy,qcoarse,tag_patch);
    return tag_patch == 0;
}

void matlab_parallel_write_header(fclaw2d_domain_t* domain, int iframe, int ngrids)
{
    const amr_options_t *gparms = get_domain_parms(domain);
    double time = get_domain_time(domain);

    printf("Matlab output Frame %d  at time %16.8e\n\n",iframe,time);

    // Write out header file containing global information for 'iframe'
    int meqn = gparms->meqn;
    int maux = 0;
    write_tfile_(iframe,time,meqn,ngrids,maux);

    // This opens file 'fort.qXXXX' for replace (where XXXX = <zero padding><iframe>, e.g. 0001,
    // 0010, 0114), and closes the file.
    new_qfile_(iframe);
}

void matlab_parallel_write_output(fclaw2d_domain_t *domain, fclaw2d_patch_t *this_patch,
                                  int this_block_idx, int this_patch_idx,
                                  int iframe,int num,int level)
{
    // In case this is needed by the setaux routine
    set_block_(&this_block_idx);

    /* ----------------------------------------------------------- */
    // Global parameters
    const amr_options_t *gparms = get_domain_parms(domain);
    int mx = gparms->mx;
    int my = gparms->my;
    int mbc = gparms->mbc;
    int meqn = gparms->meqn;

    /* ----------------------------------------------------------- */
    // Patch specific parameters
    ClawPatch *cp = get_clawpatch(this_patch);
    double xlower = cp->xlower();
    double ylower = cp->ylower();
    double dx = cp->dx();
    double dy = cp->dy();

    /* ------------------------------------------------------------ */
    // Pointers needed to pass to Fortran
    double* q = cp->q();

    // Other input arguments
    int maxmx = mx;
    int maxmy = my;

    /* ------------------------------------------------------------- */
    // This opens a file for append.  Now, the style is in the 'clawout' style.
    int matlab_level = level + 1;

    write_qfile_(maxmx,maxmy,meqn,mbc,mx,my,xlower,ylower,dx,dy,q,
                 iframe,num,matlab_level,this_block_idx);
}

#ifdef __cplusplus
#if 0
{
#endif
}
#endif
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  波形描画テンプレート・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <vector>
#include "gl_fw/glutils.hpp"

namespace view {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  render_waves template class
		@param[in]	UNIT	波形の型
		@param[in]	LIMIT	最大波形数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <typename UNIT, uint32_t LIMIT>
	class render_waves {

		std::vector<UNIT>	units_;

		double	div_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		render_waves() : units_(), div_(0.0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  波形生成
			@param[in]	time	生成時間 [sec]
			@param[in]	div		分解能 [sec]
			@return 生成した数
		*/
		//-----------------------------------------------------------------//
		uint32_t create_waves(double time, double div)
		{
			if(div <= 0.0 || time <= 0.0) return 0;

			auto n = time / div;

			if(n <= 0.0) return 0;
			else if(n > static_cast<double>(LIMIT)) return 0;

			units_.resize(static_cast<uint32_t>(n));

			div_ = div;  // 分解能

			return n;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  テスト波形生成
			@param[in]	frq		周波数 [Hz]
		*/
		//-----------------------------------------------------------------//
		void create_sin(double frq)
		{
			for(uint32_t i = 0; i < units_.size(); ++i) {
				double t = 1.0 / frq;
				units_[i] = static_cast<UNIT>(sin(2.0 * vtx::get_pi<double>() * t * i) * 32767.0) + 32768;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  描画
			@param[in]	width	横幅（ピクセル）
		*/
		//-----------------------------------------------------------------//
		void render(uint32_t width)
		{
			vtx::sposs list;
			list.resize(width);
			for(uint32_t i = 0; i < width; ++i) {
				list[i] = vtx::spos(i, units_[i] / 256);
			}

			gl::draw_line_strip(list);
		}
	};
}
<commit_msg>update sign<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  波形描画テンプレート・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <vector>
#include "gl_fw/glutils.hpp"

namespace view {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  render_waves template class
		@param[in]	UNIT	波形の型
		@param[in]	LIMIT	最大波形数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <typename UNIT, uint32_t LIMIT>
	class render_waves {

		std::vector<UNIT>	units_;

		double	div_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		render_waves() : units_(), div_(0.0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  波形生成
			@param[in]	time	生成時間 [sec]
			@param[in]	div		分解能 [sec]
			@return 生成した数
		*/
		//-----------------------------------------------------------------//
		uint32_t create_waves(double time, double div)
		{
			if(div <= 0.0 || time <= 0.0) return 0;

			auto n = time / div;

			if(n <= 0.0) return 0;
			else if(n > static_cast<double>(LIMIT)) return 0;

			units_.resize(static_cast<uint32_t>(n));

			div_ = div;  // 分解能

			return n;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  テスト波形生成
			@param[in]	frq		周波数 [Hz]
		*/
		//-----------------------------------------------------------------//
		void create_sin(double frq)
		{
			for(uint32_t i = 0; i < units_.size(); ++i) {
				double t = 1.0 / frq;
				units_[i] = 32768 - static_cast<UNIT>(sin(2.0 * vtx::get_pi<double>() * t * i) * 32767.0);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  描画
			@param[in]	width	横幅（ピクセル）
		*/
		//-----------------------------------------------------------------//
		void render(uint32_t width)
		{
			vtx::sposs list;
			list.resize(width);
			for(uint32_t i = 0; i < width; ++i) {
				list[i] = vtx::spos(i, units_[i] / 256);
			}
			gl::draw_line_strip(list);
		}
	};
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: b3dentty.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _B3D_B3DENTITY_HXX
#include "b3dentty.hxx"
#endif

#ifndef _B3D_B3DCOMMN_HXX
#include "b3dcommn.hxx"
#endif

#ifndef _B3D_B3DTRANS_HXX
#include "b3dtrans.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

/*************************************************************************
|*
|* Kopieren eine 3DEntity
|*
\************************************************************************/

void B3dEntity::Copy(B3dEntity& rEnt)
{
    aPoint = rEnt.Point();
    bDeviceCoor = rEnt.IsDeviceCoor();
    bValid = rEnt.IsValid();
    bEdgeFlag = rEnt.IsEdgeVisible();
    aPlaneNormal = rEnt.PlaneNormal();

    if(bNormalUsed = rEnt.IsNormalUsed())
        aNormal = rEnt.Normal();

    if(bTexCoorUsed = rEnt.IsTexCoorUsed())
        aTexCoor = rEnt.TexCoor();

    aColor = rEnt.Color();
}

/*************************************************************************
|*
|* Flags auf Ausgangsposition
|*
\************************************************************************/

void B3dEntity::Reset()
{
    bValid = bNormalUsed = bTexCoorUsed = bDeviceCoor = FALSE;
    bEdgeFlag = TRUE;
}

/*************************************************************************
|*
|* Device Koordinaten des Punktes berechnen
|*
\************************************************************************/

void B3dEntity::ImplToDeviceCoor(B3dTransformationSet* pSet)
{
    if(pSet && !bDeviceCoor)
    {
        const Vector3D& rScale = pSet->GetScale();
        const Vector3D& rTrans = pSet->GetTranslate();

        aPoint.Homogenize();
        aPoint[0] = (aPoint[0] * rScale[0]) + rTrans[0];
        aPoint[1] = (aPoint[1] * rScale[1]) + rTrans[1];
        aPoint[2] = (aPoint[2] * rScale[2]) + rTrans[2];

        bDeviceCoor = TRUE;
    }
}

/*************************************************************************
|*
|* aus Device Koordinaten des Punktes 3D Koor im canonical view volume
|* berechnen
|*
\************************************************************************/

void B3dEntity::ImplTo3DCoor(B3dTransformationSet* pSet)
{
    if(pSet && bDeviceCoor)
    {
        const Vector3D& rScale = pSet->GetScale();
        const Vector3D& rTrans = pSet->GetTranslate();

        aPoint.Homogenize();
        if(rScale[0] != 0.0)
            aPoint[0] = (aPoint[0] - rTrans[0]) / rScale[0];
        if(rScale[1] != 0.0)
            aPoint[1] = (aPoint[1] - rTrans[1]) / rScale[1];
        if(rScale[2] != 0.0)
            aPoint[2] = (aPoint[2] - rTrans[2]) / rScale[2];

        bDeviceCoor = FALSE;
    }
}

/*************************************************************************
|*
|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder
|* Devicekoordinaten)
|*
\************************************************************************/

void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld)
{
    if(IsDeviceCoor() && rOld.IsDeviceCoor())
    {
        SetDeviceCoor();
    }
    else
    {
        if(IsDeviceCoor())
            To3DCoor(pSet);
        if(rOld.IsDeviceCoor())
            rOld.To3DCoor(pSet);
    }
}

/*************************************************************************
|*
|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder
|* Devicekoordinaten)
|*
\************************************************************************/

void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld1,
    B3dEntity& rOld2)
{
    if(!IsDeviceCoor() && rOld1.IsDeviceCoor() && rOld2.IsDeviceCoor())
    {
        if(IsDeviceCoor())
            To3DCoor(pSet);
        if(rOld1.IsDeviceCoor())
            rOld1.To3DCoor(pSet);
        if(rOld2.IsDeviceCoor())
            rOld2.To3DCoor(pSet);
    }
}

/*************************************************************************
|*
|* Neuen Punkt an der stelle t des parametrisierten Vektors rOld1, rOld2
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcInBetween(B3dEntity& rOld1, B3dEntity& rOld2, double t)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcInBetween(rOld1.Point(), rOld2.Point(), t);
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    aPlaneNormal.CalcInBetween(rOld1.PlaneNormal(), rOld2.PlaneNormal(), t);
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        aNormal.CalcInBetween(rOld1.Normal(), rOld2.Normal(), t);
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed())
    {
        aTexCoor.CalcInBetween(rOld1.TexCoor(), rOld2.TexCoor(), t);
        SetTexCoorUsed();
    }

    // EdgeVisible berechnen
    SetEdgeVisible(rOld1.IsEdgeVisible());

    // Farbe berechnen
    aColor.CalcInBetween(rOld1.Color(), rOld2.Color(), t);
}

/*************************************************************************
|*
|* Neuen Punkt in der Mitte des parametrisierten Vektors rOld1, rOld2
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcMiddle(rOld1.Point(), rOld2.Point());
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal());
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal());
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed())
    {
        aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor());
        SetTexCoorUsed();
    }

    // EdgeVisible berechnen
    SetEdgeVisible(rOld1.IsEdgeVisible());

    // Farbe berechnen
    aColor.CalcMiddle(rOld1.Color(), rOld2.Color());
}

/*************************************************************************
|*
|* Neuen Punkt in der Mitte des Dreiecks rOld1, rOld2, rOld3
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2,
    B3dEntity& rOld3)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcMiddle(rOld1.Point(), rOld2.Point(), rOld3.Point());
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    rOld3.PlaneNormal().Normalize();
    aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal(), rOld3.PlaneNormal());
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed() && rOld3.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        rOld3.Normal().Normalize();
        aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal(), rOld3.Normal());
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed() && rOld3.IsTexCoorUsed())
    {
        aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor(), rOld3.TexCoor());
        SetTexCoorUsed();
    }

    // Farbe berechnen
    aColor.CalcMiddle(rOld1.Color(), rOld2.Color(), rOld3.Color());
}

/*************************************************************************
|*
|* Eine beliebige Transformation auf die Geometrie anwenden
|*
\************************************************************************/

void B3dEntity::Transform(const Matrix4D& rMat)
{
    aPoint *= rMat;
    if(bNormalUsed)
        rMat.RotateAndNormalize(aNormal);
}

/*************************************************************************
|*
|* Bucket fuer geometrische Daten
|*
\************************************************************************/

BASE3D_IMPL_BUCKET(B3dEntity, Bucket)

<commit_msg>INTEGRATION: CWS ooo20040815 (1.1.1.1.240); FILE MERGED 2004/08/04 13:31:01 waratah 1.1.1.1.240.1: #i32569# separate assignment from if statements<commit_after>/*************************************************************************
 *
 *  $RCSfile: b3dentty.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-09 11:25:03 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _B3D_B3DENTITY_HXX
#include "b3dentty.hxx"
#endif

#ifndef _B3D_B3DCOMMN_HXX
#include "b3dcommn.hxx"
#endif

#ifndef _B3D_B3DTRANS_HXX
#include "b3dtrans.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

/*************************************************************************
|*
|* Kopieren eine 3DEntity
|*
\************************************************************************/

void B3dEntity::Copy(B3dEntity& rEnt)
{
    aPoint = rEnt.Point();
    bDeviceCoor = rEnt.IsDeviceCoor();
    bValid = rEnt.IsValid();
    bEdgeFlag = rEnt.IsEdgeVisible();
    aPlaneNormal = rEnt.PlaneNormal();

    bNormalUsed = rEnt.IsNormalUsed();
    if( bNormalUsed )
        aNormal = rEnt.Normal();

    bTexCoorUsed = rEnt.IsTexCoorUsed();
    if( bTexCoorUsed )
        aTexCoor = rEnt.TexCoor();

    aColor = rEnt.Color();
}

/*************************************************************************
|*
|* Flags auf Ausgangsposition
|*
\************************************************************************/

void B3dEntity::Reset()
{
    bValid = bNormalUsed = bTexCoorUsed = bDeviceCoor = FALSE;
    bEdgeFlag = TRUE;
}

/*************************************************************************
|*
|* Device Koordinaten des Punktes berechnen
|*
\************************************************************************/

void B3dEntity::ImplToDeviceCoor(B3dTransformationSet* pSet)
{
    if(pSet && !bDeviceCoor)
    {
        const Vector3D& rScale = pSet->GetScale();
        const Vector3D& rTrans = pSet->GetTranslate();

        aPoint.Homogenize();
        aPoint[0] = (aPoint[0] * rScale[0]) + rTrans[0];
        aPoint[1] = (aPoint[1] * rScale[1]) + rTrans[1];
        aPoint[2] = (aPoint[2] * rScale[2]) + rTrans[2];

        bDeviceCoor = TRUE;
    }
}

/*************************************************************************
|*
|* aus Device Koordinaten des Punktes 3D Koor im canonical view volume
|* berechnen
|*
\************************************************************************/

void B3dEntity::ImplTo3DCoor(B3dTransformationSet* pSet)
{
    if(pSet && bDeviceCoor)
    {
        const Vector3D& rScale = pSet->GetScale();
        const Vector3D& rTrans = pSet->GetTranslate();

        aPoint.Homogenize();
        if(rScale[0] != 0.0)
            aPoint[0] = (aPoint[0] - rTrans[0]) / rScale[0];
        if(rScale[1] != 0.0)
            aPoint[1] = (aPoint[1] - rTrans[1]) / rScale[1];
        if(rScale[2] != 0.0)
            aPoint[2] = (aPoint[2] - rTrans[2]) / rScale[2];

        bDeviceCoor = FALSE;
    }
}

/*************************************************************************
|*
|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder
|* Devicekoordinaten)
|*
\************************************************************************/

void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld)
{
    if(IsDeviceCoor() && rOld.IsDeviceCoor())
    {
        SetDeviceCoor();
    }
    else
    {
        if(IsDeviceCoor())
            To3DCoor(pSet);
        if(rOld.IsDeviceCoor())
            rOld.To3DCoor(pSet);
    }
}

/*************************************************************************
|*
|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder
|* Devicekoordinaten)
|*
\************************************************************************/

void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld1,
    B3dEntity& rOld2)
{
    if(!IsDeviceCoor() && rOld1.IsDeviceCoor() && rOld2.IsDeviceCoor())
    {
        if(IsDeviceCoor())
            To3DCoor(pSet);
        if(rOld1.IsDeviceCoor())
            rOld1.To3DCoor(pSet);
        if(rOld2.IsDeviceCoor())
            rOld2.To3DCoor(pSet);
    }
}

/*************************************************************************
|*
|* Neuen Punkt an der stelle t des parametrisierten Vektors rOld1, rOld2
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcInBetween(B3dEntity& rOld1, B3dEntity& rOld2, double t)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcInBetween(rOld1.Point(), rOld2.Point(), t);
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    aPlaneNormal.CalcInBetween(rOld1.PlaneNormal(), rOld2.PlaneNormal(), t);
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        aNormal.CalcInBetween(rOld1.Normal(), rOld2.Normal(), t);
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed())
    {
        aTexCoor.CalcInBetween(rOld1.TexCoor(), rOld2.TexCoor(), t);
        SetTexCoorUsed();
    }

    // EdgeVisible berechnen
    SetEdgeVisible(rOld1.IsEdgeVisible());

    // Farbe berechnen
    aColor.CalcInBetween(rOld1.Color(), rOld2.Color(), t);
}

/*************************************************************************
|*
|* Neuen Punkt in der Mitte des parametrisierten Vektors rOld1, rOld2
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcMiddle(rOld1.Point(), rOld2.Point());
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal());
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal());
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed())
    {
        aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor());
        SetTexCoorUsed();
    }

    // EdgeVisible berechnen
    SetEdgeVisible(rOld1.IsEdgeVisible());

    // Farbe berechnen
    aColor.CalcMiddle(rOld1.Color(), rOld2.Color());
}

/*************************************************************************
|*
|* Neuen Punkt in der Mitte des Dreiecks rOld1, rOld2, rOld3
|* berechnen und fuellen
|*
\************************************************************************/

void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2,
    B3dEntity& rOld3)
{
    // DeviceCoor der ersten Quelle benutzen, die Basis sollte
    // vorher abgeglichen sein
    SetDeviceCoor(rOld1.IsDeviceCoor());

    // Punktkoordinaten berechnen
    aPoint.CalcMiddle(rOld1.Point(), rOld2.Point(), rOld3.Point());
    SetValid();

    // PlaneNormal Koordinaten berechnen
    rOld1.PlaneNormal().Normalize();
    rOld2.PlaneNormal().Normalize();
    rOld3.PlaneNormal().Normalize();
    aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal(), rOld3.PlaneNormal());
    aPlaneNormal.Normalize();

    // Vektor berechnen
    if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed() && rOld3.IsNormalUsed())
    {
        rOld1.Normal().Normalize();
        rOld2.Normal().Normalize();
        rOld3.Normal().Normalize();
        aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal(), rOld3.Normal());
        aNormal.Normalize();
        SetNormalUsed();
    }

    // Texturkoordinaten berechnen
    if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed() && rOld3.IsTexCoorUsed())
    {
        aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor(), rOld3.TexCoor());
        SetTexCoorUsed();
    }

    // Farbe berechnen
    aColor.CalcMiddle(rOld1.Color(), rOld2.Color(), rOld3.Color());
}

/*************************************************************************
|*
|* Eine beliebige Transformation auf die Geometrie anwenden
|*
\************************************************************************/

void B3dEntity::Transform(const Matrix4D& rMat)
{
    aPoint *= rMat;
    if(bNormalUsed)
        rMat.RotateAndNormalize(aNormal);
}

/*************************************************************************
|*
|* Bucket fuer geometrische Daten
|*
\************************************************************************/

BASE3D_IMPL_BUCKET(B3dEntity, Bucket)

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Esrille Inc.
 *
 * 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 "StackingContext.h"

#include <new>
#include <iostream>

namespace org { namespace w3c { namespace dom { namespace bootstrap {

StackingContext* StackingContext::removeChild(StackingContext* item)
{
    StackingContext* next = item->nextSibling;
    StackingContext* prev = item->previousSibling;
    if (!next)
        lastChild = prev;
    else
        next->previousSibling = prev;
    if (!prev)
        firstChild = next;
    else
        prev->nextSibling = next;
    item->parent = 0;
    --childCount;
    return item;
}

StackingContext* StackingContext::insertBefore(StackingContext* item, StackingContext* after)
{
    if (!after)
        return appendChild(item);
    item->previousSibling = after->previousSibling;
    item->nextSibling = after;
    after->previousSibling = item;
    if (!item->previousSibling)
        firstChild = item;
    else
        item->previousSibling->nextSibling = item;
    item->parent = this;
    ++childCount;
    return item;
}

StackingContext* StackingContext::appendChild(StackingContext* item)
{
    StackingContext* prev = lastChild;
    if (!prev)
        firstChild = item;
    else
        prev->nextSibling = item;
    item->previousSibling = prev;
    item->nextSibling = 0;
    lastChild = item;
    item->parent = this;
    ++childCount;
    return item;
}

StackingContext::StackingContext(int zIndex) :
    zIndex(zIndex),
    z1(0.0f),
    z3(0.0f),
    parent(0),
    firstChild(0),
    lastChild(0),
    previousSibling(0),
    nextSibling(0),
    childCount(0),
    zero(0)
{
}

StackingContext::~StackingContext()
{
    if (parent)
        parent->removeChild(this);
    while (0 < childCount) {
        StackingContext* child = removeChild(firstChild);
        delete child;
    }
}

StackingContext* StackingContext::getAuto()
{
    if (zIndex == 0)
        return this;
    if (!zero)
        zero = addContext(0);
    return zero;
}

StackingContext* StackingContext::addContext(int zIndex)
{
    if (isAuto())
        return parent->addContext(zIndex);

    StackingContext* after = 0;
    for (auto i = getFirstChild(); i; i = i->getNextSibling()) {
        if (zIndex < i->zIndex) {
            after = i;
            break;
        }
    }
    StackingContext* item = new(std::nothrow) StackingContext(zIndex);
    if (item)
        insertBefore(item, after);
    return item;

}

float StackingContext::eval(float z)
{
    z += 1.0f;
    z1 = z3 = z;
    for (auto i = getFirstChild(); i; i = i->getNextSibling()) {
        z = i->eval(z);
        if (i->zIndex < 0) {
            z += 1.0f;
            z3 = z;
        }
    }
    return z;
}

void StackingContext::dump(std::string indent)
{
    std::cout << indent << "z-index: " << zIndex << " " << z1 << " " << z3 << "\n";
    indent += "    ";
    for (auto child = getFirstChild(); child; child = child->getNextSibling())
        child->dump(indent);
}

}}}}  // org::w3c::dom::bootstrap<commit_msg>(StackingContext::getAuto) : Fix a bug.<commit_after>/*
 * Copyright 2011 Esrille Inc.
 *
 * 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 "StackingContext.h"

#include <new>
#include <iostream>

namespace org { namespace w3c { namespace dom { namespace bootstrap {

StackingContext* StackingContext::removeChild(StackingContext* item)
{
    StackingContext* next = item->nextSibling;
    StackingContext* prev = item->previousSibling;
    if (!next)
        lastChild = prev;
    else
        next->previousSibling = prev;
    if (!prev)
        firstChild = next;
    else
        prev->nextSibling = next;
    item->parent = 0;
    --childCount;
    return item;
}

StackingContext* StackingContext::insertBefore(StackingContext* item, StackingContext* after)
{
    if (!after)
        return appendChild(item);
    item->previousSibling = after->previousSibling;
    item->nextSibling = after;
    after->previousSibling = item;
    if (!item->previousSibling)
        firstChild = item;
    else
        item->previousSibling->nextSibling = item;
    item->parent = this;
    ++childCount;
    return item;
}

StackingContext* StackingContext::appendChild(StackingContext* item)
{
    StackingContext* prev = lastChild;
    if (!prev)
        firstChild = item;
    else
        prev->nextSibling = item;
    item->previousSibling = prev;
    item->nextSibling = 0;
    lastChild = item;
    item->parent = this;
    ++childCount;
    return item;
}

StackingContext::StackingContext(int zIndex) :
    zIndex(zIndex),
    z1(0.0f),
    z3(0.0f),
    parent(0),
    firstChild(0),
    lastChild(0),
    previousSibling(0),
    nextSibling(0),
    childCount(0),
    zero(0)
{
}

StackingContext::~StackingContext()
{
    if (parent)
        parent->removeChild(this);
    while (0 < childCount) {
        StackingContext* child = removeChild(firstChild);
        delete child;
    }
}

StackingContext* StackingContext::getAuto()
{
    if (isAuto())
        return this;
    if (!zero)
        zero = addContext(0);
    return zero;
}

StackingContext* StackingContext::addContext(int zIndex)
{
    if (isAuto())
        return parent->addContext(zIndex);

    StackingContext* after = 0;
    for (auto i = getFirstChild(); i; i = i->getNextSibling()) {
        if (zIndex < i->zIndex) {
            after = i;
            break;
        }
    }
    StackingContext* item = new(std::nothrow) StackingContext(zIndex);
    if (item)
        insertBefore(item, after);
    return item;

}

float StackingContext::eval(float z)
{
    z += 1.0f;
    z1 = z3 = z;
    for (auto i = getFirstChild(); i; i = i->getNextSibling()) {
        z = i->eval(z);
        if (i->zIndex < 0) {
            z += 1.0f;
            z3 = z;
        }
    }
    return z;
}

void StackingContext::dump(std::string indent)
{
    std::cout << indent << "z-index: " << zIndex << " " << z1 << " " << z3 << "\n";
    indent += "    ";
    for (auto child = getFirstChild(); child; child = child->getNextSibling())
        child->dump(indent);
}

}}}}  // org::w3c::dom::bootstrap<|endoftext|>