<commit_before>#ifndef VG_GRAPH_SYNCHRONIZER_H
#define VG_GRAPH_SYNCHRONIZER_H

/**
 * \file graph_synchronizer.hpp: define a GraphSynchronizer that can manage
 * concurrent access and updates to a VG graph.
 */

#include "vg.hpp"
#include "path_index.hpp"

#include <thread>
#include <mutex>
#include <condition_variable>

namespace vg {

using namespace std;

/**
 * Let threads get exclusive locks on subgraphs of a vg graph, for reading and
 * editing. Whan a subgraph is locked, a copy is accessible through the lock
 * object and the underlying graph can be edited (through the lock) without
 * affecting any other locked subgraphs.
 *
 * A thread may only hold a lock on a single subgraph at a time. Trying to lock
 * another subgraph while you already have a subgraph locked is likely to result
 * in a deadlock.
 */
class GraphSynchronizer {

public:

    /**
     * Create a GraphSynchronizer for synchronizing on parts of the given graph.
     */
    GraphSynchronizer(VG& graph);

    /**
     * Since internally we keep PathIndexes for paths in the graph, we expose
     * this method for getting the strings for paths.
     */
    const string& get_path_sequence(const string& path_name);

    /**
     * We can actually let users run whatever function they want with an
     * exclusive handle on a PathIndex, with the guarantee that the graph won't
     * change while they're working.
     */
    void with_path_index(const string& path_name, const function<void(const PathIndex&)>& to_run);

    /**
     * This represents a request to lock a particular context on a particular
     * GraphSynchronizer. It fulfils the BasicLockable concept requirements, so
     * you can wait on it with std::unique_lock.
     */
    class Lock {
    public:

        /**
         * Create a request to lock a certain radius around a certain position
         * along a certain path in the graph controlled by the given
         * synchronizer.
         */
        Lock(GraphSynchronizer& synchronizer, const string& path_name, size_t path_offset, size_t context_bases, bool reflect);

        /**
         * Create a request to lock a certain range of a certain path, from
         * start to end. The start and end positions must line up with the
         * boundaries of nodes in the graph. Also locks attached things that can
         * be reached by paths of the same length or shorter. Note that the
         * range must be nonempty.
         */
        Lock(GraphSynchronizer& synchronizer, const string& path_name, size_t start, size_t past_end);

        /**
         * Block until a lock is obtained.
         */
        void lock();

        /**
         * If a lock is held, unlock it.
         */
        void unlock();

        /**
         * May only be called when locked. Grab the subgraph that was extracted
         * when the lock was obtained. Does not contain any path information.
         */
        VG& get_subgraph();

        /**
         * May only be called when locked. Returns the pair of NodeSides
         * corresponding to the start and end positions used when the lock was
         * created.
         *
         * May only be called on locks that lock a start to end range.
         */
        pair<NodeSide, NodeSide> get_endpoints() const;

        /**
         * Get the NodeSides for nodes not in the extracted subgraph but in its
         * periphery that are attached to the given NodeSide in the subgraph.
         */
        set<NodeSide> get_peripheral_attachments(NodeSide graph_side);

        /**
         * May only be called when locked. Apply an edit against the base graph
         * and return the resulting translation. Note that this updates only the
         * underlying VG graph, not the copy of the locked subgraph stored in
         * the lock. Also note that the edit may only edit locked nodes.
         *
         * Edit operations will create new nodes, and cannot delete nodes or
         * apply changes (other than dividing and connecting) to existing nodes.
         *
         * Any new nodes created are created already locked.
         *
         * Any new nodes created on the left of the alignment (and any existing
         * nodes visited) will be attached to the given "dangling" NodeSides.
         * The set will be populated with the NodeSides for the ends of nodes
         * created/visited at the end of the alignment.
         */
        vector<Translation> apply_edit(const Path& path, set<NodeSide>& dangling);

        /**
         * May only be called when locked. Apply a path as an edit to the base
         * graph, leaving new nodes at the ends of the path unattached on their
         * outer sides.
         */
        vector<Translation> apply_edit(const Path& path);

        /**
         * May only be called when locked. Apply a path as an edit to the base
         * graph, attaching the outer sides of any newly created nodes to the
         * sides in the periphery attached to the extraction start and end
         * sides, respectively. The lock must have been obtained on a range,
         * rather than a radius.
         *
         * The alignment must be in the local forward orientation of the graph
         * for this to make sense.
         */
        vector<Translation> apply_full_length_edit(const Path& path);

    protected:

        /// This points back to the synchronizer we synchronize with when we get locked.
        GraphSynchronizer& synchronizer;

        // These hold the actual lock request we represent
        string path_name;

        // These can be set
        size_t path_offset;
        size_t context_bases;
        bool reflect; // Should we bounce off node ends?

        // Or these can be set
        size_t start;
        size_t past_end;

        /// This is the subgraph that got extracted during the locking procedure.
        VG subgraph;

        /// These are the endpoints that the subgraph was extracted between, if
        /// applicable.
        pair<NodeSide, NodeSide> endpoints;

        /// These are the nodes connected to the subgraph but not actually
        /// available for editing. We just need no one else to edit them.
        set<id_t> periphery;

        /// This connects internal NodeSides to NodeSides of nodes on the
        /// periphery.
        map<NodeSide, set<NodeSide>> peripheral_attachments;

        /// This is the set of nodes that this lock has currently locked.
        set<id_t> locked_nodes;
    };

protected:

    /// The graph we manage
    VG& graph;

    /// We use this to lock the whole graph, for when we're exploring and trying
    /// to lock a context, or for when we're making an edit, or for when we're
    /// trying to lock a context, or for when we're working with the
    /// PathIndexes. It's only ever held during functions in this class or
    /// internal classes (monitor-style), so we don't need it to be a recursive
    /// mutex.
    mutex whole_graph_lock;

    /// We have one condition variable where we have blocked all the threads
    /// that are waiting to lock subgraphs but couldn't the first time because
    /// we ran into already locked nodes. When nodes get unlocked, we wake them
    /// all up, and they each grab the mutex and check, one at a time, to see if
    /// they can have all their nodes this time.
    condition_variable wait_for_region;

    /// We need indexes of all the paths that someone might want to use as a
    /// basis for locking. This holds a PathIndex for each path we touch by path
    /// name.
    map<string, PathIndex> indexes;

    /**
     * Get the index for the given path name. Lock on the indexes and graph must
     * be held already.
     */
    PathIndex& get_path_index(const string& path_name);

    /**
     * Update all the path indexes according to the given translations. Lock on
     * the indexes and graph must be held already.
     */
    void update_path_indexes(const vector<Translation>& translations);

    /// This holds all the node IDs that are currently locked by someone
    set<id_t> locked_nodes;

};

}

#endif
<commit_msg>Zero-initialize unused GraphSynchronizer Lock fields<commit_after>#ifndef VG_GRAPH_SYNCHRONIZER_H
#define VG_GRAPH_SYNCHRONIZER_H

/**
 * \file graph_synchronizer.hpp: define a GraphSynchronizer that can manage
 * concurrent access and updates to a VG graph.
 */

#include "vg.hpp"
#include "path_index.hpp"

#include <thread>
#include <mutex>
#include <condition_variable>

namespace vg {

using namespace std;

/**
 * Let threads get exclusive locks on subgraphs of a vg graph, for reading and
 * editing. Whan a subgraph is locked, a copy is accessible through the lock
 * object and the underlying graph can be edited (through the lock) without
 * affecting any other locked subgraphs.
 *
 * A thread may only hold a lock on a single subgraph at a time. Trying to lock
 * another subgraph while you already have a subgraph locked is likely to result
 * in a deadlock.
 */
class GraphSynchronizer {

public:

    /**
     * Create a GraphSynchronizer for synchronizing on parts of the given graph.
     */
    GraphSynchronizer(VG& graph);

    /**
     * Since internally we keep PathIndexes for paths in the graph, we expose
     * this method for getting the strings for paths.
     */
    const string& get_path_sequence(const string& path_name);

    /**
     * We can actually let users run whatever function they want with an
     * exclusive handle on a PathIndex, with the guarantee that the graph won't
     * change while they're working.
     */
    void with_path_index(const string& path_name, const function<void(const PathIndex&)>& to_run);

    /**
     * This represents a request to lock a particular context on a particular
     * GraphSynchronizer. It fulfils the BasicLockable concept requirements, so
     * you can wait on it with std::unique_lock.
     */
    class Lock {
    public:

        /**
         * Create a request to lock a certain radius around a certain position
         * along a certain path in the graph controlled by the given
         * synchronizer.
         */
        Lock(GraphSynchronizer& synchronizer, const string& path_name, size_t path_offset, size_t context_bases, bool reflect);

        /**
         * Create a request to lock a certain range of a certain path, from
         * start to end. The start and end positions must line up with the
         * boundaries of nodes in the graph. Also locks attached things that can
         * be reached by paths of the same length or shorter. Note that the
         * range must be nonempty.
         */
        Lock(GraphSynchronizer& synchronizer, const string& path_name, size_t start, size_t past_end);

        /**
         * Block until a lock is obtained.
         */
        void lock();

        /**
         * If a lock is held, unlock it.
         */
        void unlock();

        /**
         * May only be called when locked. Grab the subgraph that was extracted
         * when the lock was obtained. Does not contain any path information.
         */
        VG& get_subgraph();

        /**
         * May only be called when locked. Returns the pair of NodeSides
         * corresponding to the start and end positions used when the lock was
         * created.
         *
         * May only be called on locks that lock a start to end range.
         */
        pair<NodeSide, NodeSide> get_endpoints() const;

        /**
         * Get the NodeSides for nodes not in the extracted subgraph but in its
         * periphery that are attached to the given NodeSide in the subgraph.
         */
        set<NodeSide> get_peripheral_attachments(NodeSide graph_side);

        /**
         * May only be called when locked. Apply an edit against the base graph
         * and return the resulting translation. Note that this updates only the
         * underlying VG graph, not the copy of the locked subgraph stored in
         * the lock. Also note that the edit may only edit locked nodes.
         *
         * Edit operations will create new nodes, and cannot delete nodes or
         * apply changes (other than dividing and connecting) to existing nodes.
         *
         * Any new nodes created are created already locked.
         *
         * Any new nodes created on the left of the alignment (and any existing
         * nodes visited) will be attached to the given "dangling" NodeSides.
         * The set will be populated with the NodeSides for the ends of nodes
         * created/visited at the end of the alignment.
         */
        vector<Translation> apply_edit(const Path& path, set<NodeSide>& dangling);

        /**
         * May only be called when locked. Apply a path as an edit to the base
         * graph, leaving new nodes at the ends of the path unattached on their
         * outer sides.
         */
        vector<Translation> apply_edit(const Path& path);

        /**
         * May only be called when locked. Apply a path as an edit to the base
         * graph, attaching the outer sides of any newly created nodes to the
         * sides in the periphery attached to the extraction start and end
         * sides, respectively. The lock must have been obtained on a range,
         * rather than a radius.
         *
         * The alignment must be in the local forward orientation of the graph
         * for this to make sense.
         */
        vector<Translation> apply_full_length_edit(const Path& path);

    protected:

        /// This points back to the synchronizer we synchronize with when we get locked.
        GraphSynchronizer& synchronizer;

        // These hold the actual lock request we represent
        string path_name;

        // These can be set
        size_t path_offset = 0;
        size_t context_bases = 0;
        bool reflect = false; // Should we bounce off node ends?

        // Or these can be set
        size_t start = 0;
        size_t past_end = 0;

        /// This is the subgraph that got extracted during the locking procedure.
        VG subgraph;

        /// These are the endpoints that the subgraph was extracted between, if
        /// applicable.
        pair<NodeSide, NodeSide> endpoints;

        /// These are the nodes connected to the subgraph but not actually
        /// available for editing. We just need no one else to edit them.
        set<id_t> periphery;

        /// This connects internal NodeSides to NodeSides of nodes on the
        /// periphery.
        map<NodeSide, set<NodeSide>> peripheral_attachments;

        /// This is the set of nodes that this lock has currently locked.
        set<id_t> locked_nodes;
    };

protected:

    /// The graph we manage
    VG& graph;

    /// We use this to lock the whole graph, for when we're exploring and trying
    /// to lock a context, or for when we're making an edit, or for when we're
    /// trying to lock a context, or for when we're working with the
    /// PathIndexes. It's only ever held during functions in this class or
    /// internal classes (monitor-style), so we don't need it to be a recursive
    /// mutex.
    mutex whole_graph_lock;

    /// We have one condition variable where we have blocked all the threads
    /// that are waiting to lock subgraphs but couldn't the first time because
    /// we ran into already locked nodes. When nodes get unlocked, we wake them
    /// all up, and they each grab the mutex and check, one at a time, to see if
    /// they can have all their nodes this time.
    condition_variable wait_for_region;

    /// We need indexes of all the paths that someone might want to use as a
    /// basis for locking. This holds a PathIndex for each path we touch by path
    /// name.
    map<string, PathIndex> indexes;

    /**
     * Get the index for the given path name. Lock on the indexes and graph must
     * be held already.
     */
    PathIndex& get_path_index(const string& path_name);

    /**
     * Update all the path indexes according to the given translations. Lock on
     * the indexes and graph must be held already.
     */
    void update_path_indexes(const vector<Translation>& translations);

    /// This holds all the node IDs that are currently locked by someone
    set<id_t> locked_nodes;

};

}

#endif
<|endoftext|>


<commit_before>/** @file gsDofMapper.hpp

    @brief implementation file for the gsDofMapper

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): C. Hofreither, A. Mantzaflaris
**/

#include <gsCore/gsMultiBasis.h>

namespace gismo
{

template<class T>
void gsDofMapper::init( const gsMultiBasis<T> & bases, index_t nComp)
{
    m_curElimId   = -1;
    m_numCpldDofs.assign(nComp+1, 1); m_numCpldDofs.front()=0;
    m_numElimDofs.assign(nComp+1,0);
    m_offset.clear();

    const size_t nPatches = bases.nBases();

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
        m_offset.push_back( m_offset.back() + bases[k-1].size() );

    m_numFreeDofs.assign(1+nComp,m_offset.back() + bases.back().size()); m_numFreeDofs.front()=0;

    m_dofs.resize(nComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

template<class T>
void gsDofMapper::init( std::vector<const gsMultiBasis<T> *> const & bases)
{
    const index_t numComp = bases.size();
    m_curElimId   = -1;
    m_numCpldDofs.assign(numComp+1,1); m_numCpldDofs.front()=0;
    m_offset.clear();

    const size_t nPatches = bases[0]->nBases();

    //Checking if bases are same size in for components.
    std::vector<index_t> offsets(nPatches);
    for (index_t comp = 0; comp < numComp; ++comp)
    {
        for (size_t k = 0; k < nPatches; ++k)
        {
            if (comp != 0)
            {
                GISMO_ASSERT(offsets[k] == bases[comp]->basis(k).size(),
                         "The sizes of the bases are not the same for every component. Dofmapper requries this!");
            }
            offsets[k] =  bases[comp]->basis(k).size();
        }
    }

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
        m_offset.push_back( m_offset.back() + bases[0]->basis(k-1).size() );

    if (nPatches == 1)
    {
        index_t dofsPatches = 0;
        for (index_t comp = 0; comp < numComp; ++comp)
            dofsPatches += bases[comp]->back().size();
        m_numFreeDofs.assign(numComp+1,m_offset.back() + dofsPatches);
	m_numFreeDofs.front()=0;
    }
    //Assuming each component are of same size;
    //i.e. bases[comp]->back().size() are equal for all comp
    else
    {
      m_numFreeDofs.assign(numComp+1, (m_offset.back() + bases[0]->back().size())*nPatches); m_numFreeDofs.front()=0;
    }

    m_numElimDofs.assign(numComp+1,0);
    m_dofs.resize(numComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

template<class T>
void gsDofMapper::init(const gsMultiBasis<T>         &basis,
                       const gsBoundaryConditions<T> &bc, int unk)
{
    init(basis, 1); //one component

    /// \todo move this code to gsMultiBasis::getMapper
    for (typename gsBoundaryConditions<T>::const_iterator
         it = bc.dirichletBegin() ; it != bc.dirichletEnd(); ++it )
    {
        if (unk == -1 || it->unknown() == unk) // special value -1 eliminates all BCs found
        {
            GISMO_ASSERT(it->ps.patch < static_cast<index_t>(m_offset.size()),
                         "Problem: a boundary condition is set on a patch id which does not exist.");

            gsMatrix<index_t> bnd = basis[it->ps.patch].boundary(it->ps.side());
            markBoundary(it->ps.patch, bnd);
        }
    }

    // corners
    for (typename gsBoundaryConditions<T>::const_citerator
         it = bc.cornerBegin() ; it != bc.cornerEnd(); ++it )
    {
        if (unk == -1 || it->unknown == unk)
        {
            GISMO_ASSERT(it->patch < static_cast<index_t>(m_offset.size()),
                         "Problem: a corner boundary condition is set on a patch id which does not exist.");

            eliminateDof(basis[it->patch].functionAtCorner(it->corner), it->patch);
        }
    }
}

template<class T>
void gsDofMapper::initSingle( const gsBasis<T> & basis, index_t nComp)
{
    m_curElimId   = -1;
    m_numFreeDofs.assign(nComp+1,basis.size()); m_numFreeDofs.front()=0;
    m_numCpldDofs.assign(nComp+1,1); m_numCpldDofs.front()=0;
    m_numElimDofs.assign(nComp+1,0);
    m_offset.resize(1,0);
    m_dofs.resize(nComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

}//namespace gismo

<commit_msg>bugfix to gsDofMapper (#443)<commit_after>/** @file gsDofMapper.hpp

    @brief implementation file for the gsDofMapper

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): C. Hofreither, A. Mantzaflaris
**/

#include <gsCore/gsMultiBasis.h>

namespace gismo
{

template<class T>
void gsDofMapper::init( const gsMultiBasis<T> & bases, index_t nComp)
{
    m_curElimId   = -1;
    m_numCpldDofs.assign(nComp+1, 1); m_numCpldDofs.front()=0;
    m_numElimDofs.assign(nComp+1,0);
    m_offset.clear();

    const size_t nPatches = bases.nBases();

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
        m_offset.push_back( m_offset.back() + bases[k-1].size() );

    m_numFreeDofs.assign(1+nComp,m_offset.back() + bases.back().size()); m_numFreeDofs.front()=0;

    m_dofs.resize(nComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

template<class T>
void gsDofMapper::init( std::vector<const gsMultiBasis<T> *> const & bases)
{
    const index_t numComp = bases.size();
    m_curElimId   = -1;
    m_numCpldDofs.assign(numComp+1,1); m_numCpldDofs.front()=0;
    m_offset.clear();

    const size_t nPatches = bases[0]->nBases();

    //Checking if bases are same size in for components.
    std::vector<index_t> offsets(nPatches);
    for (index_t comp = 0; comp < numComp; ++comp)
    {
        for (size_t k = 0; k < nPatches; ++k)
        {
            if (comp != 0)
            {
                GISMO_ASSERT(offsets[k] == bases[comp]->basis(k).size(),
                         "The sizes of the bases are not the same for every component. Dofmapper requries this!");
            }
            offsets[k] =  bases[comp]->basis(k).size();
        }
    }

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
        m_offset.push_back( m_offset.back() + bases[0]->basis(k-1).size() );

    if (nPatches == 1)
    {
        index_t dofsPatches = 0;
        for (index_t comp = 0; comp < numComp; ++comp)
            dofsPatches += bases[comp]->back().size();
        m_numFreeDofs.assign(numComp+1,m_offset.back() + dofsPatches);
	m_numFreeDofs.front()=0;
    }
    //Assuming each component are of same size;
    //i.e. bases[comp]->back().size() are equal for all comp
    else
    {
      m_numFreeDofs.assign(numComp+1, (m_offset.back() + bases[0]->back().size())); m_numFreeDofs.front()=0;
    }

    m_numElimDofs.assign(numComp+1,0);
    m_dofs.resize(numComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

template<class T>
void gsDofMapper::init(const gsMultiBasis<T>         &basis,
                       const gsBoundaryConditions<T> &bc, int unk)
{
    init(basis, 1); //one component

    /// \todo move this code to gsMultiBasis::getMapper
    for (typename gsBoundaryConditions<T>::const_iterator
         it = bc.dirichletBegin() ; it != bc.dirichletEnd(); ++it )
    {
        if (unk == -1 || it->unknown() == unk) // special value -1 eliminates all BCs found
        {
            GISMO_ASSERT(it->ps.patch < static_cast<index_t>(m_offset.size()),
                         "Problem: a boundary condition is set on a patch id which does not exist.");

            gsMatrix<index_t> bnd = basis[it->ps.patch].boundary(it->ps.side());
            markBoundary(it->ps.patch, bnd);
        }
    }

    // corners
    for (typename gsBoundaryConditions<T>::const_citerator
         it = bc.cornerBegin() ; it != bc.cornerEnd(); ++it )
    {
        if (unk == -1 || it->unknown == unk)
        {
            GISMO_ASSERT(it->patch < static_cast<index_t>(m_offset.size()),
                         "Problem: a corner boundary condition is set on a patch id which does not exist.");

            eliminateDof(basis[it->patch].functionAtCorner(it->corner), it->patch);
        }
    }
}

template<class T>
void gsDofMapper::initSingle( const gsBasis<T> & basis, index_t nComp)
{
    m_curElimId   = -1;
    m_numFreeDofs.assign(nComp+1,basis.size()); m_numFreeDofs.front()=0;
    m_numCpldDofs.assign(nComp+1,1); m_numCpldDofs.front()=0;
    m_numElimDofs.assign(nComp+1,0);
    m_offset.resize(1,0);
    m_dofs.resize(nComp, std::vector<index_t>(m_numFreeDofs.back(), 0));
}

}//namespace gismo

<|endoftext|>


<commit_before>/*
 * SchemeSmob.c
 *
 * Scheme small objects (SMOBS) for opencog atoms and truth values.
 *
 * Copyright (c) 2008 Linas Vepstas <linas@linas.org>
 */

#ifdef HAVE_GUILE

#include <libguile.h>
#include <vector>

#include "Atom.h"
#include "ClassServer.h"
#include "CogServer.h"
#include "Link.h"
#include "Node.h"
#include "SchemeSmob.h"
#include "TLB.h"

using namespace opencog;

/* ============================================================== */
/**
 * return atom->toString() for the corresponding atom.
 */
std::string SchemeSmob::to_string(SCM node)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, node))
		return handle_to_string(node);

	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_misc_tag, node))
		return misc_to_string(node);

	return "";
}

std::string SchemeSmob::handle_to_string(Handle h, int indent)
{
	if (UNDEFINED_HANDLE == h) return "#<Undefined atom handle>";

	if (h <= NOTYPE) return "#<non-real atom>";

	Atom *atom = TLB::getAtom(h);
	if (NULL == atom) return "#<Invalid handle>";
	Node *node = dynamic_cast<Node *>(atom);
	Link *link = dynamic_cast<Link *>(atom);

#ifdef CRYPTIC_STYLE
	// output the olde-style opencog notation
	std::string ret = "#<";
	ret += atom->toString();
	ret += ">\n";
#endif

	// Print a scheme expression, so that the output can be saved
	// to file, and then restored, as needed.
	std::string ret = "";
	for (int i=0; i< indent; i++) ret += "   ";
	ret += "(";
	ret += ClassServer::getTypeName(atom->getType());
	if (node)
	{
		ret += " \"";
		ret += node->getName();
		ret += "\"";

		// Print the truth value only after the node name
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}
		ret += ")";
		return ret;
	}
	else if (link)
	{
		// If there's a truth value, print it before the other atoms
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}

		// print the outgoing link set.
		std::vector<Handle> oset = link->getOutgoingSet();
		unsigned int arity = oset.size();
		for (unsigned int i=0; i<arity; i++)
		{
			ret += " ";
			ret += handle_to_string(oset[i], (0==i)?0:indent+1);
			if (i != arity-1) ret += "\n";
		}
		ret += ")";
		return ret;
	}

	return ret;
}

std::string SchemeSmob::handle_to_string(SCM node)
{
	SCM shandle = SCM_SMOB_OBJECT(node);
	Handle h = scm_to_ulong(shandle);

	return handle_to_string(h, 0) + "\n";
}

/* ============================================================== */
/**
 * Create a new scheme object, holding the atom handle
 */
SCM SchemeSmob::ss_atom (SCM shandle)
{
	if (scm_is_false(scm_integer_p(shandle)))
		scm_wrong_type_arg_msg("cog-atom", 1, shandle, "integer opencog handle");
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Return handle of atom (the handle is in integer)
 */
SCM SchemeSmob::ss_handle (SCM satom)
{
	if (!SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		scm_wrong_type_arg_msg("cog-handle", 1, satom, "opencog atom");
	return SCM_SMOB_OBJECT(satom);
}

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

SCM SchemeSmob::ss_atom_p (SCM s)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, s))
		return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * Check that the arguments represent a value node, else throw errors.
 * Return the node type.
 */
Type SchemeSmob::validate_atom (SCM stype, const char *subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	char * ct = scm_to_locale_string(stype);
	Type t = ClassServer::getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	return t;
}

Type SchemeSmob::validate_node (SCM stype, const char *subrname)
{
	Type t = validate_atom(stype, subrname);

	if (false == ClassServer::isAssignableFrom(NODE, t))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog node type");

	return t;
}

static std::string decode_string (SCM sname, const char *subrname)
{
	if (scm_is_false(scm_string_p(sname)))
		scm_wrong_type_arg_msg(subrname, 2, sname, "string name for the node");

	char * cname = scm_to_locale_string(sname);
	std::string name = cname;
	free(cname);
	return name;
}

/**
 * Create a new node, of named type stype, and string name sname
 */
SCM SchemeSmob::ss_new_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-new-node");
	std::string name = decode_string (sname, "cog-new-node");

	// Now, create the actual node... in the actual atom space.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addNode(t, name, *tv);

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/**
 * Return the indicated node, of named type stype, and string name sname
 * if it exists; else return nil if it does not exist.
 * If the node exists, *and* a truth value was specified, then change
 * the truth value.
 */
SCM SchemeSmob::ss_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-node");
	std::string name = decode_string (sname, "cog-node");

	// Now, look for the actual node... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, name);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Verify that the arguments are appropriate for a link
 */
static Type verify_link (SCM stype, const char * subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	char * ct = scm_to_locale_string(stype);
	Type t = ClassServer::getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	if (false == ClassServer::isAssignableFrom(LINK, t))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog link type");

	return t;
}

/**
 * Convert argument into a list of handles.
 */
std::vector<Handle>
SchemeSmob::decode_handle_list (SCM satom_list, const char * subrname)
{
	// Verify that second arg is an actual list
	if (!scm_is_pair(satom_list))
		scm_wrong_type_arg_msg(subrname, 2, satom_list, "a list of atoms");

	const TruthValue *tv = NULL;
	std::vector<Handle> outgoing_set;
	SCM sl = satom_list;
	int pos = 2;
	do
	{
		SCM satom = SCM_CAR(sl);

		// Verify that the contents of the list are actual atoms.
		if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		{
			// Get the handle  ... should we check for valid handles here?
			SCM shandle = SCM_SMOB_OBJECT(satom);
			Handle h = scm_to_ulong(shandle);
			outgoing_set.push_back(h);
		}
		else
		{
			// Its legit to have enmbedded truth values, just skip them.
			tv = get_tv_from_list(sl);
			if (tv == NULL)
			{
				// If its not an atom, and its not a truth value, its bad
				scm_wrong_type_arg_msg("cog-new-link", pos, satom, "opencog atom");
			}
		}
		sl = SCM_CDR(sl);
		pos++;
	}
	while (scm_is_pair(sl));

	return outgoing_set;
}

/**
 * Create a new link, of named type stype, holding the indicated atom list
 */
SCM SchemeSmob::ss_new_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-new-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-new-link");

	// Fish out a truth value, if its there.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	// Now, create the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addLink(t, outgoing_set, *tv);

	SCM shandle = scm_from_ulong(h);

	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/**
 * Return the indicated link, of named type stype, holding the
 * indicated atom list, if it exists; else return nil if
 * it does not exist.
 */
SCM SchemeSmob::ss_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-link");

	// Now, look to find the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, outgoing_set);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * delete the atom, but only if it has no incoming links.
 */
SCM SchemeSmob::ss_delete (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, false);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * delete the atom, and everything pointing to it.
 */
SCM SchemeSmob::ss_delete_recursive (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete-recursive");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, true);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

#endif
/* ===================== END OF FILE ============================ */
<commit_msg>Validate an argument as being a string.<commit_after>/*
 * SchemeSmob.c
 *
 * Scheme small objects (SMOBS) for opencog atoms and truth values.
 *
 * Copyright (c) 2008 Linas Vepstas <linas@linas.org>
 */

#ifdef HAVE_GUILE

#include <libguile.h>
#include <vector>

#include "Atom.h"
#include "ClassServer.h"
#include "CogServer.h"
#include "Link.h"
#include "Node.h"
#include "SchemeSmob.h"
#include "TLB.h"

using namespace opencog;

/* ============================================================== */
/**
 * return atom->toString() for the corresponding atom.
 */
std::string SchemeSmob::to_string(SCM node)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, node))
		return handle_to_string(node);

	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_misc_tag, node))
		return misc_to_string(node);

	return "";
}

std::string SchemeSmob::handle_to_string(Handle h, int indent)
{
	if (UNDEFINED_HANDLE == h) return "#<Undefined atom handle>";

	if (h <= NOTYPE) return "#<non-real atom>";

	Atom *atom = TLB::getAtom(h);
	if (NULL == atom) return "#<Invalid handle>";
	Node *node = dynamic_cast<Node *>(atom);
	Link *link = dynamic_cast<Link *>(atom);

#ifdef CRYPTIC_STYLE
	// output the olde-style opencog notation
	std::string ret = "#<";
	ret += atom->toString();
	ret += ">\n";
#endif

	// Print a scheme expression, so that the output can be saved
	// to file, and then restored, as needed.
	std::string ret = "";
	for (int i=0; i< indent; i++) ret += "   ";
	ret += "(";
	ret += ClassServer::getTypeName(atom->getType());
	if (node)
	{
		ret += " \"";
		ret += node->getName();
		ret += "\"";

		// Print the truth value only after the node name
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}
		ret += ")";
		return ret;
	}
	else if (link)
	{
		// If there's a truth value, print it before the other atoms
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}

		// print the outgoing link set.
		std::vector<Handle> oset = link->getOutgoingSet();
		unsigned int arity = oset.size();
		for (unsigned int i=0; i<arity; i++)
		{
			ret += " ";
			ret += handle_to_string(oset[i], (0==i)?0:indent+1);
			if (i != arity-1) ret += "\n";
		}
		ret += ")";
		return ret;
	}

	return ret;
}

std::string SchemeSmob::handle_to_string(SCM node)
{
	SCM shandle = SCM_SMOB_OBJECT(node);
	Handle h = scm_to_ulong(shandle);

	return handle_to_string(h, 0) + "\n";
}

/* ============================================================== */
/**
 * Create a new scheme object, holding the atom handle
 */
SCM SchemeSmob::ss_atom (SCM shandle)
{
	if (scm_is_false(scm_integer_p(shandle)))
		scm_wrong_type_arg_msg("cog-atom", 1, shandle, "integer opencog handle");
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Return handle of atom (the handle is in integer)
 */
SCM SchemeSmob::ss_handle (SCM satom)
{
	if (!SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		scm_wrong_type_arg_msg("cog-handle", 1, satom, "opencog atom");
	return SCM_SMOB_OBJECT(satom);
}

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

SCM SchemeSmob::ss_atom_p (SCM s)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, s))
		return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * Check that the arguments represent a value node, else throw errors.
 * Return the node type.
 */
Type SchemeSmob::validate_atom (SCM stype, const char *subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	if (scm_is_false(scm_symbol_p(stype)))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	char * ct = scm_to_locale_string(stype);
	Type t = ClassServer::getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	return t;
}

Type SchemeSmob::validate_node (SCM stype, const char *subrname)
{
	Type t = validate_atom(stype, subrname);

	if (false == ClassServer::isAssignableFrom(NODE, t))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog node type");

	return t;
}

static std::string decode_string (SCM sname, const char *subrname)
{
	if (scm_is_false(scm_string_p(sname)))
		scm_wrong_type_arg_msg(subrname, 2, sname, "string name for the node");

	char * cname = scm_to_locale_string(sname);
	std::string name = cname;
	free(cname);
	return name;
}

/**
 * Create a new node, of named type stype, and string name sname
 */
SCM SchemeSmob::ss_new_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-new-node");
	std::string name = decode_string (sname, "cog-new-node");

	// Now, create the actual node... in the actual atom space.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addNode(t, name, *tv);

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/**
 * Return the indicated node, of named type stype, and string name sname
 * if it exists; else return nil if it does not exist.
 * If the node exists, *and* a truth value was specified, then change
 * the truth value.
 */
SCM SchemeSmob::ss_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-node");
	std::string name = decode_string (sname, "cog-node");

	// Now, look for the actual node... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, name);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Verify that the arguments are appropriate for a link
 */
static Type verify_link (SCM stype, const char * subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	char * ct = scm_to_locale_string(stype);
	Type t = ClassServer::getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	if (false == ClassServer::isAssignableFrom(LINK, t))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog link type");

	return t;
}

/**
 * Convert argument into a list of handles.
 */
std::vector<Handle>
SchemeSmob::decode_handle_list (SCM satom_list, const char * subrname)
{
	// Verify that second arg is an actual list
	if (!scm_is_pair(satom_list))
		scm_wrong_type_arg_msg(subrname, 2, satom_list, "a list of atoms");

	const TruthValue *tv = NULL;
	std::vector<Handle> outgoing_set;
	SCM sl = satom_list;
	int pos = 2;
	do
	{
		SCM satom = SCM_CAR(sl);

		// Verify that the contents of the list are actual atoms.
		if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		{
			// Get the handle  ... should we check for valid handles here?
			SCM shandle = SCM_SMOB_OBJECT(satom);
			Handle h = scm_to_ulong(shandle);
			outgoing_set.push_back(h);
		}
		else
		{
			// Its legit to have enmbedded truth values, just skip them.
			tv = get_tv_from_list(sl);
			if (tv == NULL)
			{
				// If its not an atom, and its not a truth value, its bad
				scm_wrong_type_arg_msg("cog-new-link", pos, satom, "opencog atom");
			}
		}
		sl = SCM_CDR(sl);
		pos++;
	}
	while (scm_is_pair(sl));

	return outgoing_set;
}

/**
 * Create a new link, of named type stype, holding the indicated atom list
 */
SCM SchemeSmob::ss_new_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-new-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-new-link");

	// Fish out a truth value, if its there.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	// Now, create the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addLink(t, outgoing_set, *tv);

	SCM shandle = scm_from_ulong(h);

	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/**
 * Return the indicated link, of named type stype, holding the
 * indicated atom list, if it exists; else return nil if
 * it does not exist.
 */
SCM SchemeSmob::ss_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-link");

	// Now, look to find the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, outgoing_set);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}

	SCM shandle = scm_from_ulong(h);
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * delete the atom, but only if it has no incoming links.
 */
SCM SchemeSmob::ss_delete (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, false);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * delete the atom, and everything pointing to it.
 */
SCM SchemeSmob::ss_delete_recursive (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete-recursive");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, true);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

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


<commit_before>#include "Util/Log.hpp"
#include "MainWindow.hpp"
#include "Manager/Managers.hpp"
#include "Manager/RenderManager.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>

MainWindow* MainWindow::instance = nullptr;
void WindowSizeCallback(GLFWwindow* window, int width, int height);

MainWindow::MainWindow(int width, int height, bool fullscreen, bool borderless, const char* title, bool debugContext) {

    if (borderless)
        glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);

    this->debugContext = debugContext;
    if (debugContext)
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);

    GLFWmonitor* monitor = fullscreen ? glfwGetPrimaryMonitor() : nullptr;

    window = glfwCreateWindow(width, height, title, monitor, nullptr);

    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    // Setup error callbacks.
    glfwSetErrorCallback(ErrorCallback);

    input = new InputHandler(window);
    input->Update();
    input->SetActive();

    size = glm::vec2(width, height);
    instance = this;

    glfwSetWindowSizeCallback(window, WindowSizeCallback);

}

MainWindow::~MainWindow() {
    glfwDestroyWindow(window);
    delete input;
}

MainWindow* MainWindow::GetInstance() {
    return instance;
}

void MainWindow::Init(bool showNotifications) {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_PROGRAM_POINT_SIZE);

    if (debugContext)
        glDebugMessageCallback(showNotifications ? DebugMessageCallback : DebugMessageCallbackIgnoreNotifications, nullptr);
}

void MainWindow::SetVsync(bool vsync) {
    glfwSwapInterval(vsync ? 1 : 0);
}

void MainWindow::Update() {
    input->Update();
    input->SetActive();

    if (glfwWindowShouldClose(window) != GLFW_FALSE)
        shouldClose = true;
}

const glm::vec2& MainWindow::GetSize() const {
    return size;
}

void MainWindow::SetSize(int width, int height){
    size.x = width;
    size.y = height;
}

void MainWindow::SetTitle(const char *title) {
    glfwSetWindowTitle(window, title);
}

bool MainWindow::ShouldClose() const {
    return shouldClose;
}

void MainWindow::Close() {
    shouldClose = true;
}

void MainWindow::SwapBuffers() {
    glfwSwapBuffers(window);
}

GLFWwindow* MainWindow::GetGLFWWindow() const {
    return window;
}

void WindowSizeCallback(GLFWwindow* window, int width, int height)
{

    MainWindow::GetInstance()->SetSize(width, height);
    Managers().renderManager->UpdateBufferSize();

}
<commit_msg>Fix int to float conversion<commit_after>#include "Util/Log.hpp"
#include "MainWindow.hpp"
#include "Manager/Managers.hpp"
#include "Manager/RenderManager.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>

MainWindow* MainWindow::instance = nullptr;
void WindowSizeCallback(GLFWwindow* window, int width, int height);

MainWindow::MainWindow(int width, int height, bool fullscreen, bool borderless, const char* title, bool debugContext) {

    if (borderless)
        glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);

    this->debugContext = debugContext;
    if (debugContext)
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);

    GLFWmonitor* monitor = fullscreen ? glfwGetPrimaryMonitor() : nullptr;

    window = glfwCreateWindow(width, height, title, monitor, nullptr);

    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    // Setup error callbacks.
    glfwSetErrorCallback(ErrorCallback);

    input = new InputHandler(window);
    input->Update();
    input->SetActive();

    size = glm::vec2(width, height);
    instance = this;

    glfwSetWindowSizeCallback(window, WindowSizeCallback);

}

MainWindow::~MainWindow() {
    glfwDestroyWindow(window);
    delete input;
}

MainWindow* MainWindow::GetInstance() {
    return instance;
}

void MainWindow::Init(bool showNotifications) {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_PROGRAM_POINT_SIZE);

    if (debugContext)
        glDebugMessageCallback(showNotifications ? DebugMessageCallback : DebugMessageCallbackIgnoreNotifications, nullptr);
}

void MainWindow::SetVsync(bool vsync) {
    glfwSwapInterval(vsync ? 1 : 0);
}

void MainWindow::Update() {
    input->Update();
    input->SetActive();

    if (glfwWindowShouldClose(window) != GLFW_FALSE)
        shouldClose = true;
}

const glm::vec2& MainWindow::GetSize() const {
    return size;
}

void MainWindow::SetSize(int width, int height){
    size.x = static_cast<float>(width);
    size.y = static_cast<float>(height);
}

void MainWindow::SetTitle(const char *title) {
    glfwSetWindowTitle(window, title);
}

bool MainWindow::ShouldClose() const {
    return shouldClose;
}

void MainWindow::Close() {
    shouldClose = true;
}

void MainWindow::SwapBuffers() {
    glfwSwapBuffers(window);
}

GLFWwindow* MainWindow::GetGLFWWindow() const {
    return window;
}

void WindowSizeCallback(GLFWwindow* window, int width, int height) {
    MainWindow::GetInstance()->SetSize(width, height);
    Managers().renderManager->UpdateBufferSize();
}
<|endoftext|>


<commit_before>// $Id$

#include <TClonesArray.h>
#include <TString.h>

#include "AliVCluster.h"
#include "AliVTrack.h"
#include "AliPicoTrack.h"
#include "AliLog.h"

#include "AliEmcalClusTrackMatcherTask.h"

ClassImp(AliEmcalClusTrackMatcherTask)

//________________________________________________________________________
AliEmcalClusTrackMatcherTask::AliEmcalClusTrackMatcherTask(const char *name) :
  AliAnalysisTaskSE("AliEmcalClusTrackMatcherTask"),
  fTracksName("Tracks"),
  fCaloName("CaloClusters"),
  fDoClusTrack(1),
  fDoTrackClus(0)
{
  // Standard constructor.

  if (!name)
    return;
  SetName(name);
  fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.,CaloClusters,Tracks";
}

//________________________________________________________________________
AliEmcalClusTrackMatcherTask::~AliEmcalClusTrackMatcherTask()
{
  // Destructor
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::UserCreateOutputObjects()
{
  // Create user objects.
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::UserExec(Option_t *)
{
  // Main loop, called for each event.

  TList *l = InputEvent()->GetList();
  if (!l)
    return;

  TClonesArray *tracks = dynamic_cast<TClonesArray*>(l->FindObject(fTracksName));
  if (!tracks) {
    AliError(Form("Pointer to tracks %s == 0", fTracksName.Data() ));
    return;
  }

  TClonesArray *clus = dynamic_cast<TClonesArray*>(l->FindObject(fCaloName));
  if (!clus) {
    AliError(Form("Pointer to clus %s == 0", fCaloName.Data() ));
    return;
  }

  const Int_t Ntrks = tracks->GetEntries();
  const Int_t Ncls  = clus->GetEntries();

  if (fDoClusTrack) {
    for(Int_t i=0; i < Ncls; ++i) {
      AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
      if (!c)
        continue;
      c->SetEmcCpvDistance(-1);
      c->SetTrackDistance(999,999);
      Double_t dEtaMin  = 1e9;
      Double_t dPhiMin  = 1e9;
      Int_t    imin     = -1;
      for(Int_t t = 0; t<Ntrks; ++t) {
        AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
        Double_t etadiff=999;
        Double_t phidiff=999;
        AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
        Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
        if(dR > 25)
          continue;
        if (TMath::Abs(etadiff)<TMath::Abs(dEtaMin) && TMath::Abs(phidiff)<TMath::Abs(dPhiMin)) {
          dEtaMin = etadiff;
          dPhiMin = phidiff;
          imin = t;
        }
      }
      c->SetEmcCpvDistance(imin);
      c->SetTrackDistance(dPhiMin, dEtaMin);
    }
  }

  if (fDoTrackClus) {
    for(Int_t t = 0; t<Ntrks; ++t) {
      AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
      if (!track)
        continue;
      Double_t dEtaMin  = 1e9;
      Double_t dPhiMin  = 1e9;
      Int_t    imin     = -1;
      for(Int_t i=0; i < Ncls; ++i) {
        AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
        if (!c)
          continue;
        Double_t etadiff=999;
        Double_t phidiff=999;
        AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
        Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
        if(dR > 25)
          continue;
        if (TMath::Abs(etadiff)<TMath::Abs(dEtaMin) && TMath::Abs(phidiff)<TMath::Abs(dPhiMin)) {
          dEtaMin = etadiff;
          dPhiMin = phidiff;
          imin = i;
        }
      }
      track->SetEMCALcluster(imin);
    }
  }
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::Terminate(Option_t *)
{
  // Called once at the end of the analysis.

}
<commit_msg>check if track is on emcal surface for tm. Speeds up the computation.<commit_after>// $Id$

#include <TClonesArray.h>
#include <TString.h>

#include "AliVCluster.h"
#include "AliVTrack.h"
#include "AliPicoTrack.h"
#include "AliLog.h"

#include "AliEmcalClusTrackMatcherTask.h"

ClassImp(AliEmcalClusTrackMatcherTask)

//________________________________________________________________________
AliEmcalClusTrackMatcherTask::AliEmcalClusTrackMatcherTask(const char *name) :
  AliAnalysisTaskSE("AliEmcalClusTrackMatcherTask"),
  fTracksName("Tracks"),
  fCaloName("CaloClusters"),
  fDoClusTrack(1),
  fDoTrackClus(0)
{
  // Standard constructor.

  if (!name)
    return;
  SetName(name);
  fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.,CaloClusters,Tracks";
}

//________________________________________________________________________
AliEmcalClusTrackMatcherTask::~AliEmcalClusTrackMatcherTask()
{
  // Destructor.
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::UserCreateOutputObjects()
{
  // Create user objects.
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::UserExec(Option_t *)
{
  // Main loop, called for each event.

  TList *l = InputEvent()->GetList();
  if (!l)
    return;

  TClonesArray *tracks = dynamic_cast<TClonesArray*>(l->FindObject(fTracksName));
  if (!tracks) {
    AliError(Form("Pointer to tracks %s == 0", fTracksName.Data() ));
    return;
  }

  TClonesArray *clus = dynamic_cast<TClonesArray*>(l->FindObject(fCaloName));
  if (!clus) {
    AliError(Form("Pointer to clus %s == 0", fCaloName.Data() ));
    return;
  }

  const Int_t Ntrks = tracks->GetEntries();
  const Int_t Ncls  = clus->GetEntries();

  if (fDoClusTrack) {
    for(Int_t i=0; i < Ncls; ++i) {
      AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
      if (!c)
        continue;
      c->SetEmcCpvDistance(-1);
      c->SetTrackDistance(999,999);
      Double_t dEtaMin  = 1e9;
      Double_t dPhiMin  = 1e9;
      Int_t    imin     = -1;
      for(Int_t t = 0; t<Ntrks; ++t) {
        AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
      if (!track)
        continue;
      if (!track->IsEMCAL())
          continue;
        Double_t etadiff=999;
        Double_t phidiff=999;
        AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
        Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
        if(dR > 25)
          continue;
        if (TMath::Abs(etadiff)<TMath::Abs(dEtaMin) && TMath::Abs(phidiff)<TMath::Abs(dPhiMin)) {
          dEtaMin = etadiff;
          dPhiMin = phidiff;
          imin = t;
        }
      }
      c->SetEmcCpvDistance(imin);
      c->SetTrackDistance(dPhiMin, dEtaMin);
    }
  }

  if (fDoTrackClus) {
    for(Int_t t = 0; t<Ntrks; ++t) {
      AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
      if (!track)
        continue;
      if (!track->IsEMCAL())
        continue;
      Double_t dEtaMin  = 1e9;
      Double_t dPhiMin  = 1e9;
      Int_t    imin     = -1;
      for(Int_t i=0; i < Ncls; ++i) {
        AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
        if (!c)
          continue;
        Double_t etadiff=999;
        Double_t phidiff=999;
        AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
        Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
        if(dR > 25)
          continue;
        if (TMath::Abs(etadiff)<TMath::Abs(dEtaMin) && TMath::Abs(phidiff)<TMath::Abs(dPhiMin)) {
          dEtaMin = etadiff;
          dPhiMin = phidiff;
          imin = i;
        }
      }
      track->SetEMCALcluster(imin);
    }
  }
}

//________________________________________________________________________
void AliEmcalClusTrackMatcherTask::Terminate(Option_t *)
{
  // Called once at the end of the analysis.
}
<|endoftext|>


<commit_before>// File:	BlockFix.cxx
// Created:	Tue Dec  7 11:59:05 2004
// Author:	Pavel DURANDIN
// Copyright:	Open CASCADE SA 2004

#include <BlockFix.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <ShapeCustom.hxx>
#include <BRepTools.hxx>
#include <ShapeBuild_ReShape.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopLoc_Location.hxx>
#include <Geom_Surface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <ShapeFix_Wire.hxx>
#include <TopoDS_Wire.hxx>
#include <BRepTools_Modifier.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Edge.hxx>
#include <Geom2d_Curve.hxx>
#include <BRep_Builder.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeFix_Edge.hxx>
#include <ShapeFix.hxx>
#include <ShapeFix_Face.hxx>
#include <ShapeAnalysis.hxx>

#include <TColgp_SequenceOfPnt2d.hxx>
#include <ShapeAnalysis_Curve.hxx>
#include <TopoDS_Vertex.hxx>
#include <ShapeBuild_Edge.hxx>

#include <BlockFix_SphereSpaceModifier.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BlockFix_PeriodicSurfaceModifier.hxx>

#include <TopoDS_Solid.hxx>

//=======================================================================
//function : FixResult
//purpose  : auxilary
//=======================================================================
static void FixResult(const TopoDS_Shape& result,
                      Handle(ShapeBuild_ReShape)& Context,
                      const Standard_Real Tol)
{
  for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
    TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
    // face coud not be dropped or splitted on this step
    TopoDS_Face aFace = TopoDS::Face(aShape);
    TopLoc_Location L;
    Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);

    if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
        Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {

      Standard_Integer nbWires = 0;
      for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
        nbWires++;
        Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()),
                                                      aFace,
                                                      Precision::Confusion());
        sfw->FixReorder();
        if(sfw->StatusReorder ( ShapeExtend_FAIL ))
          continue;

        sfw->SetPrecision(2.*Tol);
        sfw->FixShifted();

        Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
        isDone |= sfw->FixDegenerated();

        // remove degenerated edges from not degenerated points
        ShapeAnalysis_Edge sae;
        Handle(ShapeExtend_WireData) sewd = sfw->WireData();
        Standard_Integer i;
        for( i = 1; i<=sewd->NbEdges();i++) {
          TopoDS_Edge E = sewd->Edge(i);
          if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
            sewd->Remove(i);
            isDone = Standard_True;
            i--;
          }
        }

        isDone |= sfw->FixLacking();

        // remove neighbour seam edges
        if(isDone) {
          for( i = 1; i<sewd->NbEdges();i++) {
            if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
              isDone = Standard_True;
              sewd->Remove(i);
              sewd->Remove(i);
              i--;
            }
          }
          if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
            sewd->Remove(1);
            sewd->Remove(sewd->NbEdges());
          }
        }

        if(isDone) {
          TopoDS_Wire ResWire = sfw->Wire();
          Context->Replace(ex_w.Current(), ResWire);
        };
      }
      // Implement fix orientation in case of several wires
      if(nbWires > 1) {
        TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
        Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
        if(sff->FixOrientation())
          Context->Replace(aFixedFace,sff->Face());
      }

    }
  }
}

//=======================================================================
//function : ConvertToAnalytical
//purpose  :
//=======================================================================

TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
                                          const Standard_Real Tol)
{

  // Create a modification description
  Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
  SR->SetTolerance(Tol);

  TopTools_DataMapOfShapeShape context;
  BRepTools_Modifier MD;
  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );

  Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
  FixResult(result,RS,Tol);
  result = RS->Apply(result);

  ShapeFix_Edge sfe;
  for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
    TopoDS_Edge E = TopoDS::Edge(exp.Current());
    sfe.FixVertexTolerance (E);
  }

  ShapeFix::SameParameter(result,Standard_False);
  return result;
}

//=======================================================================
//function : FixRanges
//purpose  :
//=======================================================================

TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
                                  const Standard_Real Tol)
{
  // Create a modification description
  Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
  SR->SetTolerance(Tol);

  TopTools_DataMapOfShapeShape context;
  BRepTools_Modifier MD;
  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );

  Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
  FixResult(result,RS,Tol);
  result = RS->Apply(result);

  ShapeFix_Edge sfe;
  for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
    TopoDS_Edge E = TopoDS::Edge(exp.Current());
    sfe.FixVertexTolerance (E);
  }

  ShapeFix::SameParameter(result,Standard_False);

  return result;
}
<commit_msg>PAL8395: Fix pb. with bug2extraEdges.py<commit_after>// File:	BlockFix.cxx
// Created:	Tue Dec  7 11:59:05 2004
// Author:	Pavel DURANDIN
// Copyright:	Open CASCADE SA 2004

#include <BlockFix.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <ShapeCustom.hxx>
#include <BRepTools.hxx>
#include <ShapeBuild_ReShape.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopLoc_Location.hxx>
#include <Geom_Surface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <ShapeFix_Wire.hxx>
#include <TopoDS_Wire.hxx>
#include <BRepTools_Modifier.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Edge.hxx>
#include <Geom2d_Curve.hxx>
#include <BRep_Builder.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeFix_Edge.hxx>
#include <ShapeFix.hxx>
#include <ShapeFix_Face.hxx>
#include <ShapeAnalysis.hxx>

#include <TColgp_SequenceOfPnt2d.hxx>
#include <ShapeAnalysis_Curve.hxx>
#include <TopoDS_Vertex.hxx>
#include <ShapeBuild_Edge.hxx>

#include <BlockFix_SphereSpaceModifier.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BlockFix_PeriodicSurfaceModifier.hxx>

#include <TopoDS_Solid.hxx>

//=======================================================================
//function : FixResult
//purpose  : auxilary
//=======================================================================
static void FixResult(const TopoDS_Shape& result,
                      Handle(ShapeBuild_ReShape)& Context,
                      const Standard_Real Tol)
{
  for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
    TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
    // face coud not be dropped or splitted on this step
    TopoDS_Face aFace = TopoDS::Face(aShape);
    TopLoc_Location L;
    Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);

    if( Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
        Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {

      Standard_Integer nbWires = 0;
      for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
        nbWires++;
        Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()),
                                                      aFace,
                                                      Precision::Confusion());
        sfw->FixReorder();
        if(sfw->StatusReorder ( ShapeExtend_FAIL ))
          continue;

        sfw->SetPrecision(2.*Tol);
        sfw->FixShifted();

        Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
        isDone |= sfw->FixDegenerated();

        // remove degenerated edges from not degenerated points
        ShapeAnalysis_Edge sae;
        Handle(ShapeExtend_WireData) sewd = sfw->WireData();
        Standard_Integer i;
        for( i = 1; i<=sewd->NbEdges();i++) {
          TopoDS_Edge E = sewd->Edge(i);
          if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
            sewd->Remove(i);
            isDone = Standard_True;
            i--;
          }
        }

        //isDone |= sfw->FixLacking(); // commented by skl 22.03.2005 (PAL8395)

        // remove neighbour seam edges
        if(isDone) {
          for( i = 1; i<sewd->NbEdges();i++) {
            if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
              isDone = Standard_True;
              sewd->Remove(i);
              sewd->Remove(i);
              i--;
            }
          }
          if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
            sewd->Remove(1);
            sewd->Remove(sewd->NbEdges());
          }
        }

        if(isDone) {
          TopoDS_Wire ResWire = sfw->Wire();
          Context->Replace(ex_w.Current(), ResWire);
        };
      }
      // Implement fix orientation in case of several wires
      if(nbWires > 1) {
        TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
        Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
        if(sff->FixOrientation())
          Context->Replace(aFixedFace,sff->Face());
      }

    }
  }
}

//=======================================================================
//function : ConvertToAnalytical
//purpose  :
//=======================================================================

TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
                                          const Standard_Real Tol)
{

  // Create a modification description
  Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
  SR->SetTolerance(Tol);

  TopTools_DataMapOfShapeShape context;
  BRepTools_Modifier MD;
  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );

  Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
  FixResult(result,RS,Tol);
  result = RS->Apply(result);

  ShapeFix_Edge sfe;
  for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
    TopoDS_Edge E = TopoDS::Edge(exp.Current());
    sfe.FixVertexTolerance (E);
  }

  ShapeFix::SameParameter(result,Standard_False);
  return result;
}

//=======================================================================
//function : FixRanges
//purpose  :
//=======================================================================

TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
                                  const Standard_Real Tol)
{
  // Create a modification description
  Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
  SR->SetTolerance(Tol);

  TopTools_DataMapOfShapeShape context;
  BRepTools_Modifier MD;
  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );

  Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
  FixResult(result,RS,Tol);
  result = RS->Apply(result);

  ShapeFix_Edge sfe;
  for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
    TopoDS_Edge E = TopoDS::Edge(exp.Current());
    sfe.FixVertexTolerance (E);
  }

  ShapeFix::SameParameter(result,Standard_False);

  return result;
}
<|endoftext|>


<commit_before>
#ifndef SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_INL
#define SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_INL

#include <sofa/component/controller/LCPForceFeedback.h>
#include <sofa/simulation/common/AnimateEndEvent.h>
#include <sofa/component/constraintset/LCPConstraintSolver.h>
#include <sofa/component/constraintset/GenericLCPConstraintSolver.h>

#include <sofa/core/objectmodel/BaseContext.h>

#include <algorithm>

namespace
{
template <typename DataTypes>
bool derivVectors(const typename DataTypes::VecCoord& x0, const typename DataTypes::VecCoord& x1, typename DataTypes::VecDeriv& d)
{
    unsigned int sz0 = x0.size();
    unsigned int szmin = std::min(sz0,(unsigned int)x1.size());

    d.resize(sz0);
    for(unsigned int i=0; i<szmin; ++i)
    {
        d[i]=x1[i]-x0[i];
    }
    for(unsigned int i=szmin; i<sz0; ++i)
    {
        d[i]=-x0[i];
    }
    return true;
}

template <typename DataTypes>
bool derivRigid3Vectors(const typename DataTypes::VecCoord& x0, const typename DataTypes::VecCoord& x1, typename DataTypes::VecDeriv& d)
{
    unsigned int sz0 = x0.size();
    unsigned int szmin = std::min(sz0,(unsigned int)x1.size());

    d.resize(sz0);
    for(unsigned int i=0; i<szmin; ++i)
    {
        d[i].getVCenter() = x1[i].getCenter() - x0[i].getCenter();
        // Pas de prise en charge des rotations
    }
    for(unsigned int i=szmin; i<sz0; ++i)
    {
        d[i].getVCenter() = - x0[i].getCenter();
    }
    return true;
}

template <typename DataTypes>
double computeDot(const typename DataTypes::Deriv& v0, const typename DataTypes::Deriv& v1)
{
    return v0.x()*v1.x();
}

#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template<>
bool derivVectors<Rigid3dTypes>(const Rigid3dTypes::VecCoord& x0, const Rigid3dTypes::VecCoord& x1, Rigid3dTypes::VecDeriv& d)
{
    return derivRigid3Vectors<Rigid3dTypes>(x0,x1,d);
}
template <>
double computeDot<Rigid3dTypes>(const Rigid3dTypes::Deriv& v0, const Rigid3dTypes::Deriv& v1)
{
    return dot(v0.getVCenter(),v1.getVCenter());
}

#endif
#ifndef SOFA_DOUBLE
using sofa::defaulttype::Rigid3fTypes;
template<>
bool derivVectors<Rigid3fTypes>(const Rigid3fTypes::VecCoord& x0, const Rigid3fTypes::VecCoord& x1, Rigid3fTypes::VecDeriv& d)
{
    return derivRigid3Vectors<Rigid3fTypes>(x0,x1,d);
}
template <>
double computeDot<Rigid3fTypes>(const Rigid3fTypes::Deriv& v0, const Rigid3fTypes::Deriv& v1)
{
    return dot(v0.getVCenter(),v1.getVCenter());
}

#endif

}

namespace sofa
{
namespace component
{
namespace controller
{

template <class DataTypes>
LCPForceFeedback<DataTypes>::LCPForceFeedback()
    : forceCoef(initData(&forceCoef, 0.03, "forceCoef","multiply haptic force by this coef.")),
      haptic_freq(0.0)
{
    this->f_listening.setValue(true);
    mLcp[0] = 0;
    mLcp[1] = 0;
    mLcp[2] = 0;
    mCurBufferId = 0;
    mNextBufferId = 0;
    mIsCuBufferInUse = false;
    _timer = new CTime();

}

template <class DataTypes>
void LCPForceFeedback<DataTypes>::init()
{
    core::objectmodel::BaseContext* c = this->getContext();

    this->ForceFeedback::init();
    if(!c)
    {
        serr << "LCPForceFeedback has no current context. Initialisation failed." << sendl;
        return;
    }

    c->get(lcpconstraintSolver);

    if (!lcpconstraintSolver)
    {
        serr << "LCPForceFeedback has no binding MasterContactSolver. Initialisation failed." << sendl;
        return;
    }

    mState = dynamic_cast<core::behavior::MechanicalState<DataTypes> *> (c->getMechanicalState());
    if (!mState)
    {
        serr << "LCPForceFeedback has no binding MechanicalState. Initialisation failed." << sendl;
        return;
    }

    //sout << "init LCPForceFeedback done " << sendl;
};

template <class DataTypes>
void LCPForceFeedback<DataTypes>::computeForce(const VecCoord& state,  VecDeriv& forces)
{
    const unsigned int stateSize = state.size();
    // Resize du vecteur force. Initialization  0 ?
    forces.resize(stateSize);

    if(!lcpconstraintSolver||!mState)
        return;

    if (!f_activate.getValue())
    {
        return;
    }

    //
    // Retrieve the last LCP and constraints computed by the Sofa thread.
    //
    mIsCuBufferInUse = true;

    mCurBufferId = mNextBufferId;

    const MatrixDeriv& constraints = mConstraints[mCurBufferId];
//	std::vector<int> &id_buf = mId_buf[mCurBufferId];
    VecCoord &val = mVal[mCurBufferId];
    component::constraintset::LCP* lcp = mLcp[mCurBufferId];

    if(!lcp)
    {
        mIsCuBufferInUse = false;
        return;
    }

    component::constraintset::GenericLCP* glcp = dynamic_cast<component::constraintset::GenericLCP*>(lcp);
    if((lcp->getMu() > 0.0 || glcp) && (!constraints.empty()))
    {
        VecDeriv dx;

        derivVectors< DataTypes >(val, state, dx);

        // Modify Dfree
        MatrixDerivRowConstIterator rowItEnd = constraints.end();

        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            MatrixDerivColConstIterator colItEnd = rowIt.end();

            for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
            {
                lcp->getDfree()[rowIt.index()] += computeDot<DataTypes>(colIt.val(), dx[colIt.index()]);
            }
        }

        double tol = lcp->getTolerance();
        int max = 100;

        tol *= 0.001;

        if(glcp != NULL)
        {
            glcp->setTolerance(tol);
            glcp->setMaxIter(max);
            glcp->gaussSeidel(0.0008);
        }
        else
            helper::nlcp_gaussseidelTimed(lcp->getNbConst(), lcp->getDfree(), lcp->getW(), lcp->getF(), lcp->getMu(), tol, max, true, 0.0008);

        // Restore Dfree
        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            MatrixDerivColConstIterator colItEnd = rowIt.end();

            for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
            {
                lcp->getDfree()[rowIt.index()] -= computeDot<DataTypes>(colIt.val(), dx[colIt.index()]);
            }
        }

        VecDeriv tempForces;
        tempForces.resize(val.size());

        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            if (lcp->getF()[rowIt.index()] != 0.0)
            {
                MatrixDerivColConstIterator colItEnd = rowIt.end();

                for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
                {
                    tempForces[colIt.index()] += colIt.val() * lcp->getF()[rowIt.index()];
                }
            }
        }

        for(unsigned int i = 0; i < stateSize; ++i)
        {
            forces[i] = tempForces[i] * forceCoef.getValue();
        }
    }

    mIsCuBufferInUse = false;
}

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::handleEvent(sofa::core::objectmodel::Event *event)
{
    if (!dynamic_cast<sofa::simulation::AnimateEndEvent*>(event))
        return;

    if (!lcpconstraintSolver)
        return;

    if (!mState)
        return;

    component::constraintset::LCP* new_lcp = lcpconstraintSolver->getLCP();
    if (!new_lcp)
        return;

    // Find available buffer

    unsigned char buf_index=0;
    unsigned char cbuf_index=mCurBufferId;
    unsigned char nbuf_index=mNextBufferId;

    if (buf_index == cbuf_index || buf_index == nbuf_index)
        buf_index++;

    if (buf_index == cbuf_index || buf_index == nbuf_index)
        buf_index++;

    // Compute constraints, id_buf lcp and val for the current lcp.

    MatrixDeriv& constraints = mConstraints[buf_index];

//	std::vector<int>& id_buf = mId_buf[buf_index];
    VecCoord& val = mVal[buf_index];

    // Update LCP
    mLcp[buf_index] = new_lcp;

    // Update Val
    val = mState->read(sofa::core::VecCoordId::freePosition())->getValue();

    // Update constraints and id_buf
    constraints.clear();
//	id_buf.clear();

    const MatrixDeriv& c = *(mState->getC());

    MatrixDerivRowConstIterator rowItEnd = c.end();

    for (MatrixDerivRowConstIterator rowIt = c.begin(); rowIt != rowItEnd; ++rowIt)
    {
        constraints.addLine(rowIt.index(), rowIt.row());
    }

    // valid buffer
    mNextBufferId = buf_index;

    // Lock lcp to prevent its use by the SOfa thread while it is used by haptic thread
    if(mIsCuBufferInUse)
        lcpconstraintSolver->lockLCP(mLcp[mCurBufferId], mLcp[mNextBufferId]);
    else
        lcpconstraintSolver->lockLCP(mLcp[mNextBufferId]);
}

//
// Those functions are here for compatibility with the sofa::component::controller::Forcefeedback scheme
//

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::computeForce(double , double, double, double, double, double, double, double&, double&, double&)
{}

#ifndef SOFA_DOUBLE
using sofa::defaulttype::Rigid3fTypes;
template <>
void LCPForceFeedback<Rigid3fTypes>::computeForce(double x, double y, double z, double, double, double, double, double& fx, double& fy, double& fz)
{
    Rigid3fTypes::VecCoord state;
    Rigid3fTypes::VecDeriv forces;
    state.resize(1);
    state[0].getCenter() = sofa::defaulttype::Vec3f((float)x,(float)y,(float)z);
    computeForce(state,forces);
    fx = forces[0].getVCenter().x();
    fy = forces[0].getVCenter().y();
    fz = forces[0].getVCenter().z();
}
#endif

#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template <>
void LCPForceFeedback<Rigid3dTypes>::computeForce(double x, double y, double z, double, double, double, double, double& fx, double& fy, double& fz)
{
    Rigid3dTypes::VecCoord state;
    Rigid3dTypes::VecDeriv forces;
    state.resize(1);
    state[0].getCenter() = sofa::defaulttype::Vec3d(x,y,z);
    computeForce(state,forces);
    fx = forces[0].getVCenter().x();
    fy = forces[0].getVCenter().y();
    fz = forces[0].getVCenter().z();
}
#endif

// 6D rendering of contacts
#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template <>
void LCPForceFeedback<Rigid3dTypes>::computeWrench(const SolidTypes<double>::Transform &world_H_tool,
        const SolidTypes<double>::SpatialVector &/*V_tool_world*/,
        SolidTypes<double>::SpatialVector &W_tool_world )
{
    //std::cerr<<"WARNING : LCPForceFeedback::computeWrench is not implemented"<<std::endl;

    if (!f_activate.getValue())
    {
        return;
    }

    Vec3d Force(0.0,0.0,0.0);

    this->computeForce(world_H_tool.getOrigin()[0], world_H_tool.getOrigin()[1],world_H_tool.getOrigin()[2],
            world_H_tool.getOrientation()[0], world_H_tool.getOrientation()[1], world_H_tool.getOrientation()[2], world_H_tool.getOrientation()[3],
            Force[0],  Force[1], Force[2]);

    W_tool_world.setForce(Force);

};

#endif

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::computeWrench(const SolidTypes<double>::Transform &,
        const SolidTypes<double>::SpatialVector &,
        SolidTypes<double>::SpatialVector & )
{}

} // namespace controller
} // namespace component
} // namespace sofa

#endif
<commit_msg>r8969/sofa-dev : FIX : should fix errors in nodev<commit_after>
#ifndef SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_INL
#define SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_INL

#include <sofa/component/controller/LCPForceFeedback.h>
#include <sofa/simulation/common/AnimateEndEvent.h>
#include <sofa/component/constraintset/LCPConstraintSolver.h>
#ifdef SOFA_DEV
#include <sofa/component/constraintset/GenericLCPConstraintSolver.h>
#endif // SOFA_DEV
#include <sofa/core/objectmodel/BaseContext.h>

#include <algorithm>

namespace
{
template <typename DataTypes>
bool derivVectors(const typename DataTypes::VecCoord& x0, const typename DataTypes::VecCoord& x1, typename DataTypes::VecDeriv& d)
{
    unsigned int sz0 = x0.size();
    unsigned int szmin = std::min(sz0,(unsigned int)x1.size());

    d.resize(sz0);
    for(unsigned int i=0; i<szmin; ++i)
    {
        d[i]=x1[i]-x0[i];
    }
    for(unsigned int i=szmin; i<sz0; ++i)
    {
        d[i]=-x0[i];
    }
    return true;
}

template <typename DataTypes>
bool derivRigid3Vectors(const typename DataTypes::VecCoord& x0, const typename DataTypes::VecCoord& x1, typename DataTypes::VecDeriv& d)
{
    unsigned int sz0 = x0.size();
    unsigned int szmin = std::min(sz0,(unsigned int)x1.size());

    d.resize(sz0);
    for(unsigned int i=0; i<szmin; ++i)
    {
        d[i].getVCenter() = x1[i].getCenter() - x0[i].getCenter();
        // Pas de prise en charge des rotations
    }
    for(unsigned int i=szmin; i<sz0; ++i)
    {
        d[i].getVCenter() = - x0[i].getCenter();
    }
    return true;
}

template <typename DataTypes>
double computeDot(const typename DataTypes::Deriv& v0, const typename DataTypes::Deriv& v1)
{
    return v0.x()*v1.x();
}

#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template<>
bool derivVectors<Rigid3dTypes>(const Rigid3dTypes::VecCoord& x0, const Rigid3dTypes::VecCoord& x1, Rigid3dTypes::VecDeriv& d)
{
    return derivRigid3Vectors<Rigid3dTypes>(x0,x1,d);
}
template <>
double computeDot<Rigid3dTypes>(const Rigid3dTypes::Deriv& v0, const Rigid3dTypes::Deriv& v1)
{
    return dot(v0.getVCenter(),v1.getVCenter());
}

#endif
#ifndef SOFA_DOUBLE
using sofa::defaulttype::Rigid3fTypes;
template<>
bool derivVectors<Rigid3fTypes>(const Rigid3fTypes::VecCoord& x0, const Rigid3fTypes::VecCoord& x1, Rigid3fTypes::VecDeriv& d)
{
    return derivRigid3Vectors<Rigid3fTypes>(x0,x1,d);
}
template <>
double computeDot<Rigid3fTypes>(const Rigid3fTypes::Deriv& v0, const Rigid3fTypes::Deriv& v1)
{
    return dot(v0.getVCenter(),v1.getVCenter());
}

#endif

}

namespace sofa
{
namespace component
{
namespace controller
{

template <class DataTypes>
LCPForceFeedback<DataTypes>::LCPForceFeedback()
    : forceCoef(initData(&forceCoef, 0.03, "forceCoef","multiply haptic force by this coef.")),
      haptic_freq(0.0)
{
    this->f_listening.setValue(true);
    mLcp[0] = 0;
    mLcp[1] = 0;
    mLcp[2] = 0;
    mCurBufferId = 0;
    mNextBufferId = 0;
    mIsCuBufferInUse = false;
    _timer = new CTime();

}

template <class DataTypes>
void LCPForceFeedback<DataTypes>::init()
{
    core::objectmodel::BaseContext* c = this->getContext();

    this->ForceFeedback::init();
    if(!c)
    {
        serr << "LCPForceFeedback has no current context. Initialisation failed." << sendl;
        return;
    }

    c->get(lcpconstraintSolver);

    if (!lcpconstraintSolver)
    {
        serr << "LCPForceFeedback has no binding MasterContactSolver. Initialisation failed." << sendl;
        return;
    }

    mState = dynamic_cast<core::behavior::MechanicalState<DataTypes> *> (c->getMechanicalState());
    if (!mState)
    {
        serr << "LCPForceFeedback has no binding MechanicalState. Initialisation failed." << sendl;
        return;
    }

    //sout << "init LCPForceFeedback done " << sendl;
};

template <class DataTypes>
void LCPForceFeedback<DataTypes>::computeForce(const VecCoord& state,  VecDeriv& forces)
{
    const unsigned int stateSize = state.size();
    // Resize du vecteur force. Initialization  0 ?
    forces.resize(stateSize);

    if(!lcpconstraintSolver||!mState)
        return;

    if (!f_activate.getValue())
    {
        return;
    }

    //
    // Retrieve the last LCP and constraints computed by the Sofa thread.
    //
    mIsCuBufferInUse = true;

    mCurBufferId = mNextBufferId;

    const MatrixDeriv& constraints = mConstraints[mCurBufferId];
//	std::vector<int> &id_buf = mId_buf[mCurBufferId];
    VecCoord &val = mVal[mCurBufferId];
    component::constraintset::LCP* lcp = mLcp[mCurBufferId];

    if(!lcp)
    {
        mIsCuBufferInUse = false;
        return;
    }

#ifdef SOFA_DEV
    component::constraintset::GenericLCP* glcp = dynamic_cast<component::constraintset::GenericLCP*>(lcp);
#endif // SOFA_DEV
    if( (lcp->getMu() > 0.0
#ifdef SOFA_DEV
            || glcp
#endif // SOFA_DEV
        ) && (!constraints.empty()))
    {
        VecDeriv dx;

        derivVectors< DataTypes >(val, state, dx);

        // Modify Dfree
        MatrixDerivRowConstIterator rowItEnd = constraints.end();

        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            MatrixDerivColConstIterator colItEnd = rowIt.end();

            for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
            {
                lcp->getDfree()[rowIt.index()] += computeDot<DataTypes>(colIt.val(), dx[colIt.index()]);
            }
        }

        double tol = lcp->getTolerance();
        int max = 100;

        tol *= 0.001;
#ifdef SOFA_DEV
        if(glcp != NULL)
        {
            glcp->setTolerance(tol);
            glcp->setMaxIter(max);
            glcp->gaussSeidel(0.0008);
        }
        else
#endif // SOFA_DEV
            helper::nlcp_gaussseidelTimed(lcp->getNbConst(), lcp->getDfree(), lcp->getW(), lcp->getF(), lcp->getMu(), tol, max, true, 0.0008);

        // Restore Dfree
        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            MatrixDerivColConstIterator colItEnd = rowIt.end();

            for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
            {
                lcp->getDfree()[rowIt.index()] -= computeDot<DataTypes>(colIt.val(), dx[colIt.index()]);
            }
        }

        VecDeriv tempForces;
        tempForces.resize(val.size());

        for (MatrixDerivRowConstIterator rowIt = constraints.begin(); rowIt != rowItEnd; ++rowIt)
        {
            if (lcp->getF()[rowIt.index()] != 0.0)
            {
                MatrixDerivColConstIterator colItEnd = rowIt.end();

                for (MatrixDerivColConstIterator colIt = rowIt.begin(); colIt != colItEnd; ++colIt)
                {
                    tempForces[colIt.index()] += colIt.val() * lcp->getF()[rowIt.index()];
                }
            }
        }

        for(unsigned int i = 0; i < stateSize; ++i)
        {
            forces[i] = tempForces[i] * forceCoef.getValue();
        }
    }

    mIsCuBufferInUse = false;
}

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::handleEvent(sofa::core::objectmodel::Event *event)
{
    if (!dynamic_cast<sofa::simulation::AnimateEndEvent*>(event))
        return;

    if (!lcpconstraintSolver)
        return;

    if (!mState)
        return;

    component::constraintset::LCP* new_lcp = lcpconstraintSolver->getLCP();
    if (!new_lcp)
        return;

    // Find available buffer

    unsigned char buf_index=0;
    unsigned char cbuf_index=mCurBufferId;
    unsigned char nbuf_index=mNextBufferId;

    if (buf_index == cbuf_index || buf_index == nbuf_index)
        buf_index++;

    if (buf_index == cbuf_index || buf_index == nbuf_index)
        buf_index++;

    // Compute constraints, id_buf lcp and val for the current lcp.

    MatrixDeriv& constraints = mConstraints[buf_index];

//	std::vector<int>& id_buf = mId_buf[buf_index];
    VecCoord& val = mVal[buf_index];

    // Update LCP
    mLcp[buf_index] = new_lcp;

    // Update Val
    val = mState->read(sofa::core::VecCoordId::freePosition())->getValue();

    // Update constraints and id_buf
    constraints.clear();
//	id_buf.clear();

    const MatrixDeriv& c = *(mState->getC());

    MatrixDerivRowConstIterator rowItEnd = c.end();

    for (MatrixDerivRowConstIterator rowIt = c.begin(); rowIt != rowItEnd; ++rowIt)
    {
        constraints.addLine(rowIt.index(), rowIt.row());
    }

    // valid buffer
    mNextBufferId = buf_index;

    // Lock lcp to prevent its use by the SOfa thread while it is used by haptic thread
    if(mIsCuBufferInUse)
        lcpconstraintSolver->lockLCP(mLcp[mCurBufferId], mLcp[mNextBufferId]);
    else
        lcpconstraintSolver->lockLCP(mLcp[mNextBufferId]);
}

//
// Those functions are here for compatibility with the sofa::component::controller::Forcefeedback scheme
//

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::computeForce(double , double, double, double, double, double, double, double&, double&, double&)
{}

#ifndef SOFA_DOUBLE
using sofa::defaulttype::Rigid3fTypes;
template <>
void LCPForceFeedback<Rigid3fTypes>::computeForce(double x, double y, double z, double, double, double, double, double& fx, double& fy, double& fz)
{
    Rigid3fTypes::VecCoord state;
    Rigid3fTypes::VecDeriv forces;
    state.resize(1);
    state[0].getCenter() = sofa::defaulttype::Vec3f((float)x,(float)y,(float)z);
    computeForce(state,forces);
    fx = forces[0].getVCenter().x();
    fy = forces[0].getVCenter().y();
    fz = forces[0].getVCenter().z();
}
#endif

#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template <>
void LCPForceFeedback<Rigid3dTypes>::computeForce(double x, double y, double z, double, double, double, double, double& fx, double& fy, double& fz)
{
    Rigid3dTypes::VecCoord state;
    Rigid3dTypes::VecDeriv forces;
    state.resize(1);
    state[0].getCenter() = sofa::defaulttype::Vec3d(x,y,z);
    computeForce(state,forces);
    fx = forces[0].getVCenter().x();
    fy = forces[0].getVCenter().y();
    fz = forces[0].getVCenter().z();
}
#endif

// 6D rendering of contacts
#ifndef SOFA_FLOAT
using sofa::defaulttype::Rigid3dTypes;
template <>
void LCPForceFeedback<Rigid3dTypes>::computeWrench(const SolidTypes<double>::Transform &world_H_tool,
        const SolidTypes<double>::SpatialVector &/*V_tool_world*/,
        SolidTypes<double>::SpatialVector &W_tool_world )
{
    //std::cerr<<"WARNING : LCPForceFeedback::computeWrench is not implemented"<<std::endl;

    if (!f_activate.getValue())
    {
        return;
    }

    Vec3d Force(0.0,0.0,0.0);

    this->computeForce(world_H_tool.getOrigin()[0], world_H_tool.getOrigin()[1],world_H_tool.getOrigin()[2],
            world_H_tool.getOrientation()[0], world_H_tool.getOrientation()[1], world_H_tool.getOrientation()[2], world_H_tool.getOrientation()[3],
            Force[0],  Force[1], Force[2]);

    W_tool_world.setForce(Force);

};

#endif

template <typename DataTypes>
void LCPForceFeedback<DataTypes>::computeWrench(const SolidTypes<double>::Transform &,
        const SolidTypes<double>::SpatialVector &,
        SolidTypes<double>::SpatialVector & )
{}

} // namespace controller
} // namespace component
} // namespace sofa

#endif
<|endoftext|>


<commit_before>#include "xhp.hpp"
#include "xhp_preprocess.hpp"
#include "fastpath.hpp"
#include <sstream>
using namespace std;
extern int xhpdebug;
#include <iostream>

XHPResult xhp_preprocess(istream &in, string &out, bool isEval, string &errDescription, uint32_t &errLineno) {

  // Read stream to string
  stringbuf sb;
  in >> noskipws >> &sb;
  string buffer = sb.str();
  return xhp_preprocess(buffer, out, isEval, errDescription, errLineno);
}

XHPResult xhp_preprocess(string &in, string &out, bool isEval, string &errDescription, uint32_t &errLineno) {
  xhp_flags_t flags;
  memset(&flags, 0, sizeof(xhp_flags_t));
  flags.eval = isEval;
  flags.short_tags = true;
  return xhp_preprocess(in, out, errDescription, errLineno, flags);
}

XHPResult xhp_preprocess(std::string &in, std::string &out, std::string &errDescription, uint32_t &errLineno, const xhp_flags_t &flags) {

  // Early bail if the code doesn't contain anything that looks like XHP
  char* buffer = const_cast<char*>(in.c_str());
  if (!xhp_fastpath(buffer, in.length(), flags)) {
    return XHPDidNothing;
  }

  // Create a flex buffer
  in.reserve(in.size() + 1);
  buffer = const_cast<char*>(in.c_str());
  buffer[in.size() + 1] = 0; // need double NULL for scan_buffer

  // Parse the PHP
  void* scanner;
  code_rope new_code;
  yy_extra_type extra;
  extra.idx_expr = flags.idx_expr;
  extra.insert_token = flags.eval ? T_OPEN_TAG_FAKE : 0;
  extra.short_tags = flags.short_tags;
  extra.asp_tags = flags.asp_tags;

  xhplex_init(&scanner);
  xhpset_extra(&extra, scanner);
  xhp_scan_buffer(buffer, in.size() + 2, scanner);
#ifdef DEBUG
  xhpdebug = 1;
#endif
  xhpparse(scanner, &new_code);
  xhplex_destroy(scanner);

  // Check to see what happened
  if (extra.terminated) {
    errDescription = extra.error;
    errLineno = extra.lineno;
    return XHPErred;
  } else if (!extra.used) {
    return XHPDidNothing;
  } else {
    out = new_code.c_str();
    return XHPRewrote;
  }
}
<commit_msg>Default idx_expr to true in xhp_preprocess<commit_after>#include "xhp.hpp"
#include "xhp_preprocess.hpp"
#include "fastpath.hpp"
#include <sstream>
using namespace std;
extern int xhpdebug;
#include <iostream>

XHPResult xhp_preprocess(istream &in, string &out, bool isEval, string &errDescription, uint32_t &errLineno) {

  // Read stream to string
  stringbuf sb;
  in >> noskipws >> &sb;
  string buffer = sb.str();
  return xhp_preprocess(buffer, out, isEval, errDescription, errLineno);
}

XHPResult xhp_preprocess(string &in, string &out, bool isEval, string &errDescription, uint32_t &errLineno) {
  xhp_flags_t flags;
  memset(&flags, 0, sizeof(xhp_flags_t));
  flags.eval = isEval;
  flags.short_tags = true;
  flags.idx_expr = true;
  return xhp_preprocess(in, out, errDescription, errLineno, flags);
}

XHPResult xhp_preprocess(std::string &in, std::string &out, std::string &errDescription, uint32_t &errLineno, const xhp_flags_t &flags) {

  // Early bail if the code doesn't contain anything that looks like XHP
  char* buffer = const_cast<char*>(in.c_str());
  if (!xhp_fastpath(buffer, in.length(), flags)) {
    return XHPDidNothing;
  }

  // Create a flex buffer
  in.reserve(in.size() + 1);
  buffer = const_cast<char*>(in.c_str());
  buffer[in.size() + 1] = 0; // need double NULL for scan_buffer

  // Parse the PHP
  void* scanner;
  code_rope new_code;
  yy_extra_type extra;
  extra.idx_expr = flags.idx_expr;
  extra.insert_token = flags.eval ? T_OPEN_TAG_FAKE : 0;
  extra.short_tags = flags.short_tags;
  extra.asp_tags = flags.asp_tags;

  xhplex_init(&scanner);
  xhpset_extra(&extra, scanner);
  xhp_scan_buffer(buffer, in.size() + 2, scanner);
#ifdef DEBUG
  xhpdebug = 1;
#endif
  xhpparse(scanner, &new_code);
  xhplex_destroy(scanner);

  // Check to see what happened
  if (extra.terminated) {
    errDescription = extra.error;
    errLineno = extra.lineno;
    return XHPErred;
  } else if (!extra.used) {
    return XHPDidNothing;
  } else {
    out = new_code.c_str();
    return XHPRewrote;
  }
}
<|endoftext|>