<commit_before>/*************************************************************************
This software allows for filtering in high-dimensional observation and
state spaces, as described in

M. Wuthrich, P. Pastor, M. Kalakrishnan, J. Bohg, and S. Schaal.
Probabilistic Object Tracking using a Range Camera
IEEE/RSJ Intl Conf on Intelligent Robots and Systems, 2013

In a publication based on this software pleace cite the above reference.

Copyright (C) 2014  Manuel Wuthrich

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/

#ifndef FAST_FILTERING_UTILS_PROFILING_HPP
#define FAST_FILTERING_UTILS_PROFILING_HPP

#include <sys/time.h>
#include <iostream>

// profiling macros
#define GET_TIME(time) {struct timeval profiling_time; gettimeofday(&profiling_time, NULL);\
    time = (profiling_time.tv_sec * 1000000u + profiling_time.tv_usec) /1000000.;}
#ifdef PROFILING_ON
    #define PRINT(object) std::cout << object;

    #define INIT_PROFILING struct timeval profiling_start_time, profiling_end_time;\
                                    gettimeofday(&profiling_start_time, NULL);
    #define RESET gettimeofday(&profiling_start_time, NULL);
    #define MEASURE(text)\
            gettimeofday(&profiling_end_time, NULL);\
            std::cout << "time for " << text << " " \
              << ((profiling_end_time.tv_sec - profiling_start_time.tv_sec) * 1000000u\
                 + profiling_end_time.tv_usec - profiling_start_time.tv_usec) /1000000. \
              << " s" << std::endl; gettimeofday(&profiling_start_time, NULL);
#else
    #define PRINT(object)
    #define INIT_PROFILING
    #define RESET
    #define MEASURE(text)
#endif

#endif
<commit_msg>added std::setprecision(9) and std::fixed to MEASURE output.<commit_after>/*************************************************************************
This software allows for filtering in high-dimensional observation and
state spaces, as described in

M. Wuthrich, P. Pastor, M. Kalakrishnan, J. Bohg, and S. Schaal.
Probabilistic Object Tracking using a Range Camera
IEEE/RSJ Intl Conf on Intelligent Robots and Systems, 2013

In a publication based on this software pleace cite the above reference.

Copyright (C) 2014  Manuel Wuthrich

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/

#ifndef FAST_FILTERING_UTILS_PROFILING_HPP
#define FAST_FILTERING_UTILS_PROFILING_HPP

#include <sys/time.h>
#include <iostream>

// profiling macros
#define GET_TIME(time) {struct timeval profiling_time; gettimeofday(&profiling_time, NULL);\
    time = (profiling_time.tv_sec * 1000000u + profiling_time.tv_usec) /1000000.;}
#ifdef PROFILING_ON
    #define PRINT(object) std::cout << object;

    #define INIT_PROFILING struct timeval profiling_start_time, profiling_end_time;\
                                    gettimeofday(&profiling_start_time, NULL);
    #define RESET gettimeofday(&profiling_start_time, NULL);
    #define MEASURE(text)\
            gettimeofday(&profiling_end_time, NULL);\
            std::cout << "time for " << text << " " \
              << std::setprecision(9) << std::fixed\
              << ((profiling_end_time.tv_sec - profiling_start_time.tv_sec) * 1000000u\
                 + profiling_end_time.tv_usec - profiling_start_time.tv_usec) /1000000. \
              << " s" << std::endl; gettimeofday(&profiling_start_time, NULL);
#else
    #define PRINT(object)
    #define INIT_PROFILING
    #define RESET
    #define MEASURE(text)
#endif

#endif
<|endoftext|>


<commit_before>// ///////////////////////////////////////////////////////////////////////////
// tenh/implementation/innerproduct.hpp by Victor Dods, created 2013/09/08
// Copyright Leap Motion Inc.
// ///////////////////////////////////////////////////////////////////////////

#ifndef TENH_IMPLEMENTATION_INNERPRODUCT_HPP_
#define TENH_IMPLEMENTATION_INNERPRODUCT_HPP_

#include "tenh/core.hpp"

#include "tenh/implementation/tensorproduct.hpp"

namespace Tenh {

// ///////////////////////////////////////////////////////////////////////////
// forward declaration for the InnerProduct_f metafunction (should return
// an ImplementationOf_t type that uses ImmutableArray_t)
// ///////////////////////////////////////////////////////////////////////////

template <typename BasedVectorSpace_, typename InnerProductId_, typename Scalar_> struct InnerProduct_f;

// ///////////////////////////////////////////////////////////////////////////
// standard inner product on a based vector space having an orthonormal basis
// ///////////////////////////////////////////////////////////////////////////

// corresponds to the identity matrix
struct StandardInnerProduct { static std::string type_as_string () { return "StandardInnerProduct"; } };

// template specialization for standard inner product on a based vector space having orthonormal basis
template <typename VectorSpace_, typename OrthonormalBasisId_, typename Scalar_>
struct InnerProduct_f<BasedVectorSpace_c<VectorSpace_,OrthonormalBasis_c<OrthonormalBasisId_> >,StandardInnerProduct,Scalar_>
{
private:
    typedef BasedVectorSpace_c<VectorSpace_,OrthonormalBasis_c<OrthonormalBasisId_> > BasedVectorSpace;
    typedef typename DualOf_f<BasedVectorSpace>::T DualOfBasedVectorSpace;
    typedef Diagonal2TensorProductOfBasedVectorSpaces_c<BasedVectorSpace,DualOfBasedVectorSpace> Diagonal2Tensor;
    typedef ComponentGenerator_t<Scalar_,
                                 DimensionOf_f<Diagonal2Tensor>::V,
                                 constant_component_generator_evaluator<Scalar_,DimensionOf_f<Diagonal2Tensor>::V,1>,
                                 StandardInnerProduct> ComponentGenerator;
    InnerProduct_f();
public:
    typedef ImplementationOf_t<Diagonal2Tensor,Scalar_,UseImmutableArray_t<ComponentGenerator> > T;
};

// ///////////////////////////////////////////////////////////////////////////
// induced inner product on TensorProductOfBasedVectorSpaces_c
// ///////////////////////////////////////////////////////////////////////////

// meta-function helper for induced inner products

template <typename FactorTypeList_, typename InnerProductIdTypeList_, typename Scalar_>
struct InnerProductOfEachInTypeList_f
{
private:
    enum { STATIC_ASSERT_IN_ENUM(FactorTypeList_::LENGTH == InnerProductIdTypeList_::LENGTH, LENGTHS_MUST_BE_EQUAL) };
    InnerProductOfEachInTypeList_f();
public:
    typedef TypeList_t<typename InnerProduct_f<typename FactorTypeList_::HeadType,
                                               typename InnerProductIdTypeList_::HeadType,
                                               Scalar_>::T,
                       typename InnerProductOfEachInTypeList_f<typename FactorTypeList_::BodyTypeList,
                                                               typename InnerProductIdTypeList_::BodyTypeList,
                                                               Scalar_>::T> T;
};

template <typename Scalar_>
struct InnerProductOfEachInTypeList_f<EmptyTypeList,EmptyTypeList,Scalar_>
{
    typedef EmptyTypeList T;
private:
    InnerProductOfEachInTypeList_f();
};

// induced inner product on TensorProductOfBasedVectorSpaces_c
template <typename FactorTypeList_, typename InnerProductIdTypeList_, typename Scalar_>
struct InnerProduct_f<TensorProductOfBasedVectorSpaces_c<FactorTypeList_>,TensorProduct_c<InnerProductIdTypeList_>,Scalar_>
{
private:
    typedef typename InnerProductOfEachInTypeList_f<FactorTypeList_,InnerProductIdTypeList_,Scalar_>::T InnerProductTypeList;
    InnerProduct_f();
public:
    typedef typename TensorProductOfImmutable2Tensors_f<InnerProductTypeList>::T T;
};

} // end of namespace Tenh

#endif // TENH_IMPLEMENTATION_INNERPRODUCT_HPP_
<commit_msg>That’s just completely wrong.<commit_after>// ///////////////////////////////////////////////////////////////////////////
// tenh/implementation/innerproduct.hpp by Victor Dods, created 2013/09/08
// Copyright Leap Motion Inc.
// ///////////////////////////////////////////////////////////////////////////

#ifndef TENH_IMPLEMENTATION_INNERPRODUCT_HPP_
#define TENH_IMPLEMENTATION_INNERPRODUCT_HPP_

#include "tenh/core.hpp"

#include "tenh/implementation/tensorproduct.hpp"

namespace Tenh {

// ///////////////////////////////////////////////////////////////////////////
// forward declaration for the InnerProduct_f metafunction (should return
// an ImplementationOf_t type that uses ImmutableArray_t)
// ///////////////////////////////////////////////////////////////////////////

template <typename BasedVectorSpace_, typename InnerProductId_, typename Scalar_> struct InnerProduct_f;

// ///////////////////////////////////////////////////////////////////////////
// standard inner product on a based vector space having an orthonormal basis
// ///////////////////////////////////////////////////////////////////////////

// corresponds to the identity matrix
struct StandardInnerProduct { static std::string type_as_string () { return "StandardInnerProduct"; } };

// template specialization for standard inner product on a based vector space having orthonormal basis
template <typename VectorSpace_, typename OrthonormalBasisId_, typename Scalar_>
struct InnerProduct_f<BasedVectorSpace_c<VectorSpace_,OrthonormalBasis_c<OrthonormalBasisId_> >,StandardInnerProduct,Scalar_>
{
private:
    typedef BasedVectorSpace_c<VectorSpace_,OrthonormalBasis_c<OrthonormalBasisId_> > BasedVectorSpace;
    typedef typename DualOf_f<BasedVectorSpace>::T DualOfBasedVectorSpace;
    typedef Diagonal2TensorProductOfBasedVectorSpaces_c<DualOfBasedVectorSpace,DualOfBasedVectorSpace> Diagonal2Tensor;
    typedef ComponentGenerator_t<Scalar_,
                                 DimensionOf_f<Diagonal2Tensor>::V,
                                 constant_component_generator_evaluator<Scalar_,DimensionOf_f<Diagonal2Tensor>::V,1>,
                                 StandardInnerProduct> ComponentGenerator;
    InnerProduct_f();
public:
    typedef ImplementationOf_t<Diagonal2Tensor,Scalar_,UseImmutableArray_t<ComponentGenerator> > T;
};

// ///////////////////////////////////////////////////////////////////////////
// induced inner product on TensorProductOfBasedVectorSpaces_c
// ///////////////////////////////////////////////////////////////////////////

// meta-function helper for induced inner products

template <typename FactorTypeList_, typename InnerProductIdTypeList_, typename Scalar_>
struct InnerProductOfEachInTypeList_f
{
private:
    enum { STATIC_ASSERT_IN_ENUM(FactorTypeList_::LENGTH == InnerProductIdTypeList_::LENGTH, LENGTHS_MUST_BE_EQUAL) };
    InnerProductOfEachInTypeList_f();
public:
    typedef TypeList_t<typename InnerProduct_f<typename FactorTypeList_::HeadType,
                                               typename InnerProductIdTypeList_::HeadType,
                                               Scalar_>::T,
                       typename InnerProductOfEachInTypeList_f<typename FactorTypeList_::BodyTypeList,
                                                               typename InnerProductIdTypeList_::BodyTypeList,
                                                               Scalar_>::T> T;
};

template <typename Scalar_>
struct InnerProductOfEachInTypeList_f<EmptyTypeList,EmptyTypeList,Scalar_>
{
    typedef EmptyTypeList T;
private:
    InnerProductOfEachInTypeList_f();
};

// induced inner product on TensorProductOfBasedVectorSpaces_c
template <typename FactorTypeList_, typename InnerProductIdTypeList_, typename Scalar_>
struct InnerProduct_f<TensorProductOfBasedVectorSpaces_c<FactorTypeList_>,TensorProduct_c<InnerProductIdTypeList_>,Scalar_>
{
private:
    typedef typename InnerProductOfEachInTypeList_f<FactorTypeList_,InnerProductIdTypeList_,Scalar_>::T InnerProductTypeList;
    InnerProduct_f();
public:
    typedef typename TensorProductOfImmutable2Tensors_f<InnerProductTypeList>::T T;
};

} // end of namespace Tenh

#endif // TENH_IMPLEMENTATION_INNERPRODUCT_HPP_
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// FIXME: This file shall contain the decl of cling::Jupyter in a future
// revision!
//#include "cling/Interpreter/Jupyter/Kernel.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

#include "llvm/Support/raw_ostream.h"

#include <map>
#include <string>
#include <cstring>
#ifndef LLVM_ON_WIN32
# include <unistd.h>
#else
# include <io.h>
# define write _write
#endif

// FIXME: should be moved into a Jupyter interp struct that then gets returned
// from create.
int pipeToJupyterFD = -1;

namespace cling {
  namespace Jupyter {
    struct MIMEDataRef {
      const char* m_Data;
      const long m_Size;

      MIMEDataRef(const std::string& str):
      m_Data(str.c_str()), m_Size((long)str.length() + 1) {}
      MIMEDataRef(const char* str):
      MIMEDataRef(std::string(str)) {}
      MIMEDataRef(const char* data, long size):
      m_Data(data), m_Size(size) {}
    };

    /// Push MIME stuff to Jupyter. To be called from user code.
    ///\param contentDict - dictionary of MIME type versus content. E.g.
    /// {{"text/html", {"

", }}
    ///\returns `false` if the output could not be sent.
    bool pushOutput(const std::map<std::string, MIMEDataRef> contentDict) {

      // Pipe sees (all numbers are longs, except for the first:
      // - num bytes in a long (sent as a single unsigned char!)
      // - num elements of the MIME dictionary; Jupyter selects one to display.
      // For each MIME dictionary element:
      //   - size of MIME type string  (including the terminating 0)
      //   - MIME type as 0-terminated string
      //   - size of MIME data buffer (including the terminating 0 for
      //     0-terminated strings)
      //   - MIME data buffer

      // Write number of dictionary elements (and the size of that number in a
      // char)
      unsigned char sizeLong = sizeof(long);
      if (write(pipeToJupyterFD, &sizeLong, 1) != 1)
        return false;
      long dictSize = contentDict.size();
      if (write(pipeToJupyterFD, &dictSize, sizeof(long)) != sizeof(long))
        return false;

      for (auto iContent: contentDict) {
        const std::string& mimeType = iContent.first;
        long mimeTypeSize = (long)mimeType.size();
        if (write(pipeToJupyterFD, &mimeTypeSize, sizeof(long)) != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeType.c_str(), mimeType.size() + 1)
            != mimeType.size() + 1)
          return false;
        const MIMEDataRef& mimeData = iContent.second;
        if (write(pipeToJupyterFD, &mimeData.m_Size, sizeof(long))
            != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeData.m_Data, mimeData.m_Size)
            != mimeData.m_Size)
          return false;
      }
      return true;
    }
  } // namespace Jupyter
} // namespace cling

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The Interpreter object cast to void*
using TheInterpreter = void ;

/// Create an interpreter object.
TheInterpreter*
cling_create(int argc, const char *argv[], const char* llvmdir, int pipefd) {
  auto interp = new cling::Interpreter(argc, argv, llvmdir);
  pipeToJupyterFD = pipefd;
  return interp;
}

/// Destroy the interpreter.
void cling_destroy(TheInterpreter *interpVP) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  delete interp;
}

/// Stringify a cling::Value
static std::string ValueToString(const cling::Value& V) {
  std::string valueString;
  {
    llvm::raw_string_ostream os(valueString);
    V.print(os);
  }
  return valueString;
}

/// Evaluate a string of code. Returns nullptr on failure.
/// Returns a string representation of the expression (can be "") on success.
char* cling_eval(TheInterpreter *interpVP, const char *code) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  cling::Value V;
  cling::Interpreter::CompilationResult Res = interp->process(code, &V);
  if (Res != cling::Interpreter::kSuccess)
    return nullptr;

  // cling::Jupyter::pushOutput({{"text/html", "You just executed C++ code!"}});
  if (!V.isValid())
    return strdup("");
  return strdup(ValueToString(V).c_str());
}

void cling_eval_free(char* str) {
  free(str);
}

/// Code completion interfaces.

/// Start completion of code. Returns a handle to be passed to
/// cling_complete_next() to iterate over the completion options. Returns nulptr
/// if no completions are known.
void* cling_complete_start(const char* code) {
  return new int(42);
}

/// Grab the next completion of some code. Returns nullptr if none is left.
const char* cling_complete_next(void* completionHandle) {
  int* counter = (int*) completionHandle;
  if (++(*counter) > 43) {
    delete counter;
    return nullptr;
  }
  return "COMPLETE!";
}

///\}

} // extern "C"
<commit_msg>Fix warning unsigned/signed comparison.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// FIXME: This file shall contain the decl of cling::Jupyter in a future
// revision!
//#include "cling/Interpreter/Jupyter/Kernel.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

#include "llvm/Support/raw_ostream.h"

#include <map>
#include <string>
#include <cstring>
#ifndef LLVM_ON_WIN32
# include <unistd.h>
#else
# include <io.h>
# define write _write
#endif

// FIXME: should be moved into a Jupyter interp struct that then gets returned
// from create.
int pipeToJupyterFD = -1;

namespace cling {
  namespace Jupyter {
    struct MIMEDataRef {
      const char* m_Data;
      const long m_Size;

      MIMEDataRef(const std::string& str):
      m_Data(str.c_str()), m_Size((long)str.length() + 1) {}
      MIMEDataRef(const char* str):
      MIMEDataRef(std::string(str)) {}
      MIMEDataRef(const char* data, long size):
      m_Data(data), m_Size(size) {}
    };

    /// Push MIME stuff to Jupyter. To be called from user code.
    ///\param contentDict - dictionary of MIME type versus content. E.g.
    /// {{"text/html", {"

", }}
    ///\returns `false` if the output could not be sent.
    bool pushOutput(const std::map<std::string, MIMEDataRef> contentDict) {

      // Pipe sees (all numbers are longs, except for the first:
      // - num bytes in a long (sent as a single unsigned char!)
      // - num elements of the MIME dictionary; Jupyter selects one to display.
      // For each MIME dictionary element:
      //   - size of MIME type string  (including the terminating 0)
      //   - MIME type as 0-terminated string
      //   - size of MIME data buffer (including the terminating 0 for
      //     0-terminated strings)
      //   - MIME data buffer

      // Write number of dictionary elements (and the size of that number in a
      // char)
      unsigned char sizeLong = sizeof(long);
      if (write(pipeToJupyterFD, &sizeLong, 1) != 1)
        return false;
      long dictSize = contentDict.size();
      if (write(pipeToJupyterFD, &dictSize, sizeof(long)) != sizeof(long))
        return false;

      for (auto iContent: contentDict) {
        const std::string& mimeType = iContent.first;
        long mimeTypeSize = (long)mimeType.size();
        if (write(pipeToJupyterFD, &mimeTypeSize, sizeof(long)) != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeType.c_str(), mimeType.size() + 1)
            != (long)(mimeType.size() + 1))
          return false;
        const MIMEDataRef& mimeData = iContent.second;
        if (write(pipeToJupyterFD, &mimeData.m_Size, sizeof(long))
            != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeData.m_Data, mimeData.m_Size)
            != mimeData.m_Size)
          return false;
      }
      return true;
    }
  } // namespace Jupyter
} // namespace cling

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The Interpreter object cast to void*
using TheInterpreter = void ;

/// Create an interpreter object.
TheInterpreter*
cling_create(int argc, const char *argv[], const char* llvmdir, int pipefd) {
  auto interp = new cling::Interpreter(argc, argv, llvmdir);
  pipeToJupyterFD = pipefd;
  return interp;
}

/// Destroy the interpreter.
void cling_destroy(TheInterpreter *interpVP) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  delete interp;
}

/// Stringify a cling::Value
static std::string ValueToString(const cling::Value& V) {
  std::string valueString;
  {
    llvm::raw_string_ostream os(valueString);
    V.print(os);
  }
  return valueString;
}

/// Evaluate a string of code. Returns nullptr on failure.
/// Returns a string representation of the expression (can be "") on success.
char* cling_eval(TheInterpreter *interpVP, const char *code) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  cling::Value V;
  cling::Interpreter::CompilationResult Res = interp->process(code, &V);
  if (Res != cling::Interpreter::kSuccess)
    return nullptr;

  // cling::Jupyter::pushOutput({{"text/html", "You just executed C++ code!"}});
  if (!V.isValid())
    return strdup("");
  return strdup(ValueToString(V).c_str());
}

void cling_eval_free(char* str) {
  free(str);
}

/// Code completion interfaces.

/// Start completion of code. Returns a handle to be passed to
/// cling_complete_next() to iterate over the completion options. Returns nulptr
/// if no completions are known.
void* cling_complete_start(const char* code) {
  return new int(42);
}

/// Grab the next completion of some code. Returns nullptr if none is left.
const char* cling_complete_next(void* completionHandle) {
  int* counter = (int*) completionHandle;
  if (++(*counter) > 43) {
    delete counter;
    return nullptr;
  }
  return "COMPLETE!";
}

///\}

} // extern "C"
<|endoftext|>


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

#include "mesh_manager.hpp"
#include "gltf.hpp"
#include "mesh_util.hpp"
#include <stdexcept>

using namespace std;

namespace Granite
{
MeshManager::MeshGroup *MeshManager::register_mesh(const std::string &path)
{
	Util::Hasher hash;
	hash.string(path);

	MeshGroup *group = groups.find(hash.get());
	if (group)
		return group;

	group = groups.emplace_yield(hash.get());

	GLTF::Parser parser(path);
	if (parser.get_scenes().empty())
		throw logic_error("No scenes in glTF.");

	auto &scene = parser.get_scenes().front();
	group->top_level_nodes = scene.node_indices;
	group->node_hierarchy = parser.get_nodes();
	for (auto &mesh : parser.get_meshes())
		group->renderables.push_back(create_imported_mesh(mesh, parser.get_materials().data()));

	return group;
}

static std::vector<Scene::NodeHandle> create_nodes(Scene &scene, const std::vector<Granite::SceneFormats::Node> &nodes)
{
	vector<Scene::NodeHandle> scene_nodes(nodes.size());

	for (size_t i = 0; i < nodes.size(); i++)
	{
		auto &node_info = nodes[i];
		if (node_info.has_skin)
			throw logic_error("Skinning not yet supported for MeshManager.");

		auto node = scene.create_node();
		scene_nodes[i] = move(node);
	}

	for (size_t i = 0; i < nodes.size(); i++)
	{
		auto &node_info = nodes[i];
		for (auto &child : node_info.children)
			scene_nodes[i]->add_child(scene_nodes[child]);
	}

	return scene_nodes;
}

static Scene::NodeHandle create_root_node(Scene &scene, const std::vector<Scene::NodeHandle> &nodes, const std::vector<uint32_t> &top_level_nodes)
{
	auto root = scene.create_node();
	for (auto &top_level : top_level_nodes)
		root->add_child(nodes[top_level]);
	return root;
}

MeshManager::SingleHandle MeshManager::instantiate_renderable(Scene &scene, MeshGroup *group)
{
	auto nodes = create_nodes(scene, group->node_hierarchy);

	SingleHandle handles = {};
	handles.root_node = create_root_node(scene, nodes, group->top_level_nodes);

	for (auto &node : group->node_hierarchy)
	{
		if (!node.meshes.empty())
		{
			unsigned mesh_index = node.meshes.front();
			auto node_index = unsigned(&node - group->node_hierarchy.data());
			handles.entity = scene.create_renderable(group->renderables[mesh_index], nodes[node_index].get());
			break;
		}
	}

	return handles;
}

MeshManager::MultiHandle MeshManager::instantiate_renderables(Scene &scene, MeshGroup *group)
{
	auto nodes = create_nodes(scene, group->node_hierarchy);

	MultiHandle handles = {};
	handles.root_node = create_root_node(scene, nodes, group->top_level_nodes);

	for (auto &node : group->node_hierarchy)
	{
		for (auto &mesh_index : node.meshes)
		{
			auto node_index = unsigned(&node - group->node_hierarchy.data());
			handles.entities.push_back(scene.create_renderable(group->renderables[mesh_index], nodes[node_index].get()));
		}
	}

	return handles;
}
}<commit_msg>Actually copy over node transforms in MeshManager.<commit_after>/* Copyright (c) 2017-2019 Hans-Kristian Arntzen
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "mesh_manager.hpp"
#include "gltf.hpp"
#include "mesh_util.hpp"
#include <stdexcept>

using namespace std;

namespace Granite
{
MeshManager::MeshGroup *MeshManager::register_mesh(const std::string &path)
{
	Util::Hasher hash;
	hash.string(path);

	MeshGroup *group = groups.find(hash.get());
	if (group)
		return group;

	group = groups.emplace_yield(hash.get());

	GLTF::Parser parser(path);
	if (parser.get_scenes().empty())
		throw logic_error("No scenes in glTF.");

	auto &scene = parser.get_scenes().front();
	group->top_level_nodes = scene.node_indices;
	group->node_hierarchy = parser.get_nodes();
	for (auto &mesh : parser.get_meshes())
		group->renderables.push_back(create_imported_mesh(mesh, parser.get_materials().data()));

	return group;
}

static std::vector<Scene::NodeHandle> create_nodes(Scene &scene, const std::vector<Granite::SceneFormats::Node> &nodes)
{
	vector<Scene::NodeHandle> scene_nodes(nodes.size());

	for (size_t i = 0; i < nodes.size(); i++)
	{
		auto &node_info = nodes[i];
		if (node_info.has_skin)
			throw logic_error("Skinning not yet supported for MeshManager.");

		auto node = scene.create_node();
		node->transform.translation = node_info.transform.translation;
		node->transform.rotation = node_info.transform.rotation;
		node->transform.scale = node_info.transform.scale;
		node->invalidate_cached_transform();
		scene_nodes[i] = move(node);
	}

	for (size_t i = 0; i < nodes.size(); i++)
	{
		auto &node_info = nodes[i];
		for (auto &child : node_info.children)
			scene_nodes[i]->add_child(scene_nodes[child]);
	}

	return scene_nodes;
}

static Scene::NodeHandle create_root_node(Scene &scene, const std::vector<Scene::NodeHandle> &nodes, const std::vector<uint32_t> &top_level_nodes)
{
	auto root = scene.create_node();
	for (auto &top_level : top_level_nodes)
		root->add_child(nodes[top_level]);
	return root;
}

MeshManager::SingleHandle MeshManager::instantiate_renderable(Scene &scene, MeshGroup *group)
{
	auto nodes = create_nodes(scene, group->node_hierarchy);

	SingleHandle handles = {};
	handles.root_node = create_root_node(scene, nodes, group->top_level_nodes);

	for (auto &node : group->node_hierarchy)
	{
		if (!node.meshes.empty())
		{
			unsigned mesh_index = node.meshes.front();
			auto node_index = unsigned(&node - group->node_hierarchy.data());
			handles.entity = scene.create_renderable(group->renderables[mesh_index], nodes[node_index].get());
			break;
		}
	}

	return handles;
}

MeshManager::MultiHandle MeshManager::instantiate_renderables(Scene &scene, MeshGroup *group)
{
	auto nodes = create_nodes(scene, group->node_hierarchy);

	MultiHandle handles = {};
	handles.root_node = create_root_node(scene, nodes, group->top_level_nodes);

	for (auto &node : group->node_hierarchy)
	{
		for (auto &mesh_index : node.meshes)
		{
			auto node_index = unsigned(&node - group->node_hierarchy.data());
			handles.entities.push_back(scene.create_renderable(group->renderables[mesh_index], nodes[node_index].get()));
		}
	}

	return handles;
}
}<|endoftext|>


<commit_before>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.
//
//      --------------------------------------------------------------
//      Field Interp Miniapp: Transfer a GridFunction from one mesh onto another
//      --------------------------------------------------------------
//
// This miniapp provides the capability to transfer a GridFunction
// (H1, L2, H(div), and H(curl)) from one mesh onto another using FindPointsGSLIB.
// Using FindPoints, we identify the nodal positions of the target mesh with
// respect to the source mesh and then interpolate the source GridFunction.
// The interpolated values are then projected onto the desired FiniteElementSpace
// on the target mesh. Finally, the transferred solution is visualized using GLVis.
//
// Compile with: make field-interp
//
// An H(div) function file is provided in this directory for a sample run.
// Other functions [H1, H(curl), and L2] can be generated using existing MFEM
// example codes in the "../../examples/" directory.
// Sample run:
//   field-interp
//   field-interp -ft 3
//   field-interp -m1 triple-pt-1.mesh -s1 triple-pt-1.gf -m2 triple-pt-2.mesh -ft 1

#include "mfem.hpp"
#include <fstream>

using namespace mfem;
using namespace std;

int main (int argc, char *argv[])
{
   // Set the method's default parameters.
   const char *src_mesh_file = "../meshing/square01.mesh";
   const char *tar_mesh_file = "../../data/inline-tri.mesh";
   const char *src_sltn_file = "square01_hdiv.gf";
   int order      = 3;
   int ref_levels = 0;
   int fieldtype  = -1;
   bool visualization = true;

   // Parse command-line options.
   OptionsParser args(argc, argv);
   args.AddOption(&src_mesh_file, "-m1", "--mesh1",
                  "Mesh file for the starting solution.");
   args.AddOption(&src_sltn_file, "-s1", "--solution1",
                  "Grid function for the starting solution.");
   args.AddOption(&tar_mesh_file, "-m2", "--mesh2",
                  "Mesh file for interpolation.");
   args.AddOption(&order, "-o", "--order",
                  "Order of the interpolated solution.");
   args.AddOption(&ref_levels, "-r", "--refine",
                  "Number of refinements of the interpolation mesh.");
   args.AddOption(&fieldtype, "-ft", "--field-type",
                  "Target GridFunction type: -1 - source GridFunction type (default),"
                  "0 - H1, 1 - L2, 2 - H(div), 3 - H(curl).");
   args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.Parse();
   if (!args.Good())
   {
      args.PrintUsage(cout);
      return 1;
   }
   args.PrintOptions(cout);

   // Input meshes.
   Mesh mesh_1(src_mesh_file, 1, 1, false);
   Mesh mesh_2(tar_mesh_file, 1, 1, false);
   const int dim = mesh_1.Dimension();
   MFEM_ASSERT(dim == mesh_2.Dimension(), "Source and target meshes "
               "must be in the same dimension.");
   MFEM_VERIFY(dim > 1, "GSLIB requires a 2D or a 3D mesh" );

   for (int lev = 0; lev < ref_levels; lev++)
   {
      mesh_2.UniformRefinement();
   }

   if (mesh_1.GetNodes() == NULL) { mesh_1.SetCurvature(1); }
   if (mesh_2.GetNodes() == NULL) { mesh_2.SetCurvature(1); }
   const int mesh_poly_deg = mesh_2.GetNodes()->FESpace()->GetOrder(0);
   cout << "Source mesh curvature: "
        << mesh_1.GetNodes()->OwnFEC()->Name() << endl
        << "Target mesh curvature: "
        << mesh_2.GetNodes()->OwnFEC()->Name() << endl;

   ifstream mat_stream_1(src_sltn_file);
   GridFunction func_source(&mesh_1, mat_stream_1);

   // Display the starting mesh and the field.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream sout1;
      sout1.open(vishost, visport);
      if (!sout1)
      {
         cout << "Unable to connect to GLVis server at "
              << vishost << ':' << visport << endl;
      }
      else
      {
         sout1.precision(8);
         sout1 << "solution\n" << mesh_1 << func_source
               << "window_title 'Source mesh and solution'"
               << "window_geometry 0 0 600 600";
         if (dim == 2) { sout1 << "keys RmjAc"; }
         if (dim == 3) { sout1 << "keys mA\n"; }
         sout1 << flush;
      }
   }

   const Geometry::Type gt = mesh_2.GetNodalFESpace()->GetFE(0)->GetGeomType();
   MFEM_VERIFY(gt != Geometry::PRISM, "Wedge elements are not currently "
               "supported.");

   // Ensure the source GridFunction can be transferred using FindPointsGSLIB.
   const FiniteElementCollection *fec_in = func_source.FESpace()->FEColl();
   std::cout << "Source FE collection: " << fec_in->Name() << std::endl;
   const int vdim_src   = func_source.FESpace()->GetVDim();
   int fieldtype_src = -1;
   {
      const H1_FECollection *fec_h1 = dynamic_cast<const H1_FECollection *>(fec_in);
      const L2_FECollection *fec_l2 = dynamic_cast<const L2_FECollection *>(fec_in);
      const RT_FECollection *fec_rt = dynamic_cast<const RT_FECollection *>(fec_in);
      const ND_FECollection *fec_nd = dynamic_cast<const ND_FECollection *>(fec_in);
      if (fec_h1)      { fieldtype_src = 0; }
      else if (fec_l2) { fieldtype_src = 1; }
      else if (fec_rt) { fieldtype_src = 2; }
      else if (fec_nd) { fieldtype_src = 3; }
      else { MFEM_ABORT("GridFunction type not supported yet."); }

      if (fieldtype_src <= 1 &&
          fec_h1->GetBasisType() != BasisType::GaussLobatto &&
          fec_h1->GetBasisType() != BasisType::GaussLegendre)
      {
         MFEM_ABORT("Only nodal basis are currently supported in this miniapp.");
      }
   }
   if (fieldtype == -1) { fieldtype = fieldtype_src; }

   // Setup the FiniteElementSpace and GridFunction on the target mesh.
   FiniteElementCollection *fec = NULL;
   FiniteElementSpace *fes = NULL;

   int vdim_tar = vdim_src;
   if (fieldtype == 0)
   {
      fec = new H1_FECollection(order, dim);
      vdim_tar = (fieldtype_src > 1) ? dim : vdim_src;
   }
   else if (fieldtype == 1)
   {
      fec = new L2_FECollection(order, dim);
      vdim_tar = (fieldtype_src > 1) ? dim : vdim_src;
   }
   else if (fieldtype == 2)
   {
      fec = new RT_FECollection(order, dim);
      vdim_tar = 1;
      MFEM_VERIFY(fieldtype_src > 1, "Cannot interpolate a scalar "
                  "GridFunction to a vector");

   }
   else if (fieldtype == 3)
   {
      fec = new ND_FECollection(order, dim);
      vdim_tar = 1;
      MFEM_VERIFY(fieldtype_src > 1, "Cannot interpolate a scalar "
                  "GridFunction to a vector");
   }
   else
   {
      MFEM_ABORT("GridFunction type not supported.");
   }
   std::cout << "Target FE collection: " << fec->Name() << std::endl;
   fes = new FiniteElementSpace(&mesh_2, fec, vdim_tar);
   GridFunction func_target(fes);

   const int NE = mesh_2.GetNE(),
             nsp = fes->GetFE(0)->GetNodes().GetNPoints(),
             ncomp_tar = func_target.VectorDim();

   // Generate list of points where the Gridfunction will be evaluated.
   Vector vxyz;
   if (fieldtype == 0 && order == mesh_poly_deg)
   {
      vxyz = *mesh_2.GetNodes();
   }
   else
   {
      vxyz.SetSize(nsp*NE*dim);
      for (int i = 0; i < NE; i++)
      {
         const FiniteElement *fe = fes->GetFE(i);
         const IntegrationRule ir = fe->GetNodes();
         ElementTransformation *et = fes->GetElementTransformation(i);

         DenseMatrix pos;
         et->Transform(ir, pos);
         Vector rowx(vxyz.GetData() + i*nsp, nsp),
                rowy(vxyz.GetData() + i*nsp + NE*nsp, nsp),
                rowz;
         if (dim == 3)
         {
            rowz.SetDataAndSize(vxyz.GetData() + i*nsp + 2*NE*nsp, nsp);
         }
         pos.GetRow(0, rowx);
         pos.GetRow(1, rowy);
         if (dim == 3) { pos.GetRow(2, rowz); }
      }
   }
   const int nodes_cnt = vxyz.Size() / dim;

   // Evaluate source gridfunction.
   Vector interp_vals(nodes_cnt*ncomp_tar);
   FindPointsGSLIB finder;
   finder.Setup(mesh_1);
   finder.Interpolate(vxyz, func_source, interp_vals);

   // Project the interpolated values to the target FiniteElementSpace.
   if (fieldtype <= 1) // H1 or L2
   {
      if ((fieldtype == 0 && order == mesh_poly_deg) || fieldtype == 1)
      {
         func_target = interp_vals;
      }
      else // H1 - but mesh order != GridFunction order
      {
         Array<int> vdofs;
         Vector vals;
         const int nsp = func_target.FESpace()->GetFE(0)->GetNodes().GetNPoints(),
                   NE  = mesh_2.GetNE();
         Vector elem_dof_vals(nsp*dim);

         for (int i = 0; i < mesh_2.GetNE(); i++)
         {
            fes->GetElementVDofs(i, vdofs);
            vals.SetSize(vdofs.Size());
            for (int j = 0; j < nsp; j++)
            {
               for (int d = 0; d < ncomp_tar; d++)
               {
                  // Arrange values byNodes
                  elem_dof_vals(j+d*nsp) = interp_vals(d*nsp*NE + i*nsp + j);
               }
            }
            func_target.SetSubVector(vdofs, elem_dof_vals);
         }
      }
   }
   else // H(div) or H(curl)
   {
      Array<int> vdofs;
      Vector vals;
      const int nsp = func_target.FESpace()->GetFE(0)->GetNodes().GetNPoints(),
                NE  = mesh_2.GetNE();
      Vector elem_dof_vals(nsp*dim);

      for (int i = 0; i < mesh_2.GetNE(); i++)
      {
         fes->GetElementVDofs(i, vdofs);
         vals.SetSize(vdofs.Size());
         for (int j = 0; j < nsp; j++)
         {
            for (int d = 0; d < ncomp_tar; d++)
            {
               // Arrange values byVDim
               elem_dof_vals(j*ncomp_tar+d) = interp_vals(d*nsp*NE + i*nsp + j);
            }
         }
         fes->GetFE(i)->ProjectFromNodes(elem_dof_vals,
                                         *fes->GetElementTransformation(i),
                                         vals);
         func_target.SetSubVector(vdofs, vals);
      }
   }

   // Visualize the transferred solution.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream sout1;
      sout1.open(vishost, visport);
      if (!sout1)
      {
         cout << "Unable to connect to GLVis server at "
              << vishost << ':' << visport << endl;
      }
      else
      {
         sout1.precision(8);
         sout1 << "solution\n" << mesh_2 << func_target
               << "window_title 'Target mesh and solution'"
               << "window_geometry 600 0 600 600";
         if (dim == 2) { sout1 << "keys RmjAc"; }
         if (dim == 3) { sout1 << "keys mA\n"; }
         sout1 << flush;
      }
   }

   // Output the target mesh with the interpolated solution.
   ostringstream rho_name;
   rho_name  << "interpolated.gf";
   ofstream rho_ofs(rho_name.str().c_str());
   rho_ofs.precision(8);
   func_target.Save(rho_ofs);
   rho_ofs.close();

   // Free the internal gslib data.
   finder.FreeData();

   // Delete
   delete fes;
   delete fec;

   return 0;
}
<commit_msg>AMR sample run.<commit_after>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.
//
//      --------------------------------------------------------------
//      Field Interp Miniapp: Transfer a GridFunction from one mesh onto another
//      --------------------------------------------------------------
//
// This miniapp provides the capability to transfer a GridFunction
// (H1, L2, H(div), and H(curl)) from one mesh onto another using FindPointsGSLIB.
// Using FindPoints, we identify the nodal positions of the target mesh with
// respect to the source mesh and then interpolate the source GridFunction.
// The interpolated values are then projected onto the desired FiniteElementSpace
// on the target mesh. Finally, the transferred solution is visualized using GLVis.
//
// Compile with: make field-interp
//
// An H(div) function file is provided in this directory for a sample run.
// Other functions [H1, H(curl), and L2] can be generated using existing MFEM
// example codes in the "../../examples/" directory.
//
// Sample run:
//   field-interp
//   field-interp -ft 3
//   field-interp -m1 triple-pt-1.mesh -s1 triple-pt-1.gf -m2 triple-pt-2.mesh -ft 1
//   field-interp -m2 ../meshing/amr-quad-q2.mesh -ft 0 -r 1

#include "mfem.hpp"
#include <fstream>

using namespace mfem;
using namespace std;

int main (int argc, char *argv[])
{
   // Set the method's default parameters.
   const char *src_mesh_file = "../meshing/square01.mesh";
   const char *tar_mesh_file = "../../data/inline-tri.mesh";
   const char *src_sltn_file = "square01_hdiv.gf";
   int order      = 3;
   int ref_levels = 0;
   int fieldtype  = -1;
   bool visualization = true;

   // Parse command-line options.
   OptionsParser args(argc, argv);
   args.AddOption(&src_mesh_file, "-m1", "--mesh1",
                  "Mesh file for the starting solution.");
   args.AddOption(&src_sltn_file, "-s1", "--solution1",
                  "Grid function for the starting solution.");
   args.AddOption(&tar_mesh_file, "-m2", "--mesh2",
                  "Mesh file for interpolation.");
   args.AddOption(&order, "-o", "--order",
                  "Order of the interpolated solution.");
   args.AddOption(&ref_levels, "-r", "--refine",
                  "Number of refinements of the interpolation mesh.");
   args.AddOption(&fieldtype, "-ft", "--field-type",
                  "Target GridFunction type: -1 - source GridFunction type (default),"
                  "0 - H1, 1 - L2, 2 - H(div), 3 - H(curl).");
   args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.Parse();
   if (!args.Good())
   {
      args.PrintUsage(cout);
      return 1;
   }
   args.PrintOptions(cout);

   // Input meshes.
   Mesh mesh_1(src_mesh_file, 1, 1, false);
   Mesh mesh_2(tar_mesh_file, 1, 1, false);
   const int dim = mesh_1.Dimension();
   MFEM_ASSERT(dim == mesh_2.Dimension(), "Source and target meshes "
               "must be in the same dimension.");
   MFEM_VERIFY(dim > 1, "GSLIB requires a 2D or a 3D mesh" );

   for (int lev = 0; lev < ref_levels; lev++)
   {
      mesh_2.UniformRefinement();
   }

   if (mesh_1.GetNodes() == NULL) { mesh_1.SetCurvature(1); }
   if (mesh_2.GetNodes() == NULL) { mesh_2.SetCurvature(1); }
   const int mesh_poly_deg = mesh_2.GetNodes()->FESpace()->GetOrder(0);
   cout << "Source mesh curvature: "
        << mesh_1.GetNodes()->OwnFEC()->Name() << endl
        << "Target mesh curvature: "
        << mesh_2.GetNodes()->OwnFEC()->Name() << endl;

   ifstream mat_stream_1(src_sltn_file);
   GridFunction func_source(&mesh_1, mat_stream_1);

   // Display the starting mesh and the field.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream sout1;
      sout1.open(vishost, visport);
      if (!sout1)
      {
         cout << "Unable to connect to GLVis server at "
              << vishost << ':' << visport << endl;
      }
      else
      {
         sout1.precision(8);
         sout1 << "solution\n" << mesh_1 << func_source
               << "window_title 'Source mesh and solution'"
               << "window_geometry 0 0 600 600";
         if (dim == 2) { sout1 << "keys RmjAc"; }
         if (dim == 3) { sout1 << "keys mA\n"; }
         sout1 << flush;
      }
   }

   const Geometry::Type gt = mesh_2.GetNodalFESpace()->GetFE(0)->GetGeomType();
   MFEM_VERIFY(gt != Geometry::PRISM, "Wedge elements are not currently "
               "supported.");

   // Ensure the source GridFunction can be transferred using FindPointsGSLIB.
   const FiniteElementCollection *fec_in = func_source.FESpace()->FEColl();
   std::cout << "Source FE collection: " << fec_in->Name() << std::endl;
   const int vdim_src   = func_source.FESpace()->GetVDim();
   int fieldtype_src = -1;
   {
      const H1_FECollection *fec_h1 = dynamic_cast<const H1_FECollection *>(fec_in);
      const L2_FECollection *fec_l2 = dynamic_cast<const L2_FECollection *>(fec_in);
      const RT_FECollection *fec_rt = dynamic_cast<const RT_FECollection *>(fec_in);
      const ND_FECollection *fec_nd = dynamic_cast<const ND_FECollection *>(fec_in);
      if (fec_h1)      { fieldtype_src = 0; }
      else if (fec_l2) { fieldtype_src = 1; }
      else if (fec_rt) { fieldtype_src = 2; }
      else if (fec_nd) { fieldtype_src = 3; }
      else { MFEM_ABORT("GridFunction type not supported yet."); }

      if (fieldtype_src <= 1 &&
          fec_h1->GetBasisType() != BasisType::GaussLobatto &&
          fec_h1->GetBasisType() != BasisType::GaussLegendre)
      {
         MFEM_ABORT("Only nodal basis are currently supported in this miniapp.");
      }
   }
   if (fieldtype == -1) { fieldtype = fieldtype_src; }

   // Setup the FiniteElementSpace and GridFunction on the target mesh.
   FiniteElementCollection *fec = NULL;
   FiniteElementSpace *fes = NULL;

   int vdim_tar = vdim_src;
   if (fieldtype == 0)
   {
      fec = new H1_FECollection(order, dim);
      vdim_tar = (fieldtype_src > 1) ? dim : vdim_src;
   }
   else if (fieldtype == 1)
   {
      fec = new L2_FECollection(order, dim);
      vdim_tar = (fieldtype_src > 1) ? dim : vdim_src;
   }
   else if (fieldtype == 2)
   {
      fec = new RT_FECollection(order, dim);
      vdim_tar = 1;
      MFEM_VERIFY(fieldtype_src > 1, "Cannot interpolate a scalar "
                  "GridFunction to a vector");

   }
   else if (fieldtype == 3)
   {
      fec = new ND_FECollection(order, dim);
      vdim_tar = 1;
      MFEM_VERIFY(fieldtype_src > 1, "Cannot interpolate a scalar "
                  "GridFunction to a vector");
   }
   else
   {
      MFEM_ABORT("GridFunction type not supported.");
   }
   std::cout << "Target FE collection: " << fec->Name() << std::endl;
   fes = new FiniteElementSpace(&mesh_2, fec, vdim_tar);
   GridFunction func_target(fes);

   const int NE = mesh_2.GetNE(),
             nsp = fes->GetFE(0)->GetNodes().GetNPoints(),
             ncomp_tar = func_target.VectorDim();

   // Generate list of points where the Gridfunction will be evaluated.
   Vector vxyz;
   if (fieldtype == 0 && order == mesh_poly_deg)
   {
      vxyz = *mesh_2.GetNodes();
   }
   else
   {
      vxyz.SetSize(nsp*NE*dim);
      for (int i = 0; i < NE; i++)
      {
         const FiniteElement *fe = fes->GetFE(i);
         const IntegrationRule ir = fe->GetNodes();
         ElementTransformation *et = fes->GetElementTransformation(i);

         DenseMatrix pos;
         et->Transform(ir, pos);
         Vector rowx(vxyz.GetData() + i*nsp, nsp),
                rowy(vxyz.GetData() + i*nsp + NE*nsp, nsp),
                rowz;
         if (dim == 3)
         {
            rowz.SetDataAndSize(vxyz.GetData() + i*nsp + 2*NE*nsp, nsp);
         }
         pos.GetRow(0, rowx);
         pos.GetRow(1, rowy);
         if (dim == 3) { pos.GetRow(2, rowz); }
      }
   }
   const int nodes_cnt = vxyz.Size() / dim;

   // Evaluate source gridfunction.
   Vector interp_vals(nodes_cnt*ncomp_tar);
   FindPointsGSLIB finder;
   finder.Setup(mesh_1);
   finder.Interpolate(vxyz, func_source, interp_vals);

   // Project the interpolated values to the target FiniteElementSpace.
   if (fieldtype <= 1) // H1 or L2
   {
      if ((fieldtype == 0 && order == mesh_poly_deg) || fieldtype == 1)
      {
         func_target = interp_vals;
      }
      else // H1 - but mesh order != GridFunction order
      {
         Array<int> vdofs;
         Vector vals;
         const int nsp = func_target.FESpace()->GetFE(0)->GetNodes().GetNPoints(),
                   NE  = mesh_2.GetNE();
         Vector elem_dof_vals(nsp*dim);

         for (int i = 0; i < mesh_2.GetNE(); i++)
         {
            fes->GetElementVDofs(i, vdofs);
            vals.SetSize(vdofs.Size());
            for (int j = 0; j < nsp; j++)
            {
               for (int d = 0; d < ncomp_tar; d++)
               {
                  // Arrange values byNodes
                  elem_dof_vals(j+d*nsp) = interp_vals(d*nsp*NE + i*nsp + j);
               }
            }
            func_target.SetSubVector(vdofs, elem_dof_vals);
         }
      }
   }
   else // H(div) or H(curl)
   {
      Array<int> vdofs;
      Vector vals;
      const int nsp = func_target.FESpace()->GetFE(0)->GetNodes().GetNPoints(),
                NE  = mesh_2.GetNE();
      Vector elem_dof_vals(nsp*dim);

      for (int i = 0; i < mesh_2.GetNE(); i++)
      {
         fes->GetElementVDofs(i, vdofs);
         vals.SetSize(vdofs.Size());
         for (int j = 0; j < nsp; j++)
         {
            for (int d = 0; d < ncomp_tar; d++)
            {
               // Arrange values byVDim
               elem_dof_vals(j*ncomp_tar+d) = interp_vals(d*nsp*NE + i*nsp + j);
            }
         }
         fes->GetFE(i)->ProjectFromNodes(elem_dof_vals,
                                         *fes->GetElementTransformation(i),
                                         vals);
         func_target.SetSubVector(vdofs, vals);
      }
   }

   // Visualize the transferred solution.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream sout1;
      sout1.open(vishost, visport);
      if (!sout1)
      {
         cout << "Unable to connect to GLVis server at "
              << vishost << ':' << visport << endl;
      }
      else
      {
         sout1.precision(8);
         sout1 << "solution\n" << mesh_2 << func_target
               << "window_title 'Target mesh and solution'"
               << "window_geometry 600 0 600 600";
         if (dim == 2) { sout1 << "keys RmjAc"; }
         if (dim == 3) { sout1 << "keys mA\n"; }
         sout1 << flush;
      }
   }

   // Output the target mesh with the interpolated solution.
   ostringstream rho_name;
   rho_name  << "interpolated.gf";
   ofstream rho_ofs(rho_name.str().c_str());
   rho_ofs.precision(8);
   func_target.Save(rho_ofs);
   rho_ofs.close();

   // Free the internal gslib data.
   finder.FreeData();

   // Delete
   delete fes;
   delete fec;

   return 0;
}
<|endoftext|>


<commit_before>#include <iostream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

class RenameRewriter : public clang::Rewriter
{
    std::string maOldName;
    std::string maNewName;

public:
    RenameRewriter(const std::string& rOldName, const std::string& rNewName)
        : maOldName(rOldName),
        maNewName(rNewName)
    {
    }

    const std::string& getOldName()
    {
        return maOldName;
    }

    const std::string& getNewName()
    {
        return maNewName;
    }
};

class RenameVisitor : public clang::RecursiveASTVisitor<RenameVisitor>
{
    RenameRewriter& mrRewriter;

public:
    explicit RenameVisitor(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    /*
     * class C
     * {
     * public:
     *     int nX; <- Handles this declaration.
     * };
     */
    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        // Qualified name includes "C::" as a prefix, normal name does not.
        std::string aName = pDecl->getQualifiedNameAsString();
        if (aName == mrRewriter.getOldName())
            mrRewriter.ReplaceText(pDecl->getLocation(), pDecl->getNameAsString().length(), mrRewriter.getNewName());
        return true;
    }

    /*
     * C::C()
     *     : nX(0) <- Handles this initializer.
     * {
     * }
     */
    bool VisitCXXConstructorDecl(clang::CXXConstructorDecl* pDecl)
    {
        for (clang::CXXConstructorDecl::init_const_iterator it = pDecl->init_begin(); it != pDecl->init_end(); ++it)
        {
            const clang::CXXCtorInitializer* pInitializer = *it;
            if (const clang::FieldDecl* pFieldDecl = pInitializer->getAnyMember())
            {
                std::string aName = pFieldDecl->getQualifiedNameAsString();
                if (aName == mrRewriter.getOldName())
                    mrRewriter.ReplaceText(pInitializer->getSourceLocation(), pFieldDecl->getNameAsString().length(), mrRewriter.getNewName());
            }
        }
        return true;
    }
};

class RenameASTConsumer : public clang::ASTConsumer
{
    RenameRewriter& mrRewriter;

public:
    RenameASTConsumer(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        RenameVisitor aVisitor(mrRewriter);
        mrRewriter.setSourceMgr(rContext.getSourceManager(), rContext.getLangOpts());
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        mrRewriter.getEditBuffer(rContext.getSourceManager().getMainFileID()).write(llvm::errs());
    }
};

class RenameFrontendAction
{
    RenameRewriter& mrRewriter;

public:
    RenameFrontendAction(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new RenameASTConsumer(mrRewriter);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("rename options");
    llvm::cl::opt<std::string> aOldName("old-name",
                                        llvm::cl::desc("Old name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aNewName("new-name",
                                        llvm::cl::desc("New name"),
                                        llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);
    if (aOldName.empty())
    {
        std::cerr << "no old name provided." << std::endl;
        return 1;
    }
    else if (aNewName.empty())
    {
        std::cerr << "no new name provided." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    RenameRewriter aRewriter(aOldName, aNewName);
    RenameFrontendAction aAction(aRewriter);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>clang: let rename handle clang::MemberExpr<commit_after>#include <iostream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

class RenameRewriter : public clang::Rewriter
{
    std::string maOldName;
    std::string maNewName;

public:
    RenameRewriter(const std::string& rOldName, const std::string& rNewName)
        : maOldName(rOldName),
        maNewName(rNewName)
    {
    }

    const std::string& getOldName()
    {
        return maOldName;
    }

    const std::string& getNewName()
    {
        return maNewName;
    }
};

class RenameVisitor : public clang::RecursiveASTVisitor<RenameVisitor>
{
    RenameRewriter& mrRewriter;

public:
    explicit RenameVisitor(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    /*
     * class C
     * {
     * public:
     *     int nX; <- Handles this declaration.
     * };
     */
    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        // Qualified name includes "C::" as a prefix, normal name does not.
        std::string aName = pDecl->getQualifiedNameAsString();
        if (aName == mrRewriter.getOldName())
            mrRewriter.ReplaceText(pDecl->getLocation(), pDecl->getNameAsString().length(), mrRewriter.getNewName());
        return true;
    }

    /*
     * C::C()
     *     : nX(0) <- Handles this initializer.
     * {
     * }
     */
    bool VisitCXXConstructorDecl(clang::CXXConstructorDecl* pDecl)
    {
        for (clang::CXXConstructorDecl::init_const_iterator it = pDecl->init_begin(); it != pDecl->init_end(); ++it)
        {
            const clang::CXXCtorInitializer* pInitializer = *it;
            if (const clang::FieldDecl* pFieldDecl = pInitializer->getAnyMember())
            {
                std::string aName = pFieldDecl->getQualifiedNameAsString();
                if (aName == mrRewriter.getOldName())
                    mrRewriter.ReplaceText(pInitializer->getSourceLocation(), pFieldDecl->getNameAsString().length(), mrRewriter.getNewName());
            }
        }
        return true;
    }

    /*
     * C aC;
     * aC.nX = 1; <- Handles e.g. this...
     * int y = aC.nX; <- ...and this.
     */
    bool VisitMemberExpr(clang::MemberExpr* pExpr)
    {
        if (clang::ValueDecl* pDecl = pExpr->getMemberDecl())
        {
            std::string aName = pDecl->getQualifiedNameAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pExpr->getMemberLoc(), pDecl->getNameAsString().length(), mrRewriter.getNewName());
        }
        return true;
    }
};

class RenameASTConsumer : public clang::ASTConsumer
{
    RenameRewriter& mrRewriter;

public:
    RenameASTConsumer(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        RenameVisitor aVisitor(mrRewriter);
        mrRewriter.setSourceMgr(rContext.getSourceManager(), rContext.getLangOpts());
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        mrRewriter.getEditBuffer(rContext.getSourceManager().getMainFileID()).write(llvm::errs());
    }
};

class RenameFrontendAction
{
    RenameRewriter& mrRewriter;

public:
    RenameFrontendAction(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new RenameASTConsumer(mrRewriter);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("rename options");
    llvm::cl::opt<std::string> aOldName("old-name",
                                        llvm::cl::desc("Old name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aNewName("new-name",
                                        llvm::cl::desc("New name"),
                                        llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);
    if (aOldName.empty())
    {
        std::cerr << "no old name provided." << std::endl;
        return 1;
    }
    else if (aNewName.empty())
    {
        std::cerr << "no new name provided." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    RenameRewriter aRewriter(aOldName, aNewName);
    RenameFrontendAction aAction(aRewriter);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include <iostream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

enum class RenameType
{
    Function,
    Field
};

class RenameRewriter : public clang::Rewriter
{
    std::string maOldName;
    std::string maNewName;
    RenameType meType;

public:
    RenameRewriter(const std::string& rOldName, const std::string& rNewName, const std::string& rType)
        : maOldName(rOldName),
        maNewName(rNewName)
    {
        if (rType == "function")
            meType = RenameType::Function;
        else if (rType == "field")
            meType = RenameType::Field;
    }

    const std::string& getOldName()
    {
        return maOldName;
    }

    const std::string& getNewName()
    {
        return maNewName;
    }

    RenameType getType()
    {
        return meType;
    }
};

class RenameVisitor : public clang::RecursiveASTVisitor<RenameVisitor>
{
    RenameRewriter& mrRewriter;

public:
    explicit RenameVisitor(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    bool VisitFunctionDecl(clang::FunctionDecl* pDecl)
    {
        if (mrRewriter.getType() == RenameType::Function)
        {
            std::string aName = pDecl->getNameInfo().getName().getAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pDecl->getLocation(), aName.length(), mrRewriter.getNewName());
        }
        return true;
    }

    bool VisitCallExpr(clang::CallExpr* pExpr)
    {
        if (mrRewriter.getType() == RenameType::Function)
        {
            const clang::FunctionDecl* pDecl = pExpr->getDirectCallee();
            if (!pDecl)
                return true;
            std::string aName = pDecl->getNameInfo().getName().getAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pExpr->getLocStart(), aName.length(), mrRewriter.getNewName());
        }
        return true;
    }

    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        if (mrRewriter.getType() == RenameType::Field)
        {
            // Qualified name includes "C::" as a prefix, normal name does not.
            std::string aName = pDecl->getQualifiedNameAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pDecl->getLocation(), pDecl->getNameAsString().length(), mrRewriter.getNewName());
        }
        return true;
    }
};

class RenameASTConsumer : public clang::ASTConsumer
{
    RenameRewriter& mrRewriter;

public:
    RenameASTConsumer(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        RenameVisitor aVisitor(mrRewriter);
        mrRewriter.setSourceMgr(rContext.getSourceManager(), rContext.getLangOpts());
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        mrRewriter.getEditBuffer(rContext.getSourceManager().getMainFileID()).write(llvm::errs());
    }
};

class RenameFrontendAction
{
    RenameRewriter& mrRewriter;

public:
    RenameFrontendAction(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new RenameASTConsumer(mrRewriter);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("rename options");
    llvm::cl::opt<std::string> aOldName("old-name",
                                        llvm::cl::desc("Old name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aNewName("new-name",
                                        llvm::cl::desc("New name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aType("type",
                                     llvm::cl::desc("Type (default: function, other possible value: field"),
                                     llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);
    if (aOldName.empty())
    {
        std::cerr << "no old name provided." << std::endl;
        return 1;
    }
    else if (aNewName.empty())
    {
        std::cerr << "no new name provided." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    RenameRewriter aRewriter(aOldName, aNewName, aType);
    RenameFrontendAction aAction(aRewriter);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>clang: handle ctor initializer<commit_after>#include <iostream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

enum class RenameType
{
    Function,
    Field
};

class RenameRewriter : public clang::Rewriter
{
    std::string maOldName;
    std::string maNewName;
    RenameType meType;

public:
    RenameRewriter(const std::string& rOldName, const std::string& rNewName, const std::string& rType)
        : maOldName(rOldName),
        maNewName(rNewName)
    {
        if (rType == "function")
            meType = RenameType::Function;
        else if (rType == "field")
            meType = RenameType::Field;
    }

    const std::string& getOldName()
    {
        return maOldName;
    }

    const std::string& getNewName()
    {
        return maNewName;
    }

    RenameType getType()
    {
        return meType;
    }
};

class RenameVisitor : public clang::RecursiveASTVisitor<RenameVisitor>
{
    RenameRewriter& mrRewriter;

public:
    explicit RenameVisitor(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    bool VisitFunctionDecl(clang::FunctionDecl* pDecl)
    {
        if (mrRewriter.getType() == RenameType::Function)
        {
            std::string aName = pDecl->getNameInfo().getName().getAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pDecl->getLocation(), aName.length(), mrRewriter.getNewName());
        }
        return true;
    }

    bool VisitCallExpr(clang::CallExpr* pExpr)
    {
        if (mrRewriter.getType() == RenameType::Function)
        {
            const clang::FunctionDecl* pDecl = pExpr->getDirectCallee();
            if (!pDecl)
                return true;
            std::string aName = pDecl->getNameInfo().getName().getAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pExpr->getLocStart(), aName.length(), mrRewriter.getNewName());
        }
        return true;
    }

    /*
     * class C
     * {
     * public:
     *     int nX; <- Handles this declaration.
     * };
     */
    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        if (mrRewriter.getType() == RenameType::Field)
        {
            // Qualified name includes "C::" as a prefix, normal name does not.
            std::string aName = pDecl->getQualifiedNameAsString();
            if (aName == mrRewriter.getOldName())
                mrRewriter.ReplaceText(pDecl->getLocation(), pDecl->getNameAsString().length(), mrRewriter.getNewName());
        }
        return true;
    }

    /*
     * C::C()
     *     : nX(0) <- Handles this initializer.
     * {
     * }
     */
    bool VisitCXXConstructorDecl(clang::CXXConstructorDecl* pDecl)
    {
        if (mrRewriter.getType() == RenameType::Field)
        {
            for (clang::CXXConstructorDecl::init_const_iterator it = pDecl->init_begin(); it != pDecl->init_end(); ++it)
            {
                const clang::CXXCtorInitializer* pInitializer = *it;
                if (const clang::FieldDecl* pFieldDecl = pInitializer->getAnyMember())
                {
                    std::string aName = pFieldDecl->getQualifiedNameAsString();
                    if (aName == mrRewriter.getOldName())
                        mrRewriter.ReplaceText(pInitializer->getSourceLocation(), pFieldDecl->getNameAsString().length(), mrRewriter.getNewName());
                }
            }
        }
        return true;
    }
};

class RenameASTConsumer : public clang::ASTConsumer
{
    RenameRewriter& mrRewriter;

public:
    RenameASTConsumer(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        RenameVisitor aVisitor(mrRewriter);
        mrRewriter.setSourceMgr(rContext.getSourceManager(), rContext.getLangOpts());
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        mrRewriter.getEditBuffer(rContext.getSourceManager().getMainFileID()).write(llvm::errs());
    }
};

class RenameFrontendAction
{
    RenameRewriter& mrRewriter;

public:
    RenameFrontendAction(RenameRewriter& rRewriter)
        : mrRewriter(rRewriter)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new RenameASTConsumer(mrRewriter);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("rename options");
    llvm::cl::opt<std::string> aOldName("old-name",
                                        llvm::cl::desc("Old name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aNewName("new-name",
                                        llvm::cl::desc("New name"),
                                        llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aType("type",
                                     llvm::cl::desc("Type (default: function, other possible value: field"),
                                     llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);
    if (aOldName.empty())
    {
        std::cerr << "no old name provided." << std::endl;
        return 1;
    }
    else if (aNewName.empty())
    {
        std::cerr << "no new name provided." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    RenameRewriter aRewriter(aOldName, aNewName, aType);
    RenameFrontendAction aAction(aRewriter);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>
// Library includes
#include <string>
#include <ostream>
#include <iostream>
#include <memory>

#include "grl/KukaFRI.hpp"
#include "grl/KukaFriClientData.hpp"
#include <boost/log/trivial.hpp>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <vector>
#include <iostream>

//
//template<typename T,typename V>
//inline T& printseq(T& out, V& v){
//    out << "[";
//    size_t last = v.size() - 1;
//    for(size_t i = 0; i < v.size(); ++i) {
//        out << v[i];
//        if (i != last)
//            out << ", ";
//    }
//    out << "]";
//    return out;
//}
//
//template<typename T,size_t N>
//inline boost::log::formatting_ostream& operator<< (boost::log::formatting_ostream& out, const boost::container::static_vector<T,N>& v) {
//  return printseq(out,v);
//}
//
//
//template<typename T,size_t N>
//ostream& operator<< (ostream& out, const boost::container::static_vector<T,N>& v) {
//  return printseq(out,v);
//}
//
//
//template<typename T>
//inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& out,  std::vector<T>& v)
//{
//    return printseq(out, v);
//}
//template<typename T>
//inline std::ostream& operator<<(std::ostream& out,  std::vector<T>& v)
//{
//    return printseq(out,v);
//}

using boost::asio::ip::udp;

#include <chrono>

/// @see https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time
template<typename TimeT = std::chrono::milliseconds>
struct periodic
{
    periodic():start(std::chrono::system_clock::now()){};

    template<typename F, typename ...Args>
    typename TimeT::rep execution(F func, Args&&... args)
    {
        auto duration = std::chrono::duration_cast< TimeT>
                            (std::chrono::system_clock::now() - start);
        auto count = duration.count();
        if(count > previous_count) func(std::forward<Args>(args)...);
        previous_count = count;
        return count;
    }

    std::chrono::time_point<std::chrono::system_clock> start;
    std::size_t previous_count;
};

enum { max_length = 1024 };

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

  periodic<> callIfMinPeriodPassed;

  try
  {
    std::string localhost("192.170.10.100");
    std::string localport("30200");
    std::string remotehost("192.170.10.2");
    std::string remoteport("30200");

    std::cout << "argc: " << argc << "\n";
	  /// @todo add default localhost/localport
    if (argc !=5 && argc !=1)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    if(argc ==5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
    }

      std::cout << "using: "  << argv[0] << " " <<  localhost << " " << localport << " " <<  remotehost << " " << remoteport << "\n";

    boost::asio::io_service io_service;

	std::shared_ptr<KUKA::FRI::ClientData> friData(std::make_shared<KUKA::FRI::ClientData>(7));
	std::chrono::time_point<std::chrono::high_resolution_clock> startTime;

    BOOST_VERIFY(friData);

    double delta = -0.0001;
    /// consider moving joint angles based on time
    int joint_to_move = 6;
    BOOST_LOG_TRIVIAL(warning) << "WARNING: YOU COULD DAMAGE OR DESTROY YOUR KUKA ROBOT "
                               << "if joint angle delta variable is too large with respect to "
                               << "the time it takes to go around the loop and change it. "
                               << "Current delta (radians/update): " << delta << " Joint to move: " << joint_to_move << "\n";

    std::vector<double> ipoJointPos(7,0);
    std::vector<double> offsetFromipoJointPos(7,0); // length 7, value 0
    std::vector<double> jointStateToCommand(7,0);

    grl::robot::arm::KukaFRIClientDataDriver driver(io_service,
        std::make_tuple(localhost,localport,remotehost,remoteport,grl::robot::arm::KukaFRIClientDataDriver::run_automatically)
    );

	for (std::size_t i = 0;;++i) {

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        /// perform the update step, receiving and sending data to/from the arm
        boost::system::error_code send_ec, recv_ec;
        std::size_t send_bytes_transferred = 0, recv_bytes_transferred = 0;
        bool haveNewData = !driver.update_state(friData, recv_ec, recv_bytes_transferred, send_ec, send_bytes_transferred);

        // if data didn't arrive correctly, skip and try again
        if(send_ec || recv_ec )
        {
           std::cout  << "receive error: " << recv_ec << "receive bytes: " << recv_bytes_transferred << " send error: " << send_ec << " send bytes: " << send_bytes_transferred <<  " iteration: "<< i << "\n";
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        // If we didn't receive anything new that is normal behavior,
        // but we can't process the new data so try updating again immediately.
        if(!haveNewData)
        {
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        if (grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState()) == KUKA::FRI::COMMANDING_ACTIVE)
        {
#if 1 // disabling this block causes the robot to simply sit in place, which seems to work correctly. Enabling it causes the joint to rotate.
            callIfMinPeriodPassed.execution( [&offsetFromipoJointPos,&delta,joint_to_move]()
            {
                    offsetFromipoJointPos[joint_to_move]+=delta;
                    // swap directions when a half circle was completed
                    if (
                         (offsetFromipoJointPos[joint_to_move] >  0.2 && delta > 0) ||
                         (offsetFromipoJointPos[joint_to_move] < -0.2 && delta < 0)
                       )
                    {
                       delta *=-1;
                    }
            });

#endif
        }

            KUKA::FRI::ESessionState sessionState = grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState());
        // copy current joint position to commanded position
        if (sessionState == KUKA::FRI::COMMANDING_WAIT || sessionState == KUKA::FRI::COMMANDING_ACTIVE)
        {
            boost::transform ( ipoJointPos, offsetFromipoJointPos, jointStateToCommand.begin(), std::plus<double>());
            grl::robot::arm::set(friData->commandMsg, jointStateToCommand, grl::revolute_joint_angle_open_chain_command_tag());
        }

        // vector addition between ipoJointPosition and ipoJointPositionOffsets, copying the result into jointStateToCommand
        /// @todo should we take the current joint state into consideration?

		//BOOST_LOG_TRIVIAL(trace) << "position: " << state.position << " us: " << std::chrono::duration_cast<std::chrono::microseconds>(state.timestamp - startTime).count() << " connectionQuality: " << state.connectionQuality << " operationMode: " << state.operationMode << " sessionState: " << state.sessionState << " driveState: " << state.driveState << " ipoJointPosition: " << state.ipoJointPosition << " ipoJointPositionOffsets: " << state.ipoJointPositionOffsets << "\n";
	}
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
<commit_msg>KukaFRIClientDataDriverTest improved periodic struct to make delay between updates configurable<commit_after>
// Library includes
#include <string>
#include <ostream>
#include <iostream>
#include <memory>

#include "grl/KukaFRI.hpp"
#include "grl/KukaFriClientData.hpp"
#include <boost/log/trivial.hpp>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <vector>
#include <iostream>

//
//template<typename T,typename V>
//inline T& printseq(T& out, V& v){
//    out << "[";
//    size_t last = v.size() - 1;
//    for(size_t i = 0; i < v.size(); ++i) {
//        out << v[i];
//        if (i != last)
//            out << ", ";
//    }
//    out << "]";
//    return out;
//}
//
//template<typename T,size_t N>
//inline boost::log::formatting_ostream& operator<< (boost::log::formatting_ostream& out, const boost::container::static_vector<T,N>& v) {
//  return printseq(out,v);
//}
//
//
//template<typename T,size_t N>
//ostream& operator<< (ostream& out, const boost::container::static_vector<T,N>& v) {
//  return printseq(out,v);
//}
//
//
//template<typename T>
//inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& out,  std::vector<T>& v)
//{
//    return printseq(out, v);
//}
//template<typename T>
//inline std::ostream& operator<<(std::ostream& out,  std::vector<T>& v)
//{
//    return printseq(out,v);
//}

using boost::asio::ip::udp;

#include <chrono>

/// @see https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time for the code I based this on
template<typename TimeT = std::chrono::milliseconds>
struct periodic
{
    periodic(TimeT duration = TimeT(1)):
    start(std::chrono::system_clock::now()),period_duration(duration.count()){};

    template<typename F, typename ...Args>
    typename TimeT::rep execution(F func, Args&&... args)
    {
        auto duration = std::chrono::duration_cast< TimeT>
                            (std::chrono::system_clock::now() - start);
        auto count = duration.count();
        if(count > previous_count + period_duration)
        {
            func(std::forward<Args>(args)...);
            previous_count = count;
        }
        return count;
    }

    std::chrono::time_point<std::chrono::system_clock> start;
    typename TimeT::rep period_duration;
    typename TimeT::rep previous_count;
};

enum { max_length = 1024 };

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

  periodic<> callIfMinPeriodPassed;

  try
  {
    std::string localhost("192.170.10.100");
    std::string localport("30200");
    std::string remotehost("192.170.10.2");
    std::string remoteport("30200");

    std::cout << "argc: " << argc << "\n";
	  /// @todo add default localhost/localport
    if (argc !=5 && argc !=1)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    if(argc ==5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
    }

      std::cout << "using: "  << argv[0] << " " <<  localhost << " " << localport << " " <<  remotehost << " " << remoteport << "\n";

    boost::asio::io_service io_service;

	std::shared_ptr<KUKA::FRI::ClientData> friData(std::make_shared<KUKA::FRI::ClientData>(7));
	std::chrono::time_point<std::chrono::high_resolution_clock> startTime;

    BOOST_VERIFY(friData);

    double delta = -0.0001;
    /// consider moving joint angles based on time
    int joint_to_move = 6;
    BOOST_LOG_TRIVIAL(warning) << "WARNING: YOU COULD DAMAGE OR DESTROY YOUR KUKA ROBOT "
                               << "if joint angle delta variable is too large with respect to "
                               << "the time it takes to go around the loop and change it. "
                               << "Current delta (radians/update): " << delta << " Joint to move: " << joint_to_move << "\n";

    std::vector<double> ipoJointPos(7,0);
    std::vector<double> offsetFromipoJointPos(7,0); // length 7, value 0
    std::vector<double> jointStateToCommand(7,0);

    grl::robot::arm::KukaFRIClientDataDriver driver(io_service,
        std::make_tuple(localhost,localport,remotehost,remoteport,grl::robot::arm::KukaFRIClientDataDriver::run_automatically)
    );

	for (std::size_t i = 0;;++i) {

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        /// perform the update step, receiving and sending data to/from the arm
        boost::system::error_code send_ec, recv_ec;
        std::size_t send_bytes_transferred = 0, recv_bytes_transferred = 0;
        bool haveNewData = !driver.update_state(friData, recv_ec, recv_bytes_transferred, send_ec, send_bytes_transferred);

        // if data didn't arrive correctly, skip and try again
        if(send_ec || recv_ec )
        {
           std::cout  << "receive error: " << recv_ec << "receive bytes: " << recv_bytes_transferred << " send error: " << send_ec << " send bytes: " << send_bytes_transferred <<  " iteration: "<< i << "\n";
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        // If we didn't receive anything new that is normal behavior,
        // but we can't process the new data so try updating again immediately.
        if(!haveNewData)
        {
           std::this_thread::sleep_for(std::chrono::milliseconds(1));
           continue;
        }

        /// use the interpolated joint position from the previous update as the base
        /// @todo why is this?
        if(i!=0 && friData) grl::robot::arm::copy(friData->monitoringMsg,ipoJointPos.begin(),grl::revolute_joint_angle_interpolated_open_chain_state_tag());

        if (grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState()) == KUKA::FRI::COMMANDING_ACTIVE)
        {
#if 1 // disabling this block causes the robot to simply sit in place, which seems to work correctly. Enabling it causes the joint to rotate.
            callIfMinPeriodPassed.execution( [&offsetFromipoJointPos,&delta,joint_to_move]()
            {
                    offsetFromipoJointPos[joint_to_move]+=delta;
                    // swap directions when a half circle was completed
                    if (
                         (offsetFromipoJointPos[joint_to_move] >  0.2 && delta > 0) ||
                         (offsetFromipoJointPos[joint_to_move] < -0.2 && delta < 0)
                       )
                    {
                       delta *=-1;
                    }
            });

#endif
        }

            KUKA::FRI::ESessionState sessionState = grl::robot::arm::get(friData->monitoringMsg,KUKA::FRI::ESessionState());
        // copy current joint position to commanded position
        if (sessionState == KUKA::FRI::COMMANDING_WAIT || sessionState == KUKA::FRI::COMMANDING_ACTIVE)
        {
            boost::transform ( ipoJointPos, offsetFromipoJointPos, jointStateToCommand.begin(), std::plus<double>());
            grl::robot::arm::set(friData->commandMsg, jointStateToCommand, grl::revolute_joint_angle_open_chain_command_tag());
        }

        // vector addition between ipoJointPosition and ipoJointPositionOffsets, copying the result into jointStateToCommand
        /// @todo should we take the current joint state into consideration?

		//BOOST_LOG_TRIVIAL(trace) << "position: " << state.position << " us: " << std::chrono::duration_cast<std::chrono::microseconds>(state.timestamp - startTime).count() << " connectionQuality: " << state.connectionQuality << " operationMode: " << state.operationMode << " sessionState: " << state.sessionState << " driveState: " << state.driveState << " ipoJointPosition: " << state.ipoJointPosition << " ipoJointPositionOffsets: " << state.ipoJointPositionOffsets << "\n";
	}
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
<|endoftext|>