<commit_before>#include <unistd.h>
#include <string>
#include <iostream>
#include "coreclrutil.h"

namespace Cmdline
{
    void printHelp()
    {
        std::cerr << "PowerShell on Linux native host" << std::endl
                  << "Usage: powershell [assembly] [...]" << std::endl
                  << std::endl
                  << "What it does:" << std::endl
                  << "- the host assumes that CoreCLR is located $CORE_ROOT," << std::endl
                  << "  else in lib/coreclr"
                  << "- the host assumes that the assembly named" << std::endl
                  << "  Microsoft.PowerShell.CoreCLR.AssemblyLoadContext is " << std::endl
                  << "  located in $PWRSH_ROOT, else in lib/powershell" << std::endl
                  << "- the host will launch $PWRSH_ROOT/powershell.exe" << std::endl
                  << "  if not given an explicit assembly.exe" << std::endl
                  << "- all additional parameters at the end of the command line are forwarded" << std::endl
                  << "  to the Main function in the assembly" << std::endl
                  << "- the host will execute the Main function in the specified assembly" << std::endl
                  << std::endl
                  << "Example:" << std::endl
                  << "CORE_ROOT=/test/coreclr PWRSH_ROOT=/test/powershell ./powershell get-process" << std::endl;
    }

    struct Args
    {
        Args() :
            argc(0),
            argv(nullptr),
            assembly()
        {
        }

        int argc;
        char** argv;
        std::string assembly;
    };

    // checks if string ends with ".exe"
    bool isExe(std::string arg)
    {
        std::size_t dot = arg.find_last_of(".");
        return dot == std::string::npos ? false : arg.substr(dot) == ".exe";
    }

    // simple extraction of assembly.exe so we can run other hosts
    void parseCmdline(int argc, char** argv, Args& args)
    {
        // index of arguments to forward (skip zeroth)
        int i = 1;
        // if we have any arguments
        if (argc > 1)
        {
            // check if the first is an assembly.exe
            const std::string arg = argv[i];
            if (isExe(arg))
            {
                args.assembly.assign(arg);
                ++i; // don't forward the first argument
            }
        }
        // forward arguments
        args.argc = argc - i;
        args.argv = &argv[i];
    }
}

int main(int argc, char** argv)
{
    Cmdline::Args args;
    Cmdline::parseCmdline(argc, argv, args);

    void* hostHandle;
    unsigned int domainId;
    int status = startCoreCLR(
        "ps_cmdline_host",
        &hostHandle,
        &domainId);

    if (!SUCCEEDED(status))
    {
        std::cerr << "could not start CoreCLR" << std::endl;
        return -1;
    }

    // default to powershell.exe if no host specified
    if (args.assembly.empty())
    {
        args.assembly.assign(pwrshPath);
        args.assembly.append("/");
        args.assembly.append("powershell.exe");
    }

    // call into Main of assembly
    unsigned int exitCode;
    executeAssembly(
        hostHandle, domainId, args.argc,
        (const char**)args.argv,
        args.assembly.c_str(),
        &exitCode);

    status = stopCoreCLR(hostHandle, domainId);
    if (!SUCCEEDED(status))
    {
        std::cerr << "could not stop CoreCLR" << std::endl;
        return -1;
    }

    return exitCode;
}
<commit_msg>Rename appDomainFriendlyName to psl_cmdline_host<commit_after>#include <unistd.h>
#include <string>
#include <iostream>
#include "coreclrutil.h"

namespace Cmdline
{
    void printHelp()
    {
        std::cerr << "PowerShell on Linux native host" << std::endl
                  << "Usage: powershell [assembly] [...]" << std::endl
                  << std::endl
                  << "What it does:" << std::endl
                  << "- the host assumes that CoreCLR is located $CORE_ROOT," << std::endl
                  << "  else in lib/coreclr"
                  << "- the host assumes that the assembly named" << std::endl
                  << "  Microsoft.PowerShell.CoreCLR.AssemblyLoadContext is " << std::endl
                  << "  located in $PWRSH_ROOT, else in lib/powershell" << std::endl
                  << "- the host will launch $PWRSH_ROOT/powershell.exe" << std::endl
                  << "  if not given an explicit assembly.exe" << std::endl
                  << "- all additional parameters at the end of the command line are forwarded" << std::endl
                  << "  to the Main function in the assembly" << std::endl
                  << "- the host will execute the Main function in the specified assembly" << std::endl
                  << std::endl
                  << "Example:" << std::endl
                  << "CORE_ROOT=/test/coreclr PWRSH_ROOT=/test/powershell ./powershell get-process" << std::endl;
    }

    struct Args
    {
        Args() :
            argc(0),
            argv(nullptr),
            assembly()
        {
        }

        int argc;
        char** argv;
        std::string assembly;
    };

    // checks if string ends with ".exe"
    bool isExe(std::string arg)
    {
        std::size_t dot = arg.find_last_of(".");
        return dot == std::string::npos ? false : arg.substr(dot) == ".exe";
    }

    // simple extraction of assembly.exe so we can run other hosts
    void parseCmdline(int argc, char** argv, Args& args)
    {
        // index of arguments to forward (skip zeroth)
        int i = 1;
        // if we have any arguments
        if (argc > 1)
        {
            // check if the first is an assembly.exe
            const std::string arg = argv[i];
            if (isExe(arg))
            {
                args.assembly.assign(arg);
                ++i; // don't forward the first argument
            }
        }
        // forward arguments
        args.argc = argc - i;
        args.argv = &argv[i];
    }
}

int main(int argc, char** argv)
{
    Cmdline::Args args;
    Cmdline::parseCmdline(argc, argv, args);

    void* hostHandle;
    unsigned int domainId;
    int status = startCoreCLR(
        "psl_cmdline_host",
        &hostHandle,
        &domainId);

    if (!SUCCEEDED(status))
    {
        std::cerr << "could not start CoreCLR" << std::endl;
        return -1;
    }

    // default to powershell.exe if no host specified
    if (args.assembly.empty())
    {
        args.assembly.assign(pwrshPath);
        args.assembly.append("/");
        args.assembly.append("powershell.exe");
    }

    // call into Main of assembly
    unsigned int exitCode;
    executeAssembly(
        hostHandle, domainId, args.argc,
        (const char**)args.argv,
        args.assembly.c_str(),
        &exitCode);

    status = stopCoreCLR(hostHandle, domainId);
    if (!SUCCEEDED(status))
    {
        std::cerr << "could not stop CoreCLR" << std::endl;
        return -1;
    }

    return exitCode;
}
<|endoftext|>


<commit_before>#ifndef TYPES_H
#define TYPES_H
/*
Defines a set of types for use on the hl-side.
*/

#include<cstring>
#include"objects.hpp"
#include"generics.hpp"
#include"heaps.hpp"

/*-----------------------------------------------------------------------------
Specialized broken heart tags
-----------------------------------------------------------------------------*/

/*The BrokenHeartFor classes are specialized for each
generic-derived class.  They should *not* add any
storage.
*/
template<class T>
class BrokenHeartFor : public BrokenHeart {
private:
	// disallowed
	BrokenHeartFor<T>();
	BrokenHeartFor<T>(BrokenHeartFor<T> const&);
public:
	virtual size_t real_size(void) const {
		return compute_size<T>();
	}
	explicit BrokenHeartFor<T>(Generic* x) : BrokenHeart(x) { }
};

template<class T>
class BrokenHeartForVariadic : public BrokenHeartVariadic {
private:
	// disallowed
	BrokenHeartForVariadic<T>();
	BrokenHeartForVariadic<T>(BrokenHeartForVariadic<T> const&);
public:
	virtual size_t real_size(void) const {
		return compute_size_variadic<T>(sz);
	}
	BrokenHeartForVariadic<T>(Generic* x, size_t nsz)
		: BrokenHeartVariadic(x, nsz) { }
};

/*-----------------------------------------------------------------------------
Base classes for Generic-derived objects
-----------------------------------------------------------------------------*/

template<class T>
class GenericDerived : public Generic {
protected:
	GenericDerived<T>(void) { }
public:
	virtual size_t real_size(void) const {
		return compute_size<T>();
	}
	virtual Generic* clone(Semispace* nsp) const {
		void* pt = nsp->alloc(real_size());
		try {
			new(pt) T(*static_cast<T const*>(this));
			return (Generic*) pt;
		} catch(...) {
			nsp->dealloc(pt);
			throw;
		}
	}
	virtual void break_heart(Generic* to) {
		Generic* gp = this;
		gp->~Generic();
		new((void*) gp) BrokenHeartFor<T>(to);
	};
};

/*This class implements a variable-size object by informing the
memory system to reserve extra space.
Note that classes which derive from this should provide
a factory function!
*/
template<class T>
class GenericDerivedVariadic : public Generic {
	GenericDerivedVariadic<T>(void); // disallowed!
protected:
	/*number of extra Object::ref's*/
	size_t sz;
	/*used by the derived classes to get access to
	the variadic data at the end of the object.
	*/
	inline Object::ref& index(size_t i) const {
		void* vp = const_cast<GenericDerivedVariadic<T>*>(this);
		char* cp = (char*) vp;
		cp = cp + sizeof(T);
		Object::ref* op = (Object::ref*) cp;
		return op[i];
	}
	explicit GenericDerivedVariadic<T>(size_t nsz) : sz(nsz) {
		/*clear the extra references*/
		for(size_t i; i < nsz; ++i) {
			index(i) = Object::nil();
		}
	}
	GenericDerivedVariadic<T>(GenericDerivedVariadic<T> const& o)
		: sz(o.sz) {
		for(size_t i; i < sz; ++i) {
			index(i) = o.index(i);
		}
	}
public:
	virtual size_t real_size(void) const {
		return compute_size_variadic<T>(sz);
	}
	virtual Generic* clone(Semispace* nsp) const {
		void* pt = nsp->alloc(real_size());
		try {
			new(pt) T(*static_cast<T const*>(this));
			return (Generic*) pt;
		} catch(...) {
			nsp->dealloc(pt);
			throw;
		}
	}
	virtual void break_heart(Generic *to) {
		Generic* gp = this;
		size_t nsz = sz; //save this before dtoring!
		gp->~Generic();
		new((void*) gp) BrokenHeartForVariadic<T>(to, nsz);
	}
        virtual size_t size() {
                return sz;
        }
};

/*-----------------------------------------------------------------------------
Utility
-----------------------------------------------------------------------------*/

void throw_HlError(char const*);

/*Usage:
Cons* cp = expect_type<Cons>(proc.stack().top(),
		"Your mom expects a Cons cell on top"
);
*/
template<class T>
static inline T* expect_type(Object::ref x, char const* error) {
	if(!is_a<Generic*>(x)) throw_HlError(error);
	T* tmp = dynamic_cast<T*>(as_a<Generic*>(x));
	if(!tmp) throw_HlError(error);
	return tmp;
}

/*
 * Cons cell
 */

class Cons : public GenericDerived<Cons> {
private:

  Object::ref car_ref;
  Object::ref cdr_ref;

public:

  inline Object::ref car() { return car_ref; }
  inline Object::ref cdr() { return cdr_ref; }
  inline Object::ref scar(Object::ref x) { return car_ref = x; }
  inline Object::ref scdr(Object::ref x) { return cdr_ref = x; }

  Cons() : car_ref(Object::nil()), cdr_ref(Object::nil()) {}
  /*
   * Note that we *can't* safely construct any heap-based objects
   * by, say, passing them any of their data.  This is because the
   * act of allocating space for these objects may start a garbage
   * collection, which can move *other* objects.  So any references
   * passed into the constructor will be invalid; instead, the
   * process must save the data to be put in the new object in a
   * root location (such as the process stack) and after it is
   * given the newly-constructed object, it must store the data
   * straight from the root location.
   */

  void traverse_references(GenericTraverser *gt) {
    gt->traverse(car_ref);
    gt->traverse(cdr_ref);
  }
};

extern inline Object::ref car(Object::ref x) {
	if(!x) return x;
        return expect_type<Cons>(x,"'car expects a Cons cell")->car();
}
extern inline Object::ref cdr(Object::ref x) {
	if(!x) return x;
	return expect_type<Cons>(x,"'cdr expects a Cons cell")->cdr();
}
extern inline Object::ref scar(Object::ref c, Object::ref v) {
	return expect_type<Cons>(c,"'scar expects a true Cons cell")->scar(v);
}
extern inline Object::ref scdr(Object::ref c, Object::ref v) {
	return expect_type<Cons>(c,"'scdr expects a true Cons cell")->scdr(v);
}

/*-----------------------------------------------------------------------------
HlPid
-----------------------------------------------------------------------------*/
/*Represents a process that can
be sent messages to by this process
*/

class Process;

class HlPid : public GenericDerived<HlPid> {
public:
	Process* process;
};

/*-----------------------------------------------------------------------------
Closures
-----------------------------------------------------------------------------*/

struct bytecode_t;

/*Closure
*/
class Closure : public GenericDerivedVariadic<Closure> {
private:
  bytecode_t* body;
  bool nonreusable;
  bool kontinuation;
public:
  Closure(size_t sz) : GenericDerivedVariadic<Closure>(sz),
                       nonreusable(true) {}
  Object::ref& operator[](size_t i) {
    if (i < size())
      return index(i);
    else
      throw_HlError("internal: trying to access closed vars with an index too large!");
  }
  bytecode_t* code() { return body; }
  void codereset(bytecode_t *b) { body = b; }
  void banreuse() { nonreusable = true; }
  bool reusable() { return !nonreusable; }
  static Closure* NewKClosure(Heap & h, bytecode_t *body, size_t n);
  static Closure* NewClosure(Heap & h, bytecode_t *body, size_t n);

  void traverse_references(GenericTraverser *gt) {
    for(size_t i = 0; i < sz; ++i) {
      gt->traverse(index(i));
    }
  }
};

#endif //TYPES_H
<commit_msg>inc/types.hpp: Changed Closure::banreuse() to work on all continuations<commit_after>#ifndef TYPES_H
#define TYPES_H
/*
Defines a set of types for use on the hl-side.
*/

#include<cstring>
#include"objects.hpp"
#include"generics.hpp"
#include"heaps.hpp"

/*-----------------------------------------------------------------------------
Specialized broken heart tags
-----------------------------------------------------------------------------*/

/*The BrokenHeartFor classes are specialized for each
generic-derived class.  They should *not* add any
storage.
*/
template<class T>
class BrokenHeartFor : public BrokenHeart {
private:
	// disallowed
	BrokenHeartFor<T>();
	BrokenHeartFor<T>(BrokenHeartFor<T> const&);
public:
	virtual size_t real_size(void) const {
		return compute_size<T>();
	}
	explicit BrokenHeartFor<T>(Generic* x) : BrokenHeart(x) { }
};

template<class T>
class BrokenHeartForVariadic : public BrokenHeartVariadic {
private:
	// disallowed
	BrokenHeartForVariadic<T>();
	BrokenHeartForVariadic<T>(BrokenHeartForVariadic<T> const&);
public:
	virtual size_t real_size(void) const {
		return compute_size_variadic<T>(sz);
	}
	BrokenHeartForVariadic<T>(Generic* x, size_t nsz)
		: BrokenHeartVariadic(x, nsz) { }
};

/*-----------------------------------------------------------------------------
Base classes for Generic-derived objects
-----------------------------------------------------------------------------*/

template<class T>
class GenericDerived : public Generic {
protected:
	GenericDerived<T>(void) { }
public:
	virtual size_t real_size(void) const {
		return compute_size<T>();
	}
	virtual Generic* clone(Semispace* nsp) const {
		void* pt = nsp->alloc(real_size());
		try {
			new(pt) T(*static_cast<T const*>(this));
			return (Generic*) pt;
		} catch(...) {
			nsp->dealloc(pt);
			throw;
		}
	}
	virtual void break_heart(Generic* to) {
		Generic* gp = this;
		gp->~Generic();
		new((void*) gp) BrokenHeartFor<T>(to);
	};
};

/*This class implements a variable-size object by informing the
memory system to reserve extra space.
Note that classes which derive from this should provide
a factory function!
*/
template<class T>
class GenericDerivedVariadic : public Generic {
	GenericDerivedVariadic<T>(void); // disallowed!
protected:
	/*number of extra Object::ref's*/
	size_t sz;
	/*used by the derived classes to get access to
	the variadic data at the end of the object.
	*/
	inline Object::ref& index(size_t i) const {
		void* vp = const_cast<GenericDerivedVariadic<T>*>(this);
		char* cp = (char*) vp;
		cp = cp + sizeof(T);
		Object::ref* op = (Object::ref*) cp;
		return op[i];
	}
	explicit GenericDerivedVariadic<T>(size_t nsz) : sz(nsz) {
		/*clear the extra references*/
		for(size_t i; i < nsz; ++i) {
			index(i) = Object::nil();
		}
	}
	GenericDerivedVariadic<T>(GenericDerivedVariadic<T> const& o)
		: sz(o.sz) {
		for(size_t i; i < sz; ++i) {
			index(i) = o.index(i);
		}
	}
public:
	virtual size_t real_size(void) const {
		return compute_size_variadic<T>(sz);
	}
	virtual Generic* clone(Semispace* nsp) const {
		void* pt = nsp->alloc(real_size());
		try {
			new(pt) T(*static_cast<T const*>(this));
			return (Generic*) pt;
		} catch(...) {
			nsp->dealloc(pt);
			throw;
		}
	}
	virtual void break_heart(Generic *to) {
		Generic* gp = this;
		size_t nsz = sz; //save this before dtoring!
		gp->~Generic();
		new((void*) gp) BrokenHeartForVariadic<T>(to, nsz);
	}
        virtual size_t size() {
                return sz;
        }
};

/*-----------------------------------------------------------------------------
Utility
-----------------------------------------------------------------------------*/

void throw_HlError(char const*);

/*Usage:
Cons* cp = expect_type<Cons>(proc.stack().top(),
		"Your mom expects a Cons cell on top"
);
*/
template<class T>
static inline T* expect_type(Object::ref x, char const* error) {
	if(!is_a<Generic*>(x)) throw_HlError(error);
	T* tmp = dynamic_cast<T*>(as_a<Generic*>(x));
	if(!tmp) throw_HlError(error);
	return tmp;
}

/*
 * Cons cell
 */

class Cons : public GenericDerived<Cons> {
private:

  Object::ref car_ref;
  Object::ref cdr_ref;

public:

  inline Object::ref car() { return car_ref; }
  inline Object::ref cdr() { return cdr_ref; }
  inline Object::ref scar(Object::ref x) { return car_ref = x; }
  inline Object::ref scdr(Object::ref x) { return cdr_ref = x; }

  Cons() : car_ref(Object::nil()), cdr_ref(Object::nil()) {}
  /*
   * Note that we *can't* safely construct any heap-based objects
   * by, say, passing them any of their data.  This is because the
   * act of allocating space for these objects may start a garbage
   * collection, which can move *other* objects.  So any references
   * passed into the constructor will be invalid; instead, the
   * process must save the data to be put in the new object in a
   * root location (such as the process stack) and after it is
   * given the newly-constructed object, it must store the data
   * straight from the root location.
   */

  void traverse_references(GenericTraverser *gt) {
    gt->traverse(car_ref);
    gt->traverse(cdr_ref);
  }
};

extern inline Object::ref car(Object::ref x) {
	if(!x) return x;
        return expect_type<Cons>(x,"'car expects a Cons cell")->car();
}
extern inline Object::ref cdr(Object::ref x) {
	if(!x) return x;
	return expect_type<Cons>(x,"'cdr expects a Cons cell")->cdr();
}
extern inline Object::ref scar(Object::ref c, Object::ref v) {
	return expect_type<Cons>(c,"'scar expects a true Cons cell")->scar(v);
}
extern inline Object::ref scdr(Object::ref c, Object::ref v) {
	return expect_type<Cons>(c,"'scdr expects a true Cons cell")->scdr(v);
}

/*-----------------------------------------------------------------------------
HlPid
-----------------------------------------------------------------------------*/
/*Represents a process that can
be sent messages to by this process
*/

class Process;

class HlPid : public GenericDerived<HlPid> {
public:
	Process* process;
};

/*-----------------------------------------------------------------------------
Closures
-----------------------------------------------------------------------------*/

struct bytecode_t;

/*Closure
*/
class Closure : public GenericDerivedVariadic<Closure> {
private:
  bytecode_t* body;
  bool nonreusable;
  bool kontinuation;
public:
  Closure(size_t sz) : GenericDerivedVariadic<Closure>(sz),
                       nonreusable(true) {}
  Object::ref& operator[](size_t i) {
    if (i < size())
      return index(i);
    else
      throw_HlError("internal: trying to access closed vars with an index too large!");
  }
  bytecode_t* code() { return body; }
  void codereset(bytecode_t *b) { body = b; }
  void banreuse() {
    /*ban reuse for this and for every other continuation referred to*/
    Closure* kp = this;
    if(kp) {
    loop:
      kp->nonreusable = true;
      for(size_t i; i < kp->sz; ++i) {
        Object::ref tmp = kp->index(i);
        if(is_a<Generic*>(tmp)) {
          Closure* cp = dynamic_cast<Closure*>(as_a<Generic*>(tmp));
          if(cp && cp->kontinuation) {
            /*assume only one continuation is actually referred to
            directly (this is what the compiler emits anyway)
            */
            kp = cp;
            goto loop;
          }
        }
      }
    }
  }
  bool reusable() { return !nonreusable; }
  static Closure* NewKClosure(Heap & h, bytecode_t *body, size_t n);
  static Closure* NewClosure(Heap & h, bytecode_t *body, size_t n);

  void traverse_references(GenericTraverser *gt) {
    for(size_t i = 0; i < sz; ++i) {
      gt->traverse(index(i));
    }
  }
};

#endif //TYPES_H
<|endoftext|>


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

/* Author: Ioan Sucan */

#include <gtest/gtest.h>
#include <moveit/planning_scene/planning_scene.h>
#include <urdf_parser/urdf_parser.h>
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <ros/package.h>

// This function needs to return void so the gtest FAIL() macro inside
// it works right.
void loadRobotModel(boost::shared_ptr<urdf::ModelInterface>& robot_model_out)
{
  std::string resource_dir = ros::package::getPath("moveit_resources");
  if(resource_dir == "")
  {
    FAIL() << "Failed to find package moveit_resources.";
    return;
  }
  boost::filesystem::path res_path(resource_dir);

  std::string xml_string;
  std::fstream xml_file((res_path / "test/urdf/robot.xml").string().c_str(), std::fstream::in);
  EXPECT_TRUE(xml_file.is_open());
  while ( xml_file.good() )
  {
    std::string line;
    std::getline( xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();
  robot_model_out = urdf::parseURDF(xml_string);
}

TEST(PlanningScene, LoadRestore)
{
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());
  planning_scene::PlanningScene ps(urdf_model, srdf_model);
  moveit_msgs::PlanningScene ps_msg;
  ps.getPlanningSceneMsg(ps_msg);
  ps.setPlanningSceneMsg(ps_msg);
}

TEST(PlanningScene, LoadRestoreDiff)
{
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World &world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  moveit_msgs::PlanningScene ps_msg;
  EXPECT_TRUE(planning_scene::PlanningScene::isEmpty(ps_msg));
  ps->getPlanningSceneMsg(ps_msg);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_FALSE(planning_scene::PlanningScene::isEmpty(ps_msg));
  EXPECT_TRUE(world.hasObject("sphere"));

  planning_scene::PlanningScenePtr next = ps->diff();
  EXPECT_TRUE(next->getWorld()->hasObject("sphere"));
  next->getWorldNonConst()->addToObject("sphere2", shapes::ShapeConstPtr(new shapes::Sphere(0.5)), id);
  EXPECT_EQ(next->getWorld()->size(), 2);
  EXPECT_EQ(ps->getWorld()->size(), 1);
  next->getPlanningSceneDiffMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 1);
  next->decoupleParent();
  moveit_msgs::PlanningScene ps_msg2;
  next->getPlanningSceneDiffMsg(ps_msg2);
  EXPECT_EQ(ps_msg2.world.collision_objects.size(), 0);
  next->getPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 2);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps->getWorld()->size(), 2);
}

TEST(PlanningScene, MakeAttachedDiff)
{
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World &world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  planning_scene::PlanningScenePtr attached_object_diff_scene = ps->diff();

  moveit_msgs::AttachedCollisionObject att_obj;
  att_obj.link_name = "r_wrist_roll_link";
  att_obj.object.operation = moveit_msgs::CollisionObject::ADD;
  att_obj.object.id = "sphere";

  collision_detection::CollisionRequest req;
  collision_detection::CollisionResult res;

  attached_object_diff_scene->processAttachedCollisionObjectMsg(att_obj);
  attached_object_diff_scene->checkCollision(req,res);
  ps->checkCollision(req, res);
}

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

/* Author: Ioan Sucan */

#include <gtest/gtest.h>
#include <moveit/planning_scene/planning_scene.h>
#include <urdf_parser/urdf_parser.h>
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <ros/package.h>

// This function needs to return void so the gtest FAIL() macro inside
// it works right.
void loadRobotModel(boost::shared_ptr<urdf::ModelInterface>& robot_model_out)
{
  std::string resource_dir = ros::package::getPath("moveit_resources");
  if(resource_dir == "")
  {
    FAIL() << "Failed to find package moveit_resources.";
    return;
  }
  boost::filesystem::path res_path(resource_dir);

  std::string xml_string;
  std::fstream xml_file((res_path / "test/urdf/robot.xml").string().c_str(), std::fstream::in);
  EXPECT_TRUE(xml_file.is_open());
  while ( xml_file.good() )
  {
    std::string line;
    std::getline( xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();
  robot_model_out = urdf::parseURDF(xml_string);
}

TEST(PlanningScene, LoadRestore)
{
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());
  planning_scene::PlanningScene ps(urdf_model, srdf_model);
  moveit_msgs::PlanningScene ps_msg;
  ps.getPlanningSceneMsg(ps_msg);
  ps.setPlanningSceneMsg(ps_msg);
}

TEST(PlanningScene, LoadRestoreDiff)
{
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World &world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  moveit_msgs::PlanningScene ps_msg;
  ps_msg.robot_state.is_diff = true;
  EXPECT_TRUE(planning_scene::PlanningScene::isEmpty(ps_msg));
  ps->getPlanningSceneMsg(ps_msg);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_FALSE(planning_scene::PlanningScene::isEmpty(ps_msg));
  EXPECT_TRUE(world.hasObject("sphere"));

  planning_scene::PlanningScenePtr next = ps->diff();
  EXPECT_TRUE(next->getWorld()->hasObject("sphere"));
  next->getWorldNonConst()->addToObject("sphere2", shapes::ShapeConstPtr(new shapes::Sphere(0.5)), id);
  EXPECT_EQ(next->getWorld()->size(), 2);
  EXPECT_EQ(ps->getWorld()->size(), 1);
  next->getPlanningSceneDiffMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 1);
  next->decoupleParent();
  moveit_msgs::PlanningScene ps_msg2;
  next->getPlanningSceneDiffMsg(ps_msg2);
  EXPECT_EQ(ps_msg2.world.collision_objects.size(), 0);
  next->getPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 2);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps->getWorld()->size(), 2);
}

TEST(PlanningScene, MakeAttachedDiff)
{
  boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());
  boost::shared_ptr<urdf::ModelInterface> urdf_model;
  loadRobotModel(urdf_model);

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World &world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  planning_scene::PlanningScenePtr attached_object_diff_scene = ps->diff();

  moveit_msgs::AttachedCollisionObject att_obj;
  att_obj.link_name = "r_wrist_roll_link";
  att_obj.object.operation = moveit_msgs::CollisionObject::ADD;
  att_obj.object.id = "sphere";

  collision_detection::CollisionRequest req;
  collision_detection::CollisionResult res;

  attached_object_diff_scene->processAttachedCollisionObjectMsg(att_obj);
  attached_object_diff_scene->checkCollision(req,res);
  ps->checkCollision(req, res);
}

int main(int argc, char **argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>// tests the inclusion algorithm for all 2D and 3D elements

#include "FemusInit.hpp"
#include "Marker.hpp"
#include "MultiLevelMesh.hpp"
#include "VTKWriter.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "MyVector.hpp"

using namespace femus;

// double InitalValueU(const std::vector < double >& x) {
//   return 0.5;
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   return 0.5;
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   return 0.5;
// }

//2D CASE rigid translation
double InitalValueU(const std::vector < double >& x) {
  return -x[1];
}

double InitalValueV(const std::vector < double >& x) {
  return x[0];
}

double InitalValueW(const std::vector < double >& x) {
  return 0.;
}

// double InitalValueU(const std::vector < double >& x) {
//   return (-x[1]+x[2])/sqrt(3);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   return (x[0]-x[2])/sqrt(3);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   return (x[1]-x[0])/sqrt(3);
// }

// 2D CASE with vorticity
// double pi = acos(-1.);
//
// double InitalValueU(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return 2. * sin(pi * (x[0] + 0.5)) * sin(pi * (x[0] + 0.5)) * sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) * cos(time);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return -2. * sin(pi * (x[1] + 0.5)) * sin(pi * (x[1] + 0.5)) * sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) * cos(time);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return 0.;
// }

// 3D CASE with vorticity
// double pi = acos(-1.);
//
// double InitalValueU(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*(sin(pi * (x[0] + 0.5)) * sin(pi * (x[0] + 0.5)) *
//     ( sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) - sin(pi * (x[2] + 0.5)) * cos(pi * (x[2] + 0.5)) )
//     )* cos(time);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*(sin(pi * (x[1] + 0.5)) * sin(pi * (x[1] + 0.5)) *
//     ( sin(pi * (x[2] + 0.5)) * cos(pi * (x[2] + 0.5)) - sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) )
//     )* cos(time);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*( sin(pi * (x[2] + 0.5)) * sin(pi * (x[2] + 0.5)) *
//     ( sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) - sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) )
//     )* cos(time);
//
//   return 0.;
// }

bool SetRefinementFlag(const std::vector < double >& x, const int& elemgroupnumber, const int& level) {

  bool refine = 0;

  if(elemgroupnumber == 6 && level < 4) refine = 1;
  if(elemgroupnumber == 7 && level < 5) refine = 1;
  if(elemgroupnumber == 8 && level < 6) refine = 1;

  return refine;

}

int main(int argc, char** args) {

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  std::vector < double > x(3, 0); // marker
  MultiLevelMesh mlMsh;
  double scalingFactor = 1.;
  unsigned numberOfUniformLevels = 3; //for refinement
  //unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;
  std::vector < std::string > variablesToBePrinted;

  /* element types
  0 = HEX
  1 = TET
  2 = WEDGE
  3 = QUAD
  4 = TRI
   */

  unsigned solType = 2;

  std::cout << " --------------------------------------------------     TEST     --------------------------------------------------" << std::endl;

  //mlMsh.ReadCoarseMesh("./input/prism3D.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/square.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/tri2.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/cubeMixed.neu", "seventh", scalingFactor);
  mlMsh.ReadCoarseMesh("./input/test2D.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/cubeTet.neu", "seventh", scalingFactor);
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , SetRefinementFlag);

  unsigned dim = mlMsh.GetDimension();

  MultiLevelSolution mlSol(&mlMsh);
  // add variables to mlSol
  mlSol.AddSolution("U", LAGRANGE, SECOND, 2);
  mlSol.AddSolution("V", LAGRANGE, SECOND, 2);
  if(dim == 3) mlSol.AddSolution("W", LAGRANGE, SECOND, 2);
  mlSol.Initialize("U" , InitalValueU);
  mlSol.Initialize("V" , InitalValueV);
  if(dim == 3) mlSol.Initialize("W", InitalValueW);

//   //Test 1 (QUAD):
//
  //NOTE tests ran with 4 procs
//   x[0] = -0.46875; //the marker is in element 191 (proc 3 of 4)
//   x[1] = -0.5;
//   x[2] = 0.;

  x[0] = 0.125;
  x[1] = 0.125;
  x[2] = -0.25;

//   x[0] = -0.46875; //the marker is in element 191 (proc 3 of 4)
//   x[1] = -0.5;
//   x[2] = 0.;

// //Test 1 (TET):  element 20
//     //NOTE Tests ran with 2 procs
//       x[0] = -0.5;
//       x[1] = 0.;
//       x[2] = 0.;

  std::cout << " --------------------------------------------------------------------------------------------- " << std::endl;
  Marker a1Quad(x, VOLUME, mlMsh.GetLevel(0), solType, true);
  //Marker a( x, VOLUME, mlMsh.GetLevel(numberOfUniformLevels + numberOfSelectiveLevels -1) );
  //std::cout << " The coordinates of the marker are " << x[0] << " ," << x[1] << " ," << x[2] << std::endl;
  //std::cout << " The marker type is " <<  a1Quad.GetMarkerType() << std::endl;

  double T = 2 * acos(-1.);
  unsigned n  = 100;

  std::vector< std::vector < std::vector < double > > > xn(1);
  xn[0].resize(n + 1);
  for(unsigned k = 0; k < n; k++) {
    a1Quad.GetMarkerCoordinates(xn[0][k]);
    a1Quad.Advection(mlSol.GetLevel(0), 2, T / n);
  }
  a1Quad.GetMarkerCoordinates(xn[0][n]);
  for(unsigned i = 0;  i < xn[0].size(); i++) {
    for(unsigned d = 0; d < xn[0][i].size(); d++) {
      //   std::cout << xn[0][i][d] << " ";
    }
    // std::cout << std::endl;
  }

  variablesToBePrinted.push_back("All");

  VTKWriter vtkIO(&mlSol);
  vtkIO.SetDebugOutput(true);
  vtkIO.Write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  PrintLine(DEFAULT_OUTPUTDIR, xn);

  unsigned pSize = 100;
  std::vector < Marker*> particle(pSize);

  double pi = acos(-1.);
  for(unsigned j = 0; j < pSize; j++) {
    x[0] = 0. + 0.125 * cos(2.*pi / pSize * j);
    x[1] = .25 + 0.125 * sin(2.*pi / pSize * j);
    x[2] = 0.;
    particle[j] = new Marker(x, VOLUME, mlMsh.GetLevel(numberOfUniformLevels - 1), solType, true);
  }

  std::vector < std::vector < std::vector < double > > > line(1);
  line[0].resize(pSize + 1);

  for(unsigned j = 0; j < pSize; j++) {
    particle[j]->GetMarkerCoordinates(line[0][j]);
  }
  particle[0]->GetMarkerCoordinates(line[0][pSize]);

  std::vector < std::vector < std::vector < double > > > line0 = line; // saves the initial position

  PrintLine(DEFAULT_OUTPUTDIR, line, false, 0);

  n = 200;

  clock_t start_time = clock();

  for(unsigned k = 1; k <= n; k++) {
    mlSol.CopySolutionToOldSolution();
    mlSol.UpdateSolution("U" , InitalValueU, pi * k / n);
    mlSol.UpdateSolution("V" , InitalValueV, pi * k / n);
    if(dim == 3) mlSol.UpdateSolution("W" , InitalValueW, pi * k / n);
    for(unsigned j = 0; j < pSize; j++) {
      particle[j]->Advection(mlSol.GetLevel(numberOfUniformLevels - 1), 4, T / n);
      particle[j]->GetMarkerCoordinates(line[0][j]);
    }
    particle[0]->GetMarkerCoordinates(line[0][pSize]);
    PrintLine(DEFAULT_OUTPUTDIR, line, false, k);
  }

  std::cout << std::endl << " RANNA in: " << std::setw(11) << std::setprecision(6) << std::fixed
            << static_cast<double>((clock() - start_time)) / CLOCKS_PER_SEC << " s" << std::endl;

  //computing the geometric error
  double error = 0.;
  for(unsigned j = 0; j < pSize + 1; j++) {
    double tempError = 0.;
    for(unsigned i = 0; i < dim; i++) {
      tempError += (line0[0][j][i] - line[0][j][i]) * (line0[0][j][i] - line[0][j][i]);
    }
    error += sqrt(tempError);
  }

  error = error / pSize;

  std::cout << " ERROR = " << std::setprecision (15) << error << std::endl;

  for(unsigned j = 0; j < pSize; j++) {
    delete particle[j];
  }

  return 0;
}

<commit_msg>testing the baby<commit_after>// tests the inclusion algorithm for all 2D and 3D elements

#include "FemusInit.hpp"
#include "Marker.hpp"
#include "MultiLevelMesh.hpp"
#include "VTKWriter.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "MyVector.hpp"

using namespace femus;

// double InitalValueU(const std::vector < double >& x) {
//   return 0.5;
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   return 0.5;
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   return 0.5;
// }

//2D CASE translation
double InitalValueU(const std::vector < double >& x) {
  return 1.;
}

double InitalValueV(const std::vector < double >& x) {
  return 0.;
}

double InitalValueW(const std::vector < double >& x) {
  return 0.;
}

//2D CASE rigid rotation
// double InitalValueU(const std::vector < double >& x) {
//   return -x[1];
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   return x[0];
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   return 0.;
// }

// double InitalValueU(const std::vector < double >& x) {
//   return (-x[1]+x[2])/sqrt(3);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   return (x[0]-x[2])/sqrt(3);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   return (x[1]-x[0])/sqrt(3);
// }

// 2D CASE with vorticity
// double pi = acos(-1.);
//
// double InitalValueU(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return 2. * sin(pi * (x[0] + 0.5)) * sin(pi * (x[0] + 0.5)) * sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) * cos(time);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return -2. * sin(pi * (x[1] + 0.5)) * sin(pi * (x[1] + 0.5)) * sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) * cos(time);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return 0.;
// }

// 3D CASE with vorticity
// double pi = acos(-1.);
//
// double InitalValueU(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*(sin(pi * (x[0] + 0.5)) * sin(pi * (x[0] + 0.5)) *
//     ( sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) - sin(pi * (x[2] + 0.5)) * cos(pi * (x[2] + 0.5)) )
//     )* cos(time);
// }
//
// double InitalValueV(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*(sin(pi * (x[1] + 0.5)) * sin(pi * (x[1] + 0.5)) *
//     ( sin(pi * (x[2] + 0.5)) * cos(pi * (x[2] + 0.5)) - sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) )
//     )* cos(time);
// }
//
// double InitalValueW(const std::vector < double >& x) {
//   double time = (x.size() == 4) ? x[3] : 0.;
//   return
//     2.*( sin(pi * (x[2] + 0.5)) * sin(pi * (x[2] + 0.5)) *
//     ( sin(pi * (x[0] + 0.5)) * cos(pi * (x[0] + 0.5)) - sin(pi * (x[1] + 0.5)) * cos(pi * (x[1] + 0.5)) )
//     )* cos(time);
//
//   return 0.;
// }

bool SetRefinementFlag(const std::vector < double >& x, const int& elemgroupnumber, const int& level) {

  bool refine = 0;

  if(elemgroupnumber == 6 && level < 4) refine = 1;
  if(elemgroupnumber == 7 && level < 5) refine = 1;
  if(elemgroupnumber == 8 && level < 6) refine = 1;

  return refine;

}

int main(int argc, char** args) {

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  std::vector < double > x(3, 0); // marker
  MultiLevelMesh mlMsh;
  double scalingFactor = 1.;
  unsigned numberOfUniformLevels = 3; //for refinement
  //unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;
  std::vector < std::string > variablesToBePrinted;

  /* element types
  0 = HEX
  1 = TET
  2 = WEDGE
  3 = QUAD
  4 = TRI
   */

  unsigned solType = 2;

  std::cout << " --------------------------------------------------     TEST     --------------------------------------------------" << std::endl;

  //mlMsh.ReadCoarseMesh("./input/prism3D.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/square.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/tri2.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/cubeMixed.neu", "seventh", scalingFactor);
  mlMsh.ReadCoarseMesh("./input/test2D.neu", "seventh", scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/cubeTet.neu", "seventh", scalingFactor);
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , SetRefinementFlag);

  unsigned dim = mlMsh.GetDimension();

  MultiLevelSolution mlSol(&mlMsh);
  // add variables to mlSol
  mlSol.AddSolution("U", LAGRANGE, SECOND, 2);
  mlSol.AddSolution("V", LAGRANGE, SECOND, 2);
  if(dim == 3) mlSol.AddSolution("W", LAGRANGE, SECOND, 2);
  mlSol.Initialize("U" , InitalValueU);
  mlSol.Initialize("V" , InitalValueV);
  if(dim == 3) mlSol.Initialize("W", InitalValueW);

//   //Test 1 (QUAD):
//
  //NOTE tests ran with 4 procs
//   x[0] = -0.46875; //the marker is in element 191 (proc 3 of 4)
//   x[1] = -0.5;
//   x[2] = 0.;

  x[0] = 0.125;
  x[1] = 0.125;
  x[2] = -0.25;

//   x[0] = -0.46875; //the marker is in element 191 (proc 3 of 4)
//   x[1] = -0.5;
//   x[2] = 0.;

// //Test 1 (TET):  element 20
//     //NOTE Tests ran with 2 procs
//       x[0] = -0.5;
//       x[1] = 0.;
//       x[2] = 0.;

  std::cout << " --------------------------------------------------------------------------------------------- " << std::endl;
  Marker a1Quad(x, VOLUME, mlMsh.GetLevel(0), solType, true);
  //Marker a( x, VOLUME, mlMsh.GetLevel(numberOfUniformLevels + numberOfSelectiveLevels -1) );
  //std::cout << " The coordinates of the marker are " << x[0] << " ," << x[1] << " ," << x[2] << std::endl;
  //std::cout << " The marker type is " <<  a1Quad.GetMarkerType() << std::endl;

  double T = 2 * acos(-1.);
  unsigned n  = 100;

  std::vector< std::vector < std::vector < double > > > xn(1);
  xn[0].resize(n + 1);
  for(unsigned k = 0; k < n; k++) {
    a1Quad.GetMarkerCoordinates(xn[0][k]);
    a1Quad.Advection(mlSol.GetLevel(0), 2, T / n);
  }
  a1Quad.GetMarkerCoordinates(xn[0][n]);
  for(unsigned i = 0;  i < xn[0].size(); i++) {
    for(unsigned d = 0; d < xn[0][i].size(); d++) {
      //   std::cout << xn[0][i][d] << " ";
    }
    // std::cout << std::endl;
  }

  variablesToBePrinted.push_back("All");

  VTKWriter vtkIO(&mlSol);
  vtkIO.SetDebugOutput(true);
  vtkIO.Write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  PrintLine(DEFAULT_OUTPUTDIR, xn);

  unsigned pSize = 100;
  std::vector < Marker*> particle(pSize);

//uncomment to do solid body rotation and vortex test
//   double pi = acos(-1.);
//   for(unsigned j = 0; j < pSize; j++) {
//     x[0] = 0. + 0.125 * cos(2.*pi / pSize * j);
//     x[1] = .25 + 0.125 * sin(2.*pi / pSize * j);
//     x[2] = 0.;
//     particle[j] = new Marker(x, VOLUME, mlMsh.GetLevel(numberOfUniformLevels - 1), solType, true);
//   }

  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  //initializing the particles for the translation test

    T = 1.;
    for(unsigned j = 0; j < pSize; j++) {
    x[0] = -0.5;
    x[1] = -0.5 + j/99;
    x[2] = 0.;
    particle[j] = new Marker(x, VOLUME, mlMsh.GetLevel(numberOfUniformLevels - 1), solType, true);
  }
  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  std::vector < std::vector < std::vector < double > > > line(1);
  line[0].resize(pSize + 1);

  for(unsigned j = 0; j < pSize; j++) {
    particle[j]->GetMarkerCoordinates(line[0][j]);
  }
  particle[0]->GetMarkerCoordinates(line[0][pSize]);

  std::vector < std::vector < std::vector < double > > > line0 = line; // saves the initial position

  PrintLine(DEFAULT_OUTPUTDIR, line, false, 0);

  n = 10;

  clock_t start_time = clock();

  for(unsigned k = 1; k <= n; k++) {
 // uncomment for rigid translation ad vortex test
     //mlSol.CopySolutionToOldSolution();
  //     mlSol.UpdateSolution("U" , InitalValueU, pi * k / n);
//     mlSol.UpdateSolution("V" , InitalValueV, pi * k / n);
//     if(dim == 3) mlSol.UpdateSolution("W" , InitalValueW, pi * k / n);
    for(unsigned j = 0; j < pSize; j++) {
      particle[j]->Advection(mlSol.GetLevel(numberOfUniformLevels - 1), 4, T / n);
      particle[j]->GetMarkerCoordinates(line[0][j]);
    }
    particle[0]->GetMarkerCoordinates(line[0][pSize]);
    PrintLine(DEFAULT_OUTPUTDIR, line, false, k);
  }

  std::cout << std::endl << " RANNA in: " << std::setw(11) << std::setprecision(6) << std::fixed
            << static_cast<double>((clock() - start_time)) / CLOCKS_PER_SEC << " s" << std::endl;

  //computing the geometric error
  double error = 0.;
  for(unsigned j = 0; j < pSize + 1; j++) {
    double tempError = 0.;
    for(unsigned i = 0; i < dim; i++) {
      tempError += (line0[0][j][i] - line[0][j][i]) * (line0[0][j][i] - line[0][j][i]);
    }
    error += sqrt(tempError);
  }

  error = error / pSize;

  std::cout << " ERROR = " << std::setprecision (15) << error << std::endl;

  for(unsigned j = 0; j < pSize; j++) {
    delete particle[j];
  }

  return 0;
}

<|endoftext|>


<commit_before>// =================================================================== //
// Copyright (C) 2018-2020 Kimura Ryo                                  //
//                                                                     //
// 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/.            //
// =================================================================== //

#include <iostream>
#include <memory>

#include <libbsdf/Brdf/Optimizer.h>
#include <libbsdf/Brdf/Processor.h>

#include <libbsdf/Reader/ReaderUtility.h>

#include <libbsdf/ReflectanceModel/GGX.h>
#include <libbsdf/ReflectanceModel/Lambertian.h>
#include <libbsdf/ReflectanceModel/MultipleScatteringSmith.h>
#include <libbsdf/ReflectanceModel/ReflectanceModelUtility.h>

#include <libbsdf/Writer/DdrWriter.h>
#include <libbsdf/Writer/SsddWriter.h>

#include <ArgumentParser.h>
#include <Utility.h>

using namespace lb;

/*
 * BSDF generator
 */

const std::string APP_NAME("lbgen");
const std::string APP_VERSION("1.1.0");

const std::string GgxName                       = "ggx";
const std::string MultipleScatteringSmithName   = "multiple-scattering-smith";
const std::string LambertianName                = "lambertian";

// Parameters
int numIncomingPolarAngles = 18;
int numSpecularPolarAngles = 360;
int numSpecularAzimuthalAngles = 72;
bool conservationOfEnergyUsed = false;
bool intervalAdjustmentUsed = false;
float roughness = 0.3f;
float n = 1.5f;
float k = 0.0f;
int numIterations = 10;

void showHelp()
{
    using std::cout;
    using std::endl;

    cout << "Usage: lbgen [options ...] bsdf_model out_file" << endl;
    cout << endl;
    cout << "lbgen generates BSDF data and saves the file(s)." << endl;
    cout << endl;
    cout << "Positional Arguments:" << endl;
    cout << "  bsdf_model   Analytic BSDF model" << endl;
    cout << "  out_file     Name of generated file";
    cout << "                   Valid formats:" << endl;
    cout << "                       Surface Scattering Distribution Data (\".ssdd\")" << endl;
    cout << "                       Integra Diffuse Distribution (\".ddr, .ddt\")" << endl;
    cout << "                           If there is no file extension, \".ddr\" and \".ddt\" files are generated." << endl;
    cout << endl;
    cout << "Options:" << endl;
    cout << "  -h, --help                   show this help message and exit" << endl;
    cout << "  -v, --version                show program's version number and exit" << endl;
    cout << "  -l, --list                   show acceptable models and parameters of BSDF and exit" << endl;
    cout << "  -r, --reference              show the references of BSDF models and exit" << endl;
    cout << "  -numIncomingPolarAngles      set the division number of incoming polar angles (default: 18)" << endl;
    cout << "  -numSpecularPolarAngles      set the division number of specular polar angles (default: 360)" << endl;
    cout << "  -numSpecularAzimuthalAngles  set the division number of specular azimuthal angles (default: 72)" << endl;
    cout << "  -conservationOfEnergy        fix BSDF/BRDF/BTDF if the sum of reflectance and transmittance exceed one" << endl;
    cout << "  -intervalAdjustment          adjust angle intervals by recalculation with the selected model" << endl;
#ifdef _OPENMP
    cout << "  -numThreads                  set the number of threads used by parallel processing" << endl;
#endif
}

void showList()
{
    using std::cout;
    using std::endl;

    cout << "Acceptable models:" << endl;
    cout << "  " << GgxName << endl;
    cout << "      Valid options:" << endl;
    cout << "          -roughness  set roughness of surface (default: 0.3, range: [0.01, 1.0])" << endl;
    cout << "          -n          set refractive index (default: 1.5)" << endl;
    cout << "          -k          set extinction coefficient (default: 0.0)" << endl;
    cout << "  " << MultipleScatteringSmithName << endl;
    cout << "      Valid options:" << endl;
    cout << "          -roughness      set roughness of surface (default: 0.3, range: [0.01, 1.0])" << endl;
    cout << "          -n              set refractive index (default: 1.5)" << endl;
    cout << "          -numIterations  set the number of sampling iterations (default: 10)" << endl;
    cout << "  " << LambertianName << endl;
    cout << "      Valid options: none" << endl;
}

void showReference()
{
    using std::cout;
    using std::endl;

    cout << "  " << GgxName << ": " << Ggx::getReference() << endl;
    cout << "  " << MultipleScatteringSmithName << ": " << MultipleScatteringSmith::getReference() << endl;
}

bool readOptions(ArgumentParser* ap)
{
    if (ap->read("-numIncomingPolarAngles", &numIncomingPolarAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numIncomingPolarAngles = app_utility::clampParameter("numIncomingPolarAngles",
                                                             numIncomingPolarAngles + 1, 2, 3600);
    }

    if (ap->read("-numSpecularPolarAngles", &numSpecularPolarAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numSpecularPolarAngles = app_utility::clampParameter("numSpecularPolarAngles",
                                                             numSpecularPolarAngles + 1, 2, 3600);
    }

    if (ap->read("-numSpecularAzimuthalAngles", &numSpecularAzimuthalAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numSpecularAzimuthalAngles = app_utility::clampParameter("numSpecularAzimuthalAngles",
                                                                 numSpecularAzimuthalAngles + 1, 2, 3600);
    }

    if (ap->read("-conservationOfEnergy")) {
        conservationOfEnergyUsed = true;
    }

    if (ap->read("-intervalAdjustment")) {
        intervalAdjustmentUsed = true;
    }

#ifdef _OPENMP
    int numThreads;
    ArgumentParser::ResultType result_numThreads = ap->read("-numThreads", &numThreads);
    if (result_numThreads == ArgumentParser::OK) {
        omp_set_num_threads(numThreads);
    }
    else if (result_numThreads == ArgumentParser::ERROR) {
        return false;
    }
#endif

    if (ap->read("-roughness", &roughness) == ArgumentParser::ERROR) {
        return false;
    }

    if (ap->read("-n", &n) == ArgumentParser::ERROR) {
        return false;
    }
    else if (n <= 0.0f) {
        std::cerr << "Invalid value (n): " << n << std::endl;
        return false;
    }

    if (ap->read("-k", &k) == ArgumentParser::ERROR) {
        return false;
    }
    else if (k < 0.0f) {
        std::cerr << "Invalid value (k): " << k << std::endl;
        return false;
    }

    if (ap->read("-numIterations", &numIterations) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numIterations = app_utility::clampParameter("numIterations", numIterations, 1, 10000);
    }

    return true;
}

SpecularCoordinatesBrdf* createBrdf(const ReflectanceModel& model,
                                    float                   n,
                                    int                     numIncomingPolarAngles,
                                    int                     numSpecularPolarAngles,
                                    int                     numSpecularAzimuthalAngles,
                                    DataType                dataType)
{
    SpecularCoordinatesBrdf* brdf = new SpecularCoordinatesBrdf(numIncomingPolarAngles,
                                                                1,
                                                                numSpecularPolarAngles,
                                                                numSpecularAzimuthalAngles,
                                                                2.0f,
                                                                MONOCHROMATIC_MODEL, 1, n);

    ReflectanceModelUtility::setupBrdf(model, brdf, dataType);

    if (intervalAdjustmentUsed) {
        const lb::SampleSet* ss = brdf->getSampleSet();

        // Save the number of angles before optimization.
        int numAngles0 = ss->getNumAngles0();
        int numAngles1 = ss->getNumAngles1();
        int numAngles2 = ss->getNumAngles2();
        int numAngles3 = ss->getNumAngles3();

        lb::Optimizer optimizer(brdf, 0.001f, 0.01f);
        optimizer.optimize();

        lb::ReflectanceModelUtility::setupBrdf(model, brdf,
                                               numAngles0, numAngles1, numAngles2, numAngles3,
                                               dataType, n);
    }

    brdf->setSourceType(GENERATED_SOURCE);

    return brdf;
}

int main(int argc, char** argv)
{
    Log::setNotificationLevel(Log::Level::WARN_MSG);

    ArgumentParser ap(argc, argv);

    if (ap.read("-h") || ap.read("--help") || ap.getTokens().empty()) {
        showHelp();
        return 0;
    }

    if (ap.read("-v") || ap.read("--version")) {
        app_utility::showAppVersion(APP_NAME, APP_VERSION);
        return 0;
    }

    if (ap.read("-l") || ap.read("--list")) {
        showList();
        return 0;
    }

    if (ap.read("-r") || ap.read("--reference")) {
        showReference();
        return 0;
    }

    if (!readOptions(&ap)) return 1;

    if (!ap.validateNumTokens(2)) return 1;

    std::string modelName = ap.getTokens().at(0);
    std::string fileName  = ap.getTokens().at(1);

    // Create a BRDF/BTDF model.
    std::unique_ptr<ReflectanceModel> model;
    const Vec3 white(1.0, 1.0, 1.0);
    if (modelName == GgxName) {
        roughness = app_utility::clampParameter("roughness", roughness, 0.01f, 1.0f);
        model.reset(new Ggx(white, roughness, n, k));
    }
    else if (modelName == MultipleScatteringSmithName) {
        roughness = app_utility::clampParameter("roughness", roughness, 0.01f, 1.0f);

        MultipleScatteringSmith::MaterialType matType = (k == 0.0f) ? MultipleScatteringSmith::DIELECTRIC_MATERIAL
                                                                    : MultipleScatteringSmith::CONDUCTOR_MATERIAL;

        model.reset(new MultipleScatteringSmith(white, roughness, roughness, n,
                                                static_cast<int>(matType),
                                                static_cast<int>(MultipleScatteringSmith::GAUSSIAN_HEIGHT),
                                                static_cast<int>(MultipleScatteringSmith::BECKMANN_SLOPE),
                                                numIterations));
    }
    else if (modelName == LambertianName) {
        n = 1.0f;
        model.reset(new Lambertian(white));
    }
    else {
        std::cerr << "Invalid model name: " << modelName << std::endl;
        return 1;
    }

    FileType fileType;
    if (reader_utility::hasSuffix(fileName, ".ssdd")) {
        fileType = SSDD_FILE;
    }
    else if (reader_utility::hasSuffix(fileName, ".ddr")) {
        fileType = INTEGRA_DDR_FILE;
    }
    else if (reader_utility::hasSuffix(fileName, ".ddt")) {
        fileType = INTEGRA_DDT_FILE;
    }
    else {
        fileType = UNKNOWN_FILE;
    }

    std::unique_ptr<SpecularCoordinatesBrdf> brdf, btdfData;

    // Create a BRDF.
    if (fileType != INTEGRA_DDT_FILE) {
        brdf.reset(createBrdf(*model,
                              1.0f,
                              numIncomingPolarAngles,
                              numSpecularPolarAngles,
                              numSpecularAzimuthalAngles,
                              BRDF_DATA));
    }

    // Create BTDF data in lb::SpecularCoordinatesBrdf.
    if (fileType != INTEGRA_DDR_FILE) {
        btdfData.reset(createBrdf(*model,
                                  n,
                                  numIncomingPolarAngles,
                                  numSpecularPolarAngles,
                                  numSpecularAzimuthalAngles,
                                  BTDF_DATA));
    }

    // Save files.
    std::string comments = app_utility::createComments(argc, argv, APP_NAME, APP_VERSION);
    if (fileType == INTEGRA_DDR_FILE) {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(brdf.get());
        }

        if (DdrWriter::write(fileName, *brdf, comments)) {
            std::cout << "Saved: " << fileName << std::endl;
        }
    }
    else if (fileType == INTEGRA_DDT_FILE) {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(btdfData.get());
        }

        if (DdrWriter::write(fileName, *btdfData, comments)) {
            std::cout << "Saved: " << fileName << std::endl;
        }
    }
    else {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(brdf.get(), btdfData.get());
        }

        if (fileType == SSDD_FILE) {
            std::unique_ptr<Btdf> btdf(new Btdf(std::move(btdfData)));
            std::unique_ptr<Bsdf> bsdf(new Bsdf(std::move(brdf), std::move(btdf)));
            std::unique_ptr<Material> material(new Material(std::move(bsdf)));

            if (SsddWriter::write(fileName, *material, SsddWriter::DataFormat::ASCII_DATA, comments)) {
                std::cout << "Saved: " << fileName << std::endl;
            }
        }
        else {
            if (DdrWriter::write(fileName + ".ddr", *brdf, comments)) {
                std::cout << "Saved: " << fileName + ".ddr" << std::endl;
            }

            if (DdrWriter::write(fileName + ".ddt", *btdfData, comments)) {
                std::cout << "Saved: " << fileName + ".ddt" << std::endl;
            }
        }
    }

    return 0;
}
<commit_msg>Fixed indentation in description<commit_after>// =================================================================== //
// Copyright (C) 2018-2020 Kimura Ryo                                  //
//                                                                     //
// 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/.            //
// =================================================================== //

#include <iostream>
#include <memory>

#include <libbsdf/Brdf/Optimizer.h>
#include <libbsdf/Brdf/Processor.h>

#include <libbsdf/Reader/ReaderUtility.h>

#include <libbsdf/ReflectanceModel/GGX.h>
#include <libbsdf/ReflectanceModel/Lambertian.h>
#include <libbsdf/ReflectanceModel/MultipleScatteringSmith.h>
#include <libbsdf/ReflectanceModel/ReflectanceModelUtility.h>

#include <libbsdf/Writer/DdrWriter.h>
#include <libbsdf/Writer/SsddWriter.h>

#include <ArgumentParser.h>
#include <Utility.h>

using namespace lb;

/*
 * BSDF generator
 */

const std::string APP_NAME("lbgen");
const std::string APP_VERSION("1.1.0");

const std::string GgxName                       = "ggx";
const std::string MultipleScatteringSmithName   = "multiple-scattering-smith";
const std::string LambertianName                = "lambertian";

// Parameters
int numIncomingPolarAngles = 18;
int numSpecularPolarAngles = 360;
int numSpecularAzimuthalAngles = 72;
bool conservationOfEnergyUsed = false;
bool intervalAdjustmentUsed = false;
float roughness = 0.3f;
float n = 1.5f;
float k = 0.0f;
int numIterations = 10;

void showHelp()
{
    using std::cout;
    using std::endl;

    cout << "Usage: lbgen [options ...] bsdf_model out_file" << endl;
    cout << endl;
    cout << "lbgen generates BSDF data and saves the file(s)." << endl;
    cout << endl;
    cout << "Positional Arguments:" << endl;
    cout << "  bsdf_model   Analytic BSDF model" << endl;
    cout << "  out_file     Name of generated file";
    cout << "                   Valid formats:" << endl;
    cout << "                       Surface Scattering Distribution Data (\".ssdd\")" << endl;
    cout << "                       Integra Diffuse Distribution (\".ddr, .ddt\")" << endl;
    cout << "                       If there is no file extension, \".ddr\" and \".ddt\" files are generated." << endl;
    cout << endl;
    cout << "Options:" << endl;
    cout << "  -h, --help                   show this help message and exit" << endl;
    cout << "  -v, --version                show program's version number and exit" << endl;
    cout << "  -l, --list                   show acceptable models and parameters of BSDF and exit" << endl;
    cout << "  -r, --reference              show the references of BSDF models and exit" << endl;
    cout << "  -numIncomingPolarAngles      set the division number of incoming polar angles (default: 18)" << endl;
    cout << "  -numSpecularPolarAngles      set the division number of specular polar angles (default: 360)" << endl;
    cout << "  -numSpecularAzimuthalAngles  set the division number of specular azimuthal angles (default: 72)" << endl;
    cout << "  -conservationOfEnergy        fix BSDF/BRDF/BTDF if the sum of reflectance and transmittance exceed one" << endl;
    cout << "  -intervalAdjustment          adjust angle intervals by recalculation with the selected model" << endl;
#ifdef _OPENMP
    cout << "  -numThreads                  set the number of threads used by parallel processing" << endl;
#endif
}

void showList()
{
    using std::cout;
    using std::endl;

    cout << "Acceptable models:" << endl;
    cout << "  " << GgxName << endl;
    cout << "      Valid options:" << endl;
    cout << "          -roughness  set roughness of surface (default: 0.3, range: [0.01, 1.0])" << endl;
    cout << "          -n          set refractive index (default: 1.5)" << endl;
    cout << "          -k          set extinction coefficient (default: 0.0)" << endl;
    cout << "  " << MultipleScatteringSmithName << endl;
    cout << "      Valid options:" << endl;
    cout << "          -roughness      set roughness of surface (default: 0.3, range: [0.01, 1.0])" << endl;
    cout << "          -n              set refractive index (default: 1.5)" << endl;
    cout << "          -numIterations  set the number of sampling iterations (default: 10)" << endl;
    cout << "  " << LambertianName << endl;
    cout << "      Valid options: none" << endl;
}

void showReference()
{
    using std::cout;
    using std::endl;

    cout << "  " << GgxName << ": " << Ggx::getReference() << endl;
    cout << "  " << MultipleScatteringSmithName << ": " << MultipleScatteringSmith::getReference() << endl;
}

bool readOptions(ArgumentParser* ap)
{
    if (ap->read("-numIncomingPolarAngles", &numIncomingPolarAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numIncomingPolarAngles = app_utility::clampParameter("numIncomingPolarAngles",
                                                             numIncomingPolarAngles + 1, 2, 3600);
    }

    if (ap->read("-numSpecularPolarAngles", &numSpecularPolarAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numSpecularPolarAngles = app_utility::clampParameter("numSpecularPolarAngles",
                                                             numSpecularPolarAngles + 1, 2, 3600);
    }

    if (ap->read("-numSpecularAzimuthalAngles", &numSpecularAzimuthalAngles) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numSpecularAzimuthalAngles = app_utility::clampParameter("numSpecularAzimuthalAngles",
                                                                 numSpecularAzimuthalAngles + 1, 2, 3600);
    }

    if (ap->read("-conservationOfEnergy")) {
        conservationOfEnergyUsed = true;
    }

    if (ap->read("-intervalAdjustment")) {
        intervalAdjustmentUsed = true;
    }

#ifdef _OPENMP
    int numThreads;
    ArgumentParser::ResultType result_numThreads = ap->read("-numThreads", &numThreads);
    if (result_numThreads == ArgumentParser::OK) {
        omp_set_num_threads(numThreads);
    }
    else if (result_numThreads == ArgumentParser::ERROR) {
        return false;
    }
#endif

    if (ap->read("-roughness", &roughness) == ArgumentParser::ERROR) {
        return false;
    }

    if (ap->read("-n", &n) == ArgumentParser::ERROR) {
        return false;
    }
    else if (n <= 0.0f) {
        std::cerr << "Invalid value (n): " << n << std::endl;
        return false;
    }

    if (ap->read("-k", &k) == ArgumentParser::ERROR) {
        return false;
    }
    else if (k < 0.0f) {
        std::cerr << "Invalid value (k): " << k << std::endl;
        return false;
    }

    if (ap->read("-numIterations", &numIterations) == ArgumentParser::ERROR) {
        return false;
    }
    else {
        numIterations = app_utility::clampParameter("numIterations", numIterations, 1, 10000);
    }

    return true;
}

SpecularCoordinatesBrdf* createBrdf(const ReflectanceModel& model,
                                    float                   n,
                                    int                     numIncomingPolarAngles,
                                    int                     numSpecularPolarAngles,
                                    int                     numSpecularAzimuthalAngles,
                                    DataType                dataType)
{
    SpecularCoordinatesBrdf* brdf = new SpecularCoordinatesBrdf(numIncomingPolarAngles,
                                                                1,
                                                                numSpecularPolarAngles,
                                                                numSpecularAzimuthalAngles,
                                                                2.0f,
                                                                MONOCHROMATIC_MODEL, 1, n);

    ReflectanceModelUtility::setupBrdf(model, brdf, dataType);

    if (intervalAdjustmentUsed) {
        const lb::SampleSet* ss = brdf->getSampleSet();

        // Save the number of angles before optimization.
        int numAngles0 = ss->getNumAngles0();
        int numAngles1 = ss->getNumAngles1();
        int numAngles2 = ss->getNumAngles2();
        int numAngles3 = ss->getNumAngles3();

        lb::Optimizer optimizer(brdf, 0.001f, 0.01f);
        optimizer.optimize();

        lb::ReflectanceModelUtility::setupBrdf(model, brdf,
                                               numAngles0, numAngles1, numAngles2, numAngles3,
                                               dataType, n);
    }

    brdf->setSourceType(GENERATED_SOURCE);

    return brdf;
}

int main(int argc, char** argv)
{
    Log::setNotificationLevel(Log::Level::WARN_MSG);

    ArgumentParser ap(argc, argv);

    if (ap.read("-h") || ap.read("--help") || ap.getTokens().empty()) {
        showHelp();
        return 0;
    }

    if (ap.read("-v") || ap.read("--version")) {
        app_utility::showAppVersion(APP_NAME, APP_VERSION);
        return 0;
    }

    if (ap.read("-l") || ap.read("--list")) {
        showList();
        return 0;
    }

    if (ap.read("-r") || ap.read("--reference")) {
        showReference();
        return 0;
    }

    if (!readOptions(&ap)) return 1;

    if (!ap.validateNumTokens(2)) return 1;

    std::string modelName = ap.getTokens().at(0);
    std::string fileName  = ap.getTokens().at(1);

    // Create a BRDF/BTDF model.
    std::unique_ptr<ReflectanceModel> model;
    const Vec3 white(1.0, 1.0, 1.0);
    if (modelName == GgxName) {
        roughness = app_utility::clampParameter("roughness", roughness, 0.01f, 1.0f);
        model.reset(new Ggx(white, roughness, n, k));
    }
    else if (modelName == MultipleScatteringSmithName) {
        roughness = app_utility::clampParameter("roughness", roughness, 0.01f, 1.0f);

        MultipleScatteringSmith::MaterialType matType = (k == 0.0f) ? MultipleScatteringSmith::DIELECTRIC_MATERIAL
                                                                    : MultipleScatteringSmith::CONDUCTOR_MATERIAL;

        model.reset(new MultipleScatteringSmith(white, roughness, roughness, n,
                                                static_cast<int>(matType),
                                                static_cast<int>(MultipleScatteringSmith::GAUSSIAN_HEIGHT),
                                                static_cast<int>(MultipleScatteringSmith::BECKMANN_SLOPE),
                                                numIterations));
    }
    else if (modelName == LambertianName) {
        n = 1.0f;
        model.reset(new Lambertian(white));
    }
    else {
        std::cerr << "Invalid model name: " << modelName << std::endl;
        return 1;
    }

    FileType fileType;
    if (reader_utility::hasSuffix(fileName, ".ssdd")) {
        fileType = SSDD_FILE;
    }
    else if (reader_utility::hasSuffix(fileName, ".ddr")) {
        fileType = INTEGRA_DDR_FILE;
    }
    else if (reader_utility::hasSuffix(fileName, ".ddt")) {
        fileType = INTEGRA_DDT_FILE;
    }
    else {
        fileType = UNKNOWN_FILE;
    }

    std::unique_ptr<SpecularCoordinatesBrdf> brdf, btdfData;

    // Create a BRDF.
    if (fileType != INTEGRA_DDT_FILE) {
        brdf.reset(createBrdf(*model,
                              1.0f,
                              numIncomingPolarAngles,
                              numSpecularPolarAngles,
                              numSpecularAzimuthalAngles,
                              BRDF_DATA));
    }

    // Create BTDF data in lb::SpecularCoordinatesBrdf.
    if (fileType != INTEGRA_DDR_FILE) {
        btdfData.reset(createBrdf(*model,
                                  n,
                                  numIncomingPolarAngles,
                                  numSpecularPolarAngles,
                                  numSpecularAzimuthalAngles,
                                  BTDF_DATA));
    }

    // Save files.
    std::string comments = app_utility::createComments(argc, argv, APP_NAME, APP_VERSION);
    if (fileType == INTEGRA_DDR_FILE) {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(brdf.get());
        }

        if (DdrWriter::write(fileName, *brdf, comments)) {
            std::cout << "Saved: " << fileName << std::endl;
        }
    }
    else if (fileType == INTEGRA_DDT_FILE) {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(btdfData.get());
        }

        if (DdrWriter::write(fileName, *btdfData, comments)) {
            std::cout << "Saved: " << fileName << std::endl;
        }
    }
    else {
        if (conservationOfEnergyUsed) {
            fixEnergyConservation(brdf.get(), btdfData.get());
        }

        if (fileType == SSDD_FILE) {
            std::unique_ptr<Btdf> btdf(new Btdf(std::move(btdfData)));
            std::unique_ptr<Bsdf> bsdf(new Bsdf(std::move(brdf), std::move(btdf)));
            std::unique_ptr<Material> material(new Material(std::move(bsdf)));

            if (SsddWriter::write(fileName, *material, SsddWriter::DataFormat::ASCII_DATA, comments)) {
                std::cout << "Saved: " << fileName << std::endl;
            }
        }
        else {
            if (DdrWriter::write(fileName + ".ddr", *brdf, comments)) {
                std::cout << "Saved: " << fileName + ".ddr" << std::endl;
            }

            if (DdrWriter::write(fileName + ".ddt", *btdfData, comments)) {
                std::cout << "Saved: " << fileName + ".ddt" << std::endl;
            }
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cassert>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <string>

#include "crib_hand_helper/card.h"
#include "crib_hand_helper/constants.h"
#include "crib_hand_helper/hand_counter.h"
#include "crib_hand_helper/hand_statistics.h"

using namespace crib;

bool validate_hand(const std::string& hand_string)
{
  if (hand_string.size() != 6)
  {
    return false;
  }

  for (const auto& card_char : hand_string)
  {
    // Must not be in hand more than four times
    if (std::count(hand_string.begin(), hand_string.end(), card_char) > 4)
    {
      return false;
    }

    // Capitalize letters
    auto card = card_char;
    if (!std::isdigit(card))
    {
      card = std::toupper(card);
    }

    // Must be in CARD_NAMES
    if (std::find(CARD_NAMES.begin(), CARD_NAMES.end(), card) ==
        CARD_NAMES.end())
    {
      return false;
    }
  }

  return true;
}

Hand parse_hand(const std::string& hand_string)
{
  assert(hand_string.size() == 6);

  const std::string suits = "cdhscd";

  Hand hand;
  for (std::string::size_type i = 0; i < hand_string.size(); ++i)
  {
    // Capitalize letters
    auto card = hand_string[i];
    if (!std::isdigit(card))
    {
      card = std::toupper(card);
    }

    hand.emplace_back(card, suits[i]);
  }

  return hand;
}

bool validate_suits(const std::string& suits, const Hand& hand)
{
  assert(suits.size() == 6);
  assert(hand.size() == 6);

  // Check if suits are all c, d, h, or s
  for (const auto& suit : suits)
  {
    if (std::find(CARD_SUITS.begin(), CARD_SUITS.end(), suit) ==
        CARD_SUITS.end())
    {
      std::cout << "One or more suits are invalid.\n";
      return false;
    }
  }

  // Check if two cards with the same rank have the same suit
  std::map<unsigned, std::vector<char>> rank_suits_map;
  auto suit_it = suits.cbegin();
  auto card_it = hand.cbegin();
  for (; suit_it != suits.cend() && card_it != hand.cend();
       ++suit_it, ++card_it)
  {
    auto& suits = rank_suits_map[card_it->rank];
    if (std::find(suits.begin(), suits.end(), *suit_it) != suits.end())
    {
      std::cout << "Two cards cannot have the same rank and suit.\n";
      return false;
    }
    suits.push_back(*suit_it);
  }

  return true;
}

void adjust_suits(Hand& hand)
{
  assert(hand.size() == 6);

  std::string suit_string;
  auto input_is_valid = false;
  while (!input_is_valid)
  {
    std::cout << "Enter suits: ";
    std::cin >> suit_string;
    if (suit_string.size() != 6)
    {
      std::cout << "Enter exactly six suits.\n";
      continue;
    }
    else if (!validate_suits(suit_string, hand))
    {
      continue;
    }
    input_is_valid = true;
  }

  // Adjust suits in hand
  for (std::string::size_type i = 0; i < suit_string.size(); ++i)
  {
    hand[i].suit = suit_string[i];
  }
}

void print_results(const std::vector<HandStatistics>& hand_statistics,
                   bool need_suits)
{
  assert(hand_statistics.size() == 15);

  auto discard_space = need_suits ? 12 : 10;
  std::cout << std::endl;
  std::cout << std::right << std::setw(discard_space) << "DISCARD" << std::right
            << std::setw(14) << "AVERAGE" << std::right << std::setw(7)
            << "HIGH" << std::setw(6) << std::right << "LOW" << std::endl;
  std::cout << std::right << std::setw(discard_space) << "-------" << std::right
            << std::setw(14) << "-----------" << std::right << std::setw(7)
            << "----" << std::setw(6) << std::right << "---" << std::endl;

  std::vector<std::string> previous_outputs;
  for (const auto& hs : hand_statistics)
  {
    std::string discard;
    if (need_suits)
    {
      discard = {hs.discard[0].name, hs.discard[0].suit, ' ',
                 hs.discard[1].name, hs.discard[1].suit};
    }
    else
    {
      discard = {hs.discard[0].name, ' ', hs.discard[1].name};
    }
    std::ostringstream output;
    output << std::setw(discard_space) << std::right << discard << std::setw(14)
           << std::right << std::fixed << std::setprecision(2) << std::setw(8)
           << std::right << hs.mean << " \u00b1 " << std::fixed
           << std::setprecision(1) << std::setw(3) << std::right << hs.std_dev
           << std::setw(7) << std::right << hs.best << std::setw(6)
           << std::right << hs.worst;

    // Don't print repeats
    if (std::find(previous_outputs.begin(), previous_outputs.end(),
                  output.str()) == previous_outputs.end())
    {
      std::cout << output.str() << std::endl;
      previous_outputs.push_back(output.str());
    }
  }
  std::cout << std::endl;
}

int main()
{
  while (true)
  {
    auto input_is_valid = false;
    std::string hand_string;

    // Get hand
    while (!input_is_valid)
    {
      std::cout << "Enter hand: ";
      std::cin >> hand_string;
      input_is_valid = validate_hand(hand_string);
      if (!input_is_valid)
      {
        std::cout << "Invalid hand. Try again.\n";
      }
    }

    // Make hand string upper case
    std::transform(hand_string.begin(), hand_string.end(), hand_string.begin(),
                   ::toupper);

    // Parse hand
    auto hand = parse_hand(hand_string);

    // Check if there is a Jack (will need suits in this case)
    bool need_suits = std::find(hand_string.begin(), hand_string.end(), 'J') !=
                      hand_string.end();
    if (need_suits)
    {
      std::cout << "You have a Jack in your hand. ";
    }

    // Check if there is a flush possibility (will need suits in this case);
    if (!need_suits)
    {
      input_is_valid = false;
      char response;
      while (!input_is_valid)
      {
        std::cout << "Are at least fours card the same suit? [y/n]: ";
        std::cin >> response;
        input_is_valid = response == 'y' || response == 'n';
        if (!input_is_valid)
        {
          std::cout << "Invalid selection. Please enter y or n.\n";
        }
      }
      need_suits = response == 'y';
    }

    // Adjust suits if necessary
    if (need_suits)
    {
      adjust_suits(hand);
    }

    // Get two all possible discards and corresponding keeps
    std::vector<Hand> all_discards, all_keeps;
    for (const auto& indices : SIX_CHOOSE_TWO_INDICES)
    {
      Hand discard, keep;
      for (Hand::size_type i = 0; i < hand.size(); ++i)
      {
        if (i == indices[0] || i == indices[1])
        {
          discard.push_back(hand[i]);
        }
        else
        {
          keep.push_back(hand[i]);
        }
      }
      all_discards.push_back(discard);
      all_keeps.push_back(keep);
    }

    // Calculate hand statistics
    std::vector<HandStatistics> all_hand_statistics;
    for (decltype(all_discards.size()) i = 0; i < all_discards.size(); ++i)
    {
      all_hand_statistics.push_back(
          get_hand_statistics(all_keeps[i], all_discards[i]));
    }

    // Sort from best average to worst average
    std::sort(all_hand_statistics.begin(), all_hand_statistics.end(),
              [](const HandStatistics& hs_1, const HandStatistics& hs_2) {
                return hs_1.mean > hs_2.mean;
              });

    print_results(all_hand_statistics, need_suits);
  }  // while (true)
}
<commit_msg>Buffer of std::cin now cleared properly when asking if four cards are the same suit.<commit_after>#include <algorithm>
#include <cassert>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <string>

#include "crib_hand_helper/card.h"
#include "crib_hand_helper/constants.h"
#include "crib_hand_helper/hand_counter.h"
#include "crib_hand_helper/hand_statistics.h"

using namespace crib;

bool validate_hand(const std::string& hand_string)
{
  if (hand_string.size() != 6)
  {
    return false;
  }

  for (const auto& card_char : hand_string)
  {
    // Must not be in hand more than four times
    if (std::count(hand_string.begin(), hand_string.end(), card_char) > 4)
    {
      return false;
    }

    // Capitalize letters
    auto card = card_char;
    if (!std::isdigit(card))
    {
      card = std::toupper(card);
    }

    // Must be in CARD_NAMES
    if (std::find(CARD_NAMES.begin(), CARD_NAMES.end(), card) ==
        CARD_NAMES.end())
    {
      return false;
    }
  }

  return true;
}

Hand parse_hand(const std::string& hand_string)
{
  assert(hand_string.size() == 6);

  const std::string suits = "cdhscd";

  Hand hand;
  for (std::string::size_type i = 0; i < hand_string.size(); ++i)
  {
    // Capitalize letters
    auto card = hand_string[i];
    if (!std::isdigit(card))
    {
      card = std::toupper(card);
    }

    hand.emplace_back(card, suits[i]);
  }

  return hand;
}

bool validate_suits(const std::string& suits, const Hand& hand)
{
  assert(suits.size() == 6);
  assert(hand.size() == 6);

  // Check if suits are all c, d, h, or s
  for (const auto& suit : suits)
  {
    if (std::find(CARD_SUITS.begin(), CARD_SUITS.end(), suit) ==
        CARD_SUITS.end())
    {
      std::cout << "One or more suits are invalid.\n";
      return false;
    }
  }

  // Check if two cards with the same rank have the same suit
  std::map<unsigned, std::vector<char>> rank_suits_map;
  auto suit_it = suits.cbegin();
  auto card_it = hand.cbegin();
  for (; suit_it != suits.cend() && card_it != hand.cend();
       ++suit_it, ++card_it)
  {
    auto& suits = rank_suits_map[card_it->rank];
    if (std::find(suits.begin(), suits.end(), *suit_it) != suits.end())
    {
      std::cout << "Two cards cannot have the same rank and suit.\n";
      return false;
    }
    suits.push_back(*suit_it);
  }

  return true;
}

void adjust_suits(Hand& hand)
{
  assert(hand.size() == 6);

  std::string suit_string;
  auto input_is_valid = false;
  while (!input_is_valid)
  {
    std::cout << "Enter suits: ";
    std::cin >> suit_string;
    if (suit_string.size() != 6)
    {
      std::cout << "Enter exactly six suits.\n";
      continue;
    }
    else if (!validate_suits(suit_string, hand))
    {
      continue;
    }
    input_is_valid = true;
  }

  // Adjust suits in hand
  for (std::string::size_type i = 0; i < suit_string.size(); ++i)
  {
    hand[i].suit = suit_string[i];
  }
}

void print_results(const std::vector<HandStatistics>& hand_statistics,
                   bool need_suits)
{
  assert(hand_statistics.size() == 15);

  auto discard_space = need_suits ? 12 : 10;
  std::cout << std::endl;
  std::cout << std::right << std::setw(discard_space) << "DISCARD" << std::right
            << std::setw(14) << "AVERAGE" << std::right << std::setw(7)
            << "HIGH" << std::setw(6) << std::right << "LOW" << std::endl;
  std::cout << std::right << std::setw(discard_space) << "-------" << std::right
            << std::setw(14) << "-----------" << std::right << std::setw(7)
            << "----" << std::setw(6) << std::right << "---" << std::endl;

  std::vector<std::string> previous_outputs;
  for (const auto& hs : hand_statistics)
  {
    std::string discard;
    if (need_suits)
    {
      discard = {hs.discard[0].name, hs.discard[0].suit, ' ',
                 hs.discard[1].name, hs.discard[1].suit};
    }
    else
    {
      discard = {hs.discard[0].name, ' ', hs.discard[1].name};
    }
    std::ostringstream output;
    output << std::setw(discard_space) << std::right << discard << std::setw(14)
           << std::right << std::fixed << std::setprecision(2) << std::setw(8)
           << std::right << hs.mean << " \u00b1 " << std::fixed
           << std::setprecision(1) << std::setw(3) << std::right << hs.std_dev
           << std::setw(7) << std::right << hs.best << std::setw(6)
           << std::right << hs.worst;

    // Don't print repeats
    if (std::find(previous_outputs.begin(), previous_outputs.end(),
                  output.str()) == previous_outputs.end())
    {
      std::cout << output.str() << std::endl;
      previous_outputs.push_back(output.str());
    }
  }
  std::cout << std::endl;
}

int main()
{
  while (true)
  {
    auto input_is_valid = false;
    std::string hand_string;

    // Get hand
    while (!input_is_valid)
    {
      std::cout << "Enter hand: ";
      std::cin >> hand_string;
      input_is_valid = validate_hand(hand_string);
      if (!input_is_valid)
      {
        std::cout << "Invalid hand. Try again.\n";
      }
    }

    // Make hand string upper case
    std::transform(hand_string.begin(), hand_string.end(), hand_string.begin(),
                   ::toupper);

    // Parse hand
    auto hand = parse_hand(hand_string);

    // Check if there is a Jack (will need suits in this case)
    bool need_suits = std::find(hand_string.begin(), hand_string.end(), 'J') !=
                      hand_string.end();
    if (need_suits)
    {
      std::cout << "You have a Jack in your hand. ";
    }

    // Check if there is a flush possibility (will need suits in this case);
    if (!need_suits)
    {
      input_is_valid = false;
      char response;
      while (!input_is_valid)
      {
        std::cout << "Are at least fours card the same suit? [y/n]: ";
        std::cin >> response;
        input_is_valid = response == 'y' || response == 'n';
        if (!input_is_valid)
        {
          std::cout << "Invalid selection. Please enter y or n.\n";
          std::cin.clear();
          std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
      }
      need_suits = response == 'y';
    }

    // Adjust suits if necessary
    if (need_suits)
    {
      adjust_suits(hand);
    }

    // Get two all possible discards and corresponding keeps
    std::vector<Hand> all_discards, all_keeps;
    for (const auto& indices : SIX_CHOOSE_TWO_INDICES)
    {
      Hand discard, keep;
      for (Hand::size_type i = 0; i < hand.size(); ++i)
      {
        if (i == indices[0] || i == indices[1])
        {
          discard.push_back(hand[i]);
        }
        else
        {
          keep.push_back(hand[i]);
        }
      }
      all_discards.push_back(discard);
      all_keeps.push_back(keep);
    }

    // Calculate hand statistics
    std::vector<HandStatistics> all_hand_statistics;
    for (decltype(all_discards.size()) i = 0; i < all_discards.size(); ++i)
    {
      all_hand_statistics.push_back(
          get_hand_statistics(all_keeps[i], all_discards[i]));
    }

    // Sort from best average to worst average
    std::sort(all_hand_statistics.begin(), all_hand_statistics.end(),
              [](const HandStatistics& hs_1, const HandStatistics& hs_2) {
                return hs_1.mean > hs_2.mean;
              });

    print_results(all_hand_statistics, need_suits);
  }  // while (true)
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "HalideRuntime.h"
#include "HalideRuntimeOpenGL.h"

#include "halide_blur_glsl.h"
#include "halide_ycc_glsl.h"

class Image {
public:
    enum Layout {
        Interleaved, Planar
    };

    buffer_t buf;

    Image(int w, int h, int c, int elem_size, Layout layout = Interleaved) {
        memset(&buf, 0, sizeof(buffer_t));
        buf.extent[0] = w;
        buf.extent[1] = h;
        buf.extent[2] = c;
        buf.elem_size = elem_size;

        if (layout == Interleaved) {
            buf.stride[0] = buf.extent[2];
            buf.stride[1] = buf.extent[0] * buf.stride[0];
            buf.stride[2] = 1;
        } else {
            buf.stride[0] = 1;
            buf.stride[1] = buf.extent[0] * buf.stride[0];
            buf.stride[2] = buf.extent[1] * buf.stride[1];
        }
        size_t size = w * h * c * elem_size;
        buf.host = (uint8_t*)malloc(size);
        memset(buf.host, 0, size);
        buf.host_dirty = true;
    }
    ~Image() {
        free(buf.host);
    }
};

void test_blur() {
    const int W = 12, H = 32, C = 3;
    Image input(W, H, C, sizeof(uint8_t), Image::Planar);
    Image output(W, H, C, sizeof(uint8_t), Image::Planar);

    fprintf(stderr, "test_blur\n");
    halide_blur_glsl(&input.buf, &output.buf);
    fprintf(stderr, "test_blur complete\n");
}

void test_ycc() {
    const int W = 12, H = 32, C = 3;
    Image input(W, H, C, sizeof(uint8_t), Image::Planar);
    Image output(W, H, C, sizeof(uint8_t), Image::Planar);

    fprintf(stderr, "test_ycc\n");
    halide_ycc_glsl(&input.buf, &output.buf);
    fprintf(stderr, "Ycc complete\n");
}

void test_device_sync() {
    const int W = 12, H = 32, C = 3;
    Image temp(W, H, C, sizeof(uint8_t), Image::Planar);

    int result = halide_device_malloc(nullptr, &temp.buf, halide_opengl_device_interface());
    if (result != 0) {
        fprintf(stderr, "halide_device_malloc failed with return %d.\n", result);
    } else {
        result = halide_device_sync(nullptr, &temp.buf);
        if (result != 0) {
            fprintf(stderr, "halide_device_sync failed with return %d.\n", result);
        } else {
            fprintf(stderr, "Test device sync complete.\n");
        }
    }
}

int main(int argc, char* argv[]) {
    test_blur();
    test_ycc();
    test_device_sync();
}
<commit_msg>Update opengl_test to use Buffer<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "HalideRuntime.h"
#include "HalideRuntimeOpenGL.h"
#include "HalideBuffer.h"

using Halide::Buffer;

#include "halide_blur_glsl.h"
#include "halide_ycc_glsl.h"

void test_blur() {
    const int W = 12, H = 32, C = 3;
    Buffer<uint8_t> input(W, H, C);
    Buffer<uint8_t> output(W, H, C);

    fprintf(stderr, "test_blur\n");
    halide_blur_glsl(input, output);
    fprintf(stderr, "test_blur complete\n");
}

void test_ycc() {
    const int W = 12, H = 32, C = 3;
    Buffer<uint8_t> input(W, H, C);
    Buffer<uint8_t> output(W, H, C);

    fprintf(stderr, "test_ycc\n");
    halide_ycc_glsl(input, output);
    fprintf(stderr, "Ycc complete\n");
}

void test_device_sync() {
    const int W = 12, H = 32, C = 3;
    Buffer<uint8_t> temp(W, H, C);

    temp.set_host_dirty();
    int result = temp.copy_to_device(halide_opengl_device_interface());
    if (result != 0) {
        fprintf(stderr, "halide_device_malloc failed with return %d.\n", result);
        abort();
    } else {
        result = temp.device_sync();
        if (result != 0) {
            fprintf(stderr, "halide_device_sync failed with return %d.\n", result);
            abort();
        } else {
            fprintf(stderr, "Test device sync complete.\n");
        }
    }
}

int main(int argc, char* argv[]) {
    test_blur();
    test_ycc();
    test_device_sync();
}
<|endoftext|>