<commit_before>
using namespace std;
#include "GEOMImpl_RevolutionDriver.hxx"
#include "GEOMImpl_IRevolution.hxx"
#include "GEOMImpl_Types.hxx"
#include "GEOM_Function.hxx"

#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>

#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <StdFail_NotDone.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_ConstructionError.hxx>

//=======================================================================
//function : GetID
//purpose  :
//=======================================================================
const Standard_GUID& GEOMImpl_RevolutionDriver::GetID()
{
  static Standard_GUID aRevolutionDriver("FF1BBB18-5D14-4df2-980B-3A668264EA16");
  return aRevolutionDriver;
}

//=======================================================================
//function : GEOMImpl_RevolutionDriver
//purpose  :
//=======================================================================
GEOMImpl_RevolutionDriver::GEOMImpl_RevolutionDriver()
{
}

//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_RevolutionDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IRevolution aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == REVOLUTION_BASE_AXIS_ANGLE) {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    Handle(GEOM_Function) aRefAxis = aCI.GetAxis();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    TopoDS_Shape aShapeAxis = aRefAxis->GetValue();
    if (aShapeAxis.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise("Revolution Axis must be an edge");
    }

    TopoDS_Edge anE = TopoDS::Edge(aShapeAxis);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (V1.IsNull() || V2.IsNull()) {
      Standard_ConstructionError::Raise("Bad edge for the Revolution Axis given");
    }

    gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
    if (aV.Magnitude() < Precision::Confusion()) {
      Standard_ConstructionError::Raise
        ("End vertices of edge, defining the Revolution Axis, are too close");
    }

    gp_Ax1 anAxis (BRep_Tool::Pnt(V1), aV);
    BRepPrimAPI_MakeRevol MR (aShapeBase, anAxis, aCI.GetAngle(), Standard_False);
    if (!MR.IsDone()) MR.Build();
    if (!MR.IsDone()) StdFail_NotDone::Raise("Revolution algorithm has failed");
    aShape = MR.Shape();
  } else {
  }

  if (aShape.IsNull()) return 0;
  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}

//=======================================================================
//function :  GEOMImpl_RevolutionDriver_Type_
//purpose  :
//=======================================================================
Standard_EXPORT Handle_Standard_Type& GEOMImpl_RevolutionDriver_Type_()
{

  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);

  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_RevolutionDriver",
			                                 sizeof(GEOMImpl_RevolutionDriver),
			                                 1,
			                                 (Standard_Address)_Ancestors,
			                                 (Standard_Address)NULL);

  return _aType;
}

//=======================================================================
//function : DownCast
//purpose  :
//=======================================================================
const Handle(GEOMImpl_RevolutionDriver) Handle(GEOMImpl_RevolutionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
{
  Handle(GEOMImpl_RevolutionDriver) _anOtherObject;

  if (!AnObject.IsNull()) {
     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_RevolutionDriver))) {
       _anOtherObject = Handle(GEOMImpl_RevolutionDriver)((Handle(GEOMImpl_RevolutionDriver)&)AnObject);
     }
  }

  return _anOtherObject ;
}
<commit_msg>if a shape to be rotated is a vertex, and it is located ON the Revolution Axis, then the algorithm builds a circle with null radius.  Incorrect, visualization of such shape fails.  This case is checked and revolution is not done in this case.<commit_after>
using namespace std;
#include "GEOMImpl_RevolutionDriver.hxx"
#include "GEOMImpl_IRevolution.hxx"
#include "GEOMImpl_Types.hxx"
#include "GEOM_Function.hxx"

#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>

#include <gp_Pnt.hxx>
#include <gp_Lin.hxx>
#include <gp_Dir.hxx>
#include <Precision.hxx>
#include <StdFail_NotDone.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_ConstructionError.hxx>

//=======================================================================
//function : GetID
//purpose  :
//=======================================================================
const Standard_GUID& GEOMImpl_RevolutionDriver::GetID()
{
  static Standard_GUID aRevolutionDriver("FF1BBB18-5D14-4df2-980B-3A668264EA16");
  return aRevolutionDriver;
}

//=======================================================================
//function : GEOMImpl_RevolutionDriver
//purpose  :
//=======================================================================
GEOMImpl_RevolutionDriver::GEOMImpl_RevolutionDriver()
{
}

//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_RevolutionDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IRevolution aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == REVOLUTION_BASE_AXIS_ANGLE) {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    Handle(GEOM_Function) aRefAxis = aCI.GetAxis();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    TopoDS_Shape aShapeAxis = aRefAxis->GetValue();
    if (aShapeAxis.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise("Revolution Axis must be an edge");
    }

    TopoDS_Edge anE = TopoDS::Edge(aShapeAxis);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (V1.IsNull() || V2.IsNull()) {
      Standard_ConstructionError::Raise("Bad edge for the Revolution Axis given");
    }

    gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
    if (aV.Magnitude() < Precision::Confusion()) {
      Standard_ConstructionError::Raise
        ("End vertices of edge, defining the Revolution Axis, are too close");
    }

    if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
      gp_Lin aL(BRep_Tool::Pnt(V1), gp_Dir(aV));
      Standard_Real d = aL.Distance(BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)));
      if (d < Precision::Confusion()) {
	Standard_ConstructionError::Raise("Vertex to be rotated is too close to Revolution Axis");
      }
    }

    gp_Ax1 anAxis (BRep_Tool::Pnt(V1), aV);
    BRepPrimAPI_MakeRevol MR (aShapeBase, anAxis, aCI.GetAngle(), Standard_False);
    if (!MR.IsDone()) MR.Build();
    if (!MR.IsDone()) StdFail_NotDone::Raise("Revolution algorithm has failed");
    aShape = MR.Shape();
  } else {
  }

  if (aShape.IsNull()) return 0;
  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}

//=======================================================================
//function :  GEOMImpl_RevolutionDriver_Type_
//purpose  :
//=======================================================================
Standard_EXPORT Handle_Standard_Type& GEOMImpl_RevolutionDriver_Type_()
{

  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);

  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_RevolutionDriver",
			                                 sizeof(GEOMImpl_RevolutionDriver),
			                                 1,
			                                 (Standard_Address)_Ancestors,
			                                 (Standard_Address)NULL);

  return _aType;
}

//=======================================================================
//function : DownCast
//purpose  :
//=======================================================================
const Handle(GEOMImpl_RevolutionDriver) Handle(GEOMImpl_RevolutionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
{
  Handle(GEOMImpl_RevolutionDriver) _anOtherObject;

  if (!AnObject.IsNull()) {
     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_RevolutionDriver))) {
       _anOtherObject = Handle(GEOMImpl_RevolutionDriver)((Handle(GEOMImpl_RevolutionDriver)&)AnObject);
     }
  }

  return _anOtherObject ;
}
<|endoftext|>


<commit_before>#include "assembler_class.hpp"

namespace flare32
{

Assembler::Assembler(char* s_input_filename)
{
	set_input_filename(s_input_filename);
	set_infile(fopen(input_filename(), "r"));

	if (infile() == nullptr)
	{
		err("Cannot read file");
	}

	fill_builtin_sym_tbl();
}

int Assembler::operator () ()
{
	//do
	//{
	//	reinit();

	//	advance();
	//	lex();

	//	while (next_tok() != &Tok::Eof)
	//	{
	//		line();
	//	}

	//} while (changed());

	// Two passes
	for (set_pass(0); pass() < 2; set_pass(pass() + 1))
	{
		reinit();

		advance();
		lex();

		while (next_tok() != &Tok::Eof)
		{
			line();
		}

		printout("\n\n");
	}

	return 0;
}

void Assembler::reinit()
{
	rewind(infile());
	set_line_num(1);
	set_next_char(' ');
	set_next_tok(nullptr);
	set_next_sym_str("");
	set_next_num(-1);
	//set_changed(false);
}

void Assembler::fill_builtin_sym_tbl()
{
	// General-purpose registers
	builtin_sym_tbl().insert_or_assign(Symbol("r0", &Tok::Reg, 0));
	builtin_sym_tbl().insert_or_assign(Symbol("r1", &Tok::Reg, 1));
	builtin_sym_tbl().insert_or_assign(Symbol("r2", &Tok::Reg, 2));
	builtin_sym_tbl().insert_or_assign(Symbol("r3", &Tok::Reg, 3));
	builtin_sym_tbl().insert_or_assign(Symbol("r4", &Tok::Reg, 4));
	builtin_sym_tbl().insert_or_assign(Symbol("r5", &Tok::Reg, 5));
	builtin_sym_tbl().insert_or_assign(Symbol("r6", &Tok::Reg, 6));
	builtin_sym_tbl().insert_or_assign(Symbol("r7", &Tok::Reg, 7));
	builtin_sym_tbl().insert_or_assign(Symbol("r8", &Tok::Reg, 8));
	builtin_sym_tbl().insert_or_assign(Symbol("r9", &Tok::Reg, 9));
	builtin_sym_tbl().insert_or_assign(Symbol("r10", &Tok::Reg, 10));
	builtin_sym_tbl().insert_or_assign(Symbol("r11", &Tok::Reg, 11));
	builtin_sym_tbl().insert_or_assign(Symbol("r12", &Tok::Reg, 12));
	builtin_sym_tbl().insert_or_assign(Symbol("r13", &Tok::Reg, 13));
	builtin_sym_tbl().insert_or_assign(Symbol("r14", &Tok::Reg, 14));
	builtin_sym_tbl().insert_or_assign(Symbol("r15", &Tok::Reg, 15));
	builtin_sym_tbl().insert_or_assign(Symbol("lr", &Tok::Reg, 14));
	builtin_sym_tbl().insert_or_assign(Symbol("sp", &Tok::Reg, 15));

	// Special-purpose registers
	builtin_sym_tbl().insert_or_assign(Symbol("pc", &Tok::RegPc, -1));
	builtin_sym_tbl().insert_or_assign(Symbol("ira", &Tok::RegIra, -1));
	builtin_sym_tbl().insert_or_assign(Symbol("flags", &Tok::RegFlags,
		-1));

	// Instructions
	for (const auto& outer_iter : __instr_tbl.instr_vec)
	{
		for (const auto& instr : *outer_iter)
		{
			builtin_sym_tbl().insert_or_assign(Symbol(instr->str(),
				&Tok::Instr, -1));
		}
	}
}

void Assembler::need(PTok tok)
{
	if (next_tok() == tok)
	{
		lex();
	}
	else
	{
		printerr("need():  ");
		expected_tokens(tok);
	}
}

void Assembler::advance()
{
	if (next_char() == EOF)
	{
		set_next_tok(&Tok::Eof);
		return;
	}

	//set_next_char(getchar());
	set_next_char(getc(infile()));

	if (next_char() == '\n')
	{
		++__line_num;
	}
}

void Assembler::lex()
{
	//while (isspace(next_char()) && (next_char() != '\n'))
	while (isspace(next_char()) && (next_char() != '\n'))
	{
		advance();
	}

	if (next_char() == '\n')
	{
		set_next_tok(&Tok::Newline);
		advance();
		return;
	}

	if (next_char() == EOF)
	{
		set_next_tok(&Tok::Eof);
		return;
	}

	std::string next_str;
	next_str += next_char();

	if (next_str == "")
	{
	}

	#define VARNAME(some_tok) \
		else if (next_str == Tok::some_tok.str()) \
		{ \
			set_next_tok(&Tok::some_tok); \
			advance(); \
			return; \
		}
	#define VALUE(some_str)

	LIST_OF_PUNCT_TOKENS(VARNAME, VALUE)
	LIST_OF_SINGLE_CHAR_OPERATOR_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	// Find an identifier
	if (isalpha(next_char()) || (next_char() == '_'))
	{
		//printout("lex():  An ident?\n");
		next_str = "";
		next_str += next_char();
		advance();

		while (isalnum(next_char()) || (next_char() == '_'))
		{
			next_str += next_char();
			advance();
		}

		//printout("lex():  next_str, next_char():  ", next_str, ", ",
		//	(char)next_char(), "\n");

		// If we haven't seen a user symbol like this before...
		if (!user_sym_tbl().contains(next_str))
		{
			// ...Then create a new symbol
			//printout("Creating a new symbol....\n");
			Symbol to_insert(next_str, &Tok::Ident, 0);

			user_sym_tbl().at(next_str) = to_insert;
		}

		if (builtin_sym_tbl().contains(next_str))
		{
			const Symbol& temp = builtin_sym_tbl().at(next_str);
			set_next_tok(temp.token());
		}
		else
		{
			set_next_tok(&Tok::Ident);
		}

		set_next_sym_str(next_str);

		return;
	}

	// The constant 0
	if (next_char() == '0')
	{
		set_next_num(0);
		set_next_tok(&Tok::NatNum);

		advance();

		if (isdigit(next_char()))
		{
			expected("Natural number that does not start with 0!");
		}
	}

	// Find a constant natural number
	if (isdigit(next_char()))
	{
		set_next_num(0);

		do
		{
			set_next_num((next_num() * 10) + (next_char() - '0'));
			advance();
		} while (isdigit(next_char()));

		set_next_tok(&Tok::NatNum);

		return;
	}

	// BitShL
	if (next_char() == '<')
	{
		advance();

		if (next_char() == '<')
		{
			advance();
			set_next_tok(&Tok::BitShL);
		}
		else
		{
			expected("\"<<\" but got \"", next_str, "\"!");
		}

		return;
	}

	// BitShR
	if (next_char() == '>')
	{
		advance();

		if (next_char() == '>')
		{
			advance();
			set_next_tok(&Tok::BitShR);
		}
		else
		{
			expected("\">>\" but got \"", next_str, "\"!");
		}

		return;
	}
}

void Assembler::line()
{
	printout("line():  ", next_tok()->str(), "\n");
	lex();
}

s64 Assembler::handle_expr()
{
	const auto old_next_tok = next_tok();

	s64 ret;

	if ((old_next_tok == &Tok::Plus) || (old_next_tok == &Tok::Minus))
	{
		lex();

		if (old_next_tok == &Tok::Plus)
		{
			ret = handle_term();
		}
		else // if (old_next_tok == &Tok::Minus)
		{
			ret = -handle_term();
		}
	}
	else
	{
		ret = handle_term();
	}

	if ((next_tok() == &Tok::Plus) || (next_tok() == &Tok::Minus))
	{
		ret += handle_expr();
	}

	return ret;

}

s64 Assembler::handle_term()
{
	s64 ret = handle_factor();

	while ((next_tok() == &Tok::Mult) || (next_tok() == &Tok::Div)
		|| (next_tok() == &Tok::BitAnd) || (next_tok() == &Tok::BitOr)
		|| (next_tok() == &Tok::BitXor) || (next_tok() == &Tok::BitShL)
		|| (next_tok() == &Tok::BitShR))
	{
		const auto old_next_tok = next_tok();
		lex();

		if (old_next_tok == &Tok::Mult)
		{
			ret *= handle_factor();
		}
		else if (old_next_tok == &Tok::Div)
		{
			ret /= handle_factor();
		}
		else if (old_next_tok == &Tok::BitAnd)
		{
			ret &= handle_factor();
		}
		else if (old_next_tok == &Tok::BitOr)
		{
			ret |= handle_factor();
		}
		else if (old_next_tok == &Tok::BitXor)
		{
			ret ^= handle_factor();
		}
		else if (old_next_tok == &Tok::BitShL)
		{
			ret <<= handle_factor();
		}
		else if (old_next_tok == &Tok::BitShR)
		{
			ret >>= handle_factor();
		}
	}

	return ret;
}

s64 Assembler::handle_factor()
{
	if (next_tok() == &Tok::NatNum)
	{
		s64 ret = next_num();
		lex();
		return ret;
	}
	//else if (next_tok() == &Tok::Ident)
	else if (next_tok_is_ident_ish())
	{
		// This works because handle_factor() should only be called when
		// we're not asking for a user symbol
		const Symbol& sym = user_sym_tbl().at(next_sym_str());
		s64 ret = sym.value();
		lex();
		return ret;
	}

	s64 ret;

	if (next_tok() != &Tok::LParen)
	{
		//expected("token of type \"", Tok::NatNum.str(), "\" or \"",
		//	Tok::Ident.str(), "\" or \"", Tok::LParen.str(), "\"!");
		expected_tokens(&Tok::NatNum, &Tok::Ident, &Tok::LParen);
	}

	need(&Tok::LParen);

	ret = handle_expr();

	need(&Tok::RParen);

	return ret;
}

bool Assembler::tok_is_punct(PTok some_tok) const
{
	if (some_tok == nullptr)
	{
	}

	#define VARNAME(other_tok) \
		else if (some_tok == &Tok::other_tok) \
		{ \
			return true; \
		}
	#define VALUE(other_str)

	LIST_OF_PUNCT_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	return false;
}

bool Assembler::tok_is_ident_ish(PTok some_tok) const
{
	if (some_tok == nullptr)
	{
	}

	#define VARNAME(other_tok) \
		else if (some_tok == &Tok::other_tok) \
		{ \
			return true; \
		}
	#define VALUE(other_str)

	LIST_OF_IDENT_ISH_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	return false;
}

}
<commit_msg>ParseNode stuff<commit_after>#include "assembler_class.hpp"

namespace flare32
{

Assembler::Assembler(char* s_input_filename)
{
	set_input_filename(s_input_filename);
	set_infile(fopen(input_filename(), "r"));

	if (infile() == nullptr)
	{
		err("Cannot read file");
	}

	fill_builtin_sym_tbl();
}

int Assembler::operator () ()
{
	//do
	//{
	//	reinit();

	//	advance();
	//	lex();

	//	while (next_tok() != &Tok::Eof)
	//	{
	//		line();
	//	}

	//} while (changed());

	// Two passes
	for (set_pass(0); pass() < 2; set_pass(pass() + 1))
	{
		reinit();

		advance();
		lex();

		while (next_tok() != &Tok::Eof)
		{
			line();
		}

		printout("\n\n");
	}

	return 0;
}

void Assembler::reinit()
{
	rewind(infile());
	set_line_num(1);
	set_next_char(' ');
	set_next_tok(nullptr);
	set_next_sym_str("");
	set_next_num(-1);
	//set_changed(false);
}

void Assembler::fill_builtin_sym_tbl()
{
	// General-purpose registers
	builtin_sym_tbl().insert_or_assign(Symbol("r0", &Tok::Reg, 0));
	builtin_sym_tbl().insert_or_assign(Symbol("r1", &Tok::Reg, 1));
	builtin_sym_tbl().insert_or_assign(Symbol("r2", &Tok::Reg, 2));
	builtin_sym_tbl().insert_or_assign(Symbol("r3", &Tok::Reg, 3));
	builtin_sym_tbl().insert_or_assign(Symbol("r4", &Tok::Reg, 4));
	builtin_sym_tbl().insert_or_assign(Symbol("r5", &Tok::Reg, 5));
	builtin_sym_tbl().insert_or_assign(Symbol("r6", &Tok::Reg, 6));
	builtin_sym_tbl().insert_or_assign(Symbol("r7", &Tok::Reg, 7));
	builtin_sym_tbl().insert_or_assign(Symbol("r8", &Tok::Reg, 8));
	builtin_sym_tbl().insert_or_assign(Symbol("r9", &Tok::Reg, 9));
	builtin_sym_tbl().insert_or_assign(Symbol("r10", &Tok::Reg, 10));
	builtin_sym_tbl().insert_or_assign(Symbol("r11", &Tok::Reg, 11));
	builtin_sym_tbl().insert_or_assign(Symbol("r12", &Tok::Reg, 12));
	builtin_sym_tbl().insert_or_assign(Symbol("r13", &Tok::Reg, 13));
	builtin_sym_tbl().insert_or_assign(Symbol("r14", &Tok::Reg, 14));
	builtin_sym_tbl().insert_or_assign(Symbol("r15", &Tok::Reg, 15));
	builtin_sym_tbl().insert_or_assign(Symbol("lr", &Tok::Reg, 14));
	builtin_sym_tbl().insert_or_assign(Symbol("sp", &Tok::Reg, 15));

	// Special-purpose registers
	builtin_sym_tbl().insert_or_assign(Symbol("pc", &Tok::RegPc, -1));
	builtin_sym_tbl().insert_or_assign(Symbol("ira", &Tok::RegIra, -1));
	builtin_sym_tbl().insert_or_assign(Symbol("flags", &Tok::RegFlags,
		-1));

	// Instructions
	for (const auto& outer_iter : __instr_tbl.instr_vec)
	{
		for (const auto& instr : *outer_iter)
		{
			builtin_sym_tbl().insert_or_assign(Symbol(instr->str(),
				&Tok::Instr, -1));
		}
	}
}

void Assembler::need(PTok tok)
{
	if (next_tok() == tok)
	{
		lex();
	}
	else
	{
		printerr("need():  ");
		expected_tokens(tok);
	}
}

void Assembler::advance()
{
	if (next_char() == EOF)
	{
		set_next_tok(&Tok::Eof);
		return;
	}

	//set_next_char(getchar());
	set_next_char(getc(infile()));

	if (next_char() == '\n')
	{
		++__line_num;
	}
}

void Assembler::lex()
{
	//while (isspace(next_char()) && (next_char() != '\n'))
	while (isspace(next_char()) && (next_char() != '\n'))
	{
		advance();
	}

	if (next_char() == '\n')
	{
		set_next_tok(&Tok::Newline);
		advance();
		return;
	}

	if (next_char() == EOF)
	{
		set_next_tok(&Tok::Eof);
		return;
	}

	std::string next_str;
	next_str += next_char();

	if (next_str == "")
	{
	}

	#define VARNAME(some_tok) \
		else if (next_str == Tok::some_tok.str()) \
		{ \
			set_next_tok(&Tok::some_tok); \
			advance(); \
			return; \
		}
	#define VALUE(some_str)

	LIST_OF_PUNCT_TOKENS(VARNAME, VALUE)
	LIST_OF_SINGLE_CHAR_OPERATOR_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	// Find an identifier
	if (isalpha(next_char()) || (next_char() == '_'))
	{
		//printout("lex():  An ident?\n");
		next_str = "";
		next_str += next_char();
		advance();

		while (isalnum(next_char()) || (next_char() == '_'))
		{
			next_str += next_char();
			advance();
		}

		//printout("lex():  next_str, next_char():  ", next_str, ", ",
		//	(char)next_char(), "\n");

		// If we haven't seen a user symbol like this before...
		if (!user_sym_tbl().contains(next_str))
		{
			// ...Then create a new symbol
			//printout("Creating a new symbol....\n");
			Symbol to_insert(next_str, &Tok::Ident, 0);

			user_sym_tbl().at(next_str) = to_insert;
		}

		if (builtin_sym_tbl().contains(next_str))
		{
			const Symbol& temp = builtin_sym_tbl().at(next_str);
			set_next_tok(temp.token());
		}
		else
		{
			set_next_tok(&Tok::Ident);
		}

		set_next_sym_str(next_str);

		return;
	}

	// The constant 0
	if (next_char() == '0')
	{
		set_next_num(0);
		set_next_tok(&Tok::NatNum);

		advance();

		if (isdigit(next_char()))
		{
			expected("Natural number that does not start with 0!");
		}
	}

	// Find a constant natural number
	if (isdigit(next_char()))
	{
		set_next_num(0);

		do
		{
			set_next_num((next_num() * 10) + (next_char() - '0'));
			advance();
		} while (isdigit(next_char()));

		set_next_tok(&Tok::NatNum);

		return;
	}

	// BitShL
	if (next_char() == '<')
	{
		advance();

		if (next_char() == '<')
		{
			advance();
			set_next_tok(&Tok::BitShL);
		}
		else
		{
			expected("\"<<\" but got \"", next_str, "\"!");
		}

		return;
	}

	// BitShR
	if (next_char() == '>')
	{
		advance();

		if (next_char() == '>')
		{
			advance();
			set_next_tok(&Tok::BitShR);
		}
		else
		{
			expected("\">>\" but got \"", next_str, "\"!");
		}

		return;
	}
}

void Assembler::line()
{
	//printout("line():  ", next_tok()->str(), "\n");
	//lex();

	// Why the crap did I **not** do something like this the first time.
	// It makes things easier to build a parse "tree" for the current line.
	std::vector<ParseNode> parse_vec;

	while (next_tok() != &Tok::Newline)
	{
		parse_vec.push_back(ParseNode(next_tok(), next_sym_str(),
			next_num()));
		lex();
	}

	for (const auto& node : parse_vec)
	{
		printout(node.next_tok->str(), "\t\t");
	}
	printout("\n");

	lex();

}

s64 Assembler::handle_expr()
{
	const auto old_next_tok = next_tok();

	s64 ret;

	if ((old_next_tok == &Tok::Plus) || (old_next_tok == &Tok::Minus))
	{
		lex();

		if (old_next_tok == &Tok::Plus)
		{
			ret = handle_term();
		}
		else // if (old_next_tok == &Tok::Minus)
		{
			ret = -handle_term();
		}
	}
	else
	{
		ret = handle_term();
	}

	if ((next_tok() == &Tok::Plus) || (next_tok() == &Tok::Minus))
	{
		ret += handle_expr();
	}

	return ret;

}

s64 Assembler::handle_term()
{
	s64 ret = handle_factor();

	while ((next_tok() == &Tok::Mult) || (next_tok() == &Tok::Div)
		|| (next_tok() == &Tok::BitAnd) || (next_tok() == &Tok::BitOr)
		|| (next_tok() == &Tok::BitXor) || (next_tok() == &Tok::BitShL)
		|| (next_tok() == &Tok::BitShR))
	{
		const auto old_next_tok = next_tok();
		lex();

		if (old_next_tok == &Tok::Mult)
		{
			ret *= handle_factor();
		}
		else if (old_next_tok == &Tok::Div)
		{
			ret /= handle_factor();
		}
		else if (old_next_tok == &Tok::BitAnd)
		{
			ret &= handle_factor();
		}
		else if (old_next_tok == &Tok::BitOr)
		{
			ret |= handle_factor();
		}
		else if (old_next_tok == &Tok::BitXor)
		{
			ret ^= handle_factor();
		}
		else if (old_next_tok == &Tok::BitShL)
		{
			ret <<= handle_factor();
		}
		else if (old_next_tok == &Tok::BitShR)
		{
			ret >>= handle_factor();
		}
	}

	return ret;
}

s64 Assembler::handle_factor()
{
	if (next_tok() == &Tok::NatNum)
	{
		s64 ret = next_num();
		lex();
		return ret;
	}
	//else if (next_tok() == &Tok::Ident)
	else if (next_tok_is_ident_ish())
	{
		// This works because handle_factor() should only be called when
		// we're not asking for a user symbol
		const Symbol& sym = user_sym_tbl().at(next_sym_str());
		s64 ret = sym.value();
		lex();
		return ret;
	}

	s64 ret;

	if (next_tok() != &Tok::LParen)
	{
		//expected("token of type \"", Tok::NatNum.str(), "\" or \"",
		//	Tok::Ident.str(), "\" or \"", Tok::LParen.str(), "\"!");
		expected_tokens(&Tok::NatNum, &Tok::Ident, &Tok::LParen);
	}

	need(&Tok::LParen);

	ret = handle_expr();

	need(&Tok::RParen);

	return ret;
}

bool Assembler::tok_is_punct(PTok some_tok) const
{
	if (some_tok == nullptr)
	{
	}

	#define VARNAME(other_tok) \
		else if (some_tok == &Tok::other_tok) \
		{ \
			return true; \
		}
	#define VALUE(other_str)

	LIST_OF_PUNCT_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	return false;
}

bool Assembler::tok_is_ident_ish(PTok some_tok) const
{
	if (some_tok == nullptr)
	{
	}

	#define VARNAME(other_tok) \
		else if (some_tok == &Tok::other_tok) \
		{ \
			return true; \
		}
	#define VALUE(other_str)

	LIST_OF_IDENT_ISH_TOKENS(VARNAME, VALUE)

	#undef VARNAME
	#undef VALUE

	return false;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/atom_browser_client.h"

#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/native_window.h"
#include "atom/browser/window_list.h"
#include "chrome/browser/printing/printing_message_filter.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/common/webpreferences.h"

namespace atom {

namespace {

struct FindByProcessId {
  explicit FindByProcessId(int child_process_id)
      : child_process_id_(child_process_id) {
  }

  bool operator() (NativeWindow* const window) {
    content::WebContents* web_contents = window->GetWebContents();
    if (!web_contents)
      return false;

    int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
    return id == child_process_id_;
  }

  int child_process_id_;
};

}  // namespace

AtomBrowserClient::AtomBrowserClient()
    : dying_render_process_(NULL) {
}

AtomBrowserClient::~AtomBrowserClient() {
}

void AtomBrowserClient::RenderProcessWillLaunch(
    content::RenderProcessHost* host) {
  host->AddFilter(new PrintingMessageFilter(host->GetID()));
}

void AtomBrowserClient::ResourceDispatcherHostCreated() {
  resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
  content::ResourceDispatcherHost::Get()->SetDelegate(
      resource_dispatcher_delegate_.get());
}

content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
  return new AtomAccessTokenStore;
}

void AtomBrowserClient::OverrideWebkitPrefs(
    content::RenderViewHost* render_view_host,
    const GURL& url,
    WebPreferences* prefs) {
  prefs->javascript_enabled = true;
  prefs->web_security_enabled = true;
  prefs->javascript_can_open_windows_automatically = true;
  prefs->plugins_enabled = false;
  prefs->dom_paste_enabled = true;
  prefs->java_enabled = false;
  prefs->allow_scripts_to_close_windows = true;
  prefs->javascript_can_access_clipboard = true;
  prefs->local_storage_enabled = true;
  prefs->databases_enabled = true;
  prefs->application_cache_enabled = true;
  prefs->allow_universal_access_from_file_urls = true;
  prefs->allow_file_access_from_file_urls = true;
  prefs->experimental_webgl_enabled = true;
  prefs->allow_displaying_insecure_content = true;
  prefs->allow_running_insecure_content = true;

  NativeWindow* window = NativeWindow::FromRenderView(
      render_view_host->GetProcess()->GetID(),
      render_view_host->GetRoutingID());
  if (window)
    window->OverrideWebkitPrefs(url, prefs);
}

bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
    content::SiteInstance* site_instance,
    const GURL& current_url,
    const GURL& new_url) {
  if (site_instance->HasProcess())
    dying_render_process_ = site_instance->GetProcess();

  // Restart renderer process for all navigations, this relies on a patch to
  // Chromium: http://git.io/_PaNyg.
  return true;
}

std::string AtomBrowserClient::GetApplicationLocale() {
  return l10n_util::GetApplicationLocale("");
}

void AtomBrowserClient::AppendExtraCommandLineSwitches(
    base::CommandLine* command_line,
    int child_process_id) {
  WindowList* list = WindowList::GetInstance();
  NativeWindow* window = NULL;

  // Find the owner of this child process.
  WindowList::const_iterator iter = std::find_if(
      list->begin(), list->end(), FindByProcessId(child_process_id));
  if (iter != list->end())
    window = *iter;

  // If the render process is a newly started one, which means the window still
  // uses the old going-to-be-swapped render process, then we try to find the
  // window from the swapped render process.
  if (window == NULL && dying_render_process_ != NULL) {
    child_process_id = dying_render_process_->GetID();
    WindowList::const_iterator iter = std::find_if(
        list->begin(), list->end(), FindByProcessId(child_process_id));
    if (iter != list->end())
      window = *iter;
  }

  if (window != NULL)
    window->AppendExtraCommandLineSwitches(command_line, child_process_id);

  dying_render_process_ = NULL;
}

brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
    const content::MainFunctionParams&) {
  v8::V8::Initialize();  // Init V8 before creating main parts.
  return new AtomBrowserMainParts;
}

}  // namespace atom
<commit_msg>Turn off web security for devtools.<commit_after>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/atom_browser_client.h"

#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/native_window.h"
#include "atom/browser/window_list.h"
#include "chrome/browser/printing/printing_message_filter.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/common/webpreferences.h"

namespace atom {

namespace {

struct FindByProcessId {
  explicit FindByProcessId(int child_process_id)
      : child_process_id_(child_process_id) {
  }

  bool operator() (NativeWindow* const window) {
    content::WebContents* web_contents = window->GetWebContents();
    if (!web_contents)
      return false;

    int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
    return id == child_process_id_;
  }

  int child_process_id_;
};

}  // namespace

AtomBrowserClient::AtomBrowserClient()
    : dying_render_process_(NULL) {
}

AtomBrowserClient::~AtomBrowserClient() {
}

void AtomBrowserClient::RenderProcessWillLaunch(
    content::RenderProcessHost* host) {
  host->AddFilter(new PrintingMessageFilter(host->GetID()));
}

void AtomBrowserClient::ResourceDispatcherHostCreated() {
  resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
  content::ResourceDispatcherHost::Get()->SetDelegate(
      resource_dispatcher_delegate_.get());
}

content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
  return new AtomAccessTokenStore;
}

void AtomBrowserClient::OverrideWebkitPrefs(
    content::RenderViewHost* render_view_host,
    const GURL& url,
    WebPreferences* prefs) {
  prefs->javascript_enabled = true;
  prefs->web_security_enabled = true;
  prefs->javascript_can_open_windows_automatically = true;
  prefs->plugins_enabled = false;
  prefs->dom_paste_enabled = true;
  prefs->java_enabled = false;
  prefs->allow_scripts_to_close_windows = true;
  prefs->javascript_can_access_clipboard = true;
  prefs->local_storage_enabled = true;
  prefs->databases_enabled = true;
  prefs->application_cache_enabled = true;
  prefs->allow_universal_access_from_file_urls = true;
  prefs->allow_file_access_from_file_urls = true;
  prefs->experimental_webgl_enabled = true;
  prefs->allow_displaying_insecure_content = true;
  prefs->allow_running_insecure_content = true;

  // Turn off web security for devtools.
  if (url.SchemeIs("chrome-devtools")) {
    prefs->web_security_enabled = false;
    return;
  }

  NativeWindow* window = NativeWindow::FromRenderView(
      render_view_host->GetProcess()->GetID(),
      render_view_host->GetRoutingID());
  if (window)
    window->OverrideWebkitPrefs(url, prefs);
}

bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
    content::SiteInstance* site_instance,
    const GURL& current_url,
    const GURL& new_url) {
  if (site_instance->HasProcess())
    dying_render_process_ = site_instance->GetProcess();

  // Restart renderer process for all navigations, this relies on a patch to
  // Chromium: http://git.io/_PaNyg.
  return true;
}

std::string AtomBrowserClient::GetApplicationLocale() {
  return l10n_util::GetApplicationLocale("");
}

void AtomBrowserClient::AppendExtraCommandLineSwitches(
    base::CommandLine* command_line,
    int child_process_id) {
  WindowList* list = WindowList::GetInstance();
  NativeWindow* window = NULL;

  // Find the owner of this child process.
  WindowList::const_iterator iter = std::find_if(
      list->begin(), list->end(), FindByProcessId(child_process_id));
  if (iter != list->end())
    window = *iter;

  // If the render process is a newly started one, which means the window still
  // uses the old going-to-be-swapped render process, then we try to find the
  // window from the swapped render process.
  if (window == NULL && dying_render_process_ != NULL) {
    child_process_id = dying_render_process_->GetID();
    WindowList::const_iterator iter = std::find_if(
        list->begin(), list->end(), FindByProcessId(child_process_id));
    if (iter != list->end())
      window = *iter;
  }

  if (window != NULL)
    window->AppendExtraCommandLineSwitches(command_line, child_process_id);

  dying_render_process_ = NULL;
}

brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
    const content::MainFunctionParams&) {
  v8::V8::Initialize();  // Init V8 before creating main parts.
  return new AtomBrowserMainParts;
}

}  // namespace atom
<|endoftext|>


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

#include <stdlib.h>
#include <votca/csg/beadlist.h>
#include <votca/csg/csgapplication.h>
#include <votca/csg/nblist.h>
#include <votca/csg/nblistgrid.h>
#include <votca/tools/histogramnew.h>

using namespace std;
using namespace votca::csg;

class OrientCorrApp : public CsgApplication {

  string ProgramName() override { return "orientcorr"; }

  void HelpText(ostream &out) override {
    out << "Calculates the orientational correlation function\n"
           "    <3/2*u(0)*u(r) - 1/2>\n"
           "for a polymer melt, where u is the vector pointing along a bond "
           "and \n"
           "r the distance between bond segments (centered on middle of "
           "bond).\n\n"
           "The output is correlation.dat (with intra-molecular contributions) "
           "and\n"
           "correlation_excl.dat, where inter-molecular contributions are "
           "excluded.";
  }

  void Initialize() override;

  bool DoTrajectory() override { return true; }
  // do a threaded analyzis, splitting in time domain
  bool DoThreaded() override { return true; }
  // we don't care about the order of the analyzed frames
  bool SynchronizeThreads() override { return false; }

  // called before groing through all frames
  void BeginEvaluate(Topology *top, Topology *top_ref) override;
  // called after all frames were parsed
  void EndEvaluate() override;

  // creates a worker for a thread
  CsgApplication::Worker *ForkWorker(void) override;
  // merge data of worker into main
  void MergeWorker(Worker *worker) override;

 public:
  // helper class to choose nbsearch algorithm
  static NBList *CreateNBSearch();

 protected:
  votca::tools::HistogramNew _cor;
  votca::tools::HistogramNew _count;
  votca::tools::HistogramNew _cor_excl;
  votca::tools::HistogramNew _count_excl;
  static string _nbmethod;
  double _cut_off;
  votca::Index _nbins;
};

string OrientCorrApp::_nbmethod;

// Earch thread has a worker and analysis data
class MyWorker : public CsgApplication::Worker {
 public:
  ~MyWorker() override = default;

  // evaluate the current frame
  void EvalConfiguration(Topology *top, Topology *top_ref) override;

  // callback if neighborsearch finds a pair
  bool FoundPair(Bead *b1, Bead *b2, const Eigen::Vector3d &r,
                 const double dist);

  // accumulator of the 3/2*u(0)u(r) - 1/2
  votca::tools::HistogramNew _cor;
  // number of hits for each bin
  votca::tools::HistogramNew _count;
  // accumulator of the 3/2*u(0)u(r) - 1/2, only inter-molecular
  votca::tools::HistogramNew _cor_excl;
  // number of hits for each bin, only inter-molecular
  votca::tools::HistogramNew _count_excl;
  double _cut_off;
};

int main(int argc, char **argv) {
  OrientCorrApp app;
  return app.Exec(argc, argv);
}

// add some program options
void OrientCorrApp::Initialize() {
  // add all standard application options
  CsgApplication::Initialize();
  // some application specific options
  AddProgramOptions("Neighbor search options")(
      "cutoff,c",
      boost::program_options::value<double>(&_cut_off)->default_value(1.0),
      "cutoff for the neighbor search")(
      "nbins",
      boost::program_options::value<votca::Index>(&_nbins)->default_value(40),
      "number of bins for the grid")(
      "nbmethod",
      boost::program_options::value<string>(&_nbmethod)->default_value("grid"),
      "neighbor search algorithm (simple or grid)");
}

NBList *OrientCorrApp::CreateNBSearch() {
  if (_nbmethod == "simple") {
    return new NBList();
  }
  if (_nbmethod == "grid") {
    return new NBListGrid();
  }

  throw std::runtime_error(
      "unknown neighbor search method, use simple or grid");
  return nullptr;
}

// initialize the histograms
void OrientCorrApp::BeginEvaluate(Topology *, Topology *) {
  _cor.Initialize(0, _cut_off, _nbins);
  _count.Initialize(0, _cut_off, _nbins);
  _cor_excl.Initialize(0, _cut_off, _nbins);
  _count_excl.Initialize(0, _cut_off, _nbins);
}

// creates worker for each thread
CsgApplication::Worker *OrientCorrApp::ForkWorker() {
  MyWorker *worker;
  worker = new MyWorker();
  worker->_cut_off = _cut_off;
  worker->_cor.Initialize(0, worker->_cut_off, _nbins);
  worker->_count.Initialize(0, worker->_cut_off, _nbins);
  worker->_cor_excl.Initialize(0, worker->_cut_off, _nbins);
  worker->_count_excl.Initialize(0, worker->_cut_off, _nbins);
  return worker;
}

// evaluates a frame
void MyWorker::EvalConfiguration(Topology *top, Topology *) {

  // first genearate a mapped topology
  // the beads are sitting on the bonds and have an orientation which
  // is pointing along bond direction
  Topology mapped;
  cout << "generating mapped topology...";

  // copy box size
  mapped.setBox(top->getBox());

  // loop over all molecules
  for (auto mol_src : top->Molecules()) {
    // create a molecule in mapped topology
    Molecule *mol = mapped.CreateMolecule(mol_src->getName());
    // loop over beads in molecule
    for (votca::Index i = 0; i < mol_src->BeadCount() - 1; ++i) {
      // create a bead in mapped topology
      string bead_type = "A";
      if (mapped.BeadTypeExist(bead_type) == false) {
        mapped.RegisterBeadType(bead_type);
      }
      Bead *b =
          mapped.CreateBead(Bead::ellipsoidal, "A", bead_type, 1, 0.0, 0.0);
      Eigen::Vector3d p1 = mol_src->getBead(i)->getPos();
      Eigen::Vector3d p2 = mol_src->getBead(i + 1)->getPos();
      // position is in middle of bond
      Eigen::Vector3d pos = 0.5 * (p1 + p2);
      // orientation pointing along bond
      Eigen::Vector3d v = p2 - p1;
      v.normalize();
      b->setPos(pos);
      b->setV(v);
      mol->AddBead(b, "A");
    }
  }
  cout << "done\n";

  // the neighbor search only finds pairs, add self-self correlation parts here
  _cor.Process(0.0f, (double)mapped.BeadCount());
  _count.Process(0.0f, (double)mapped.BeadCount());

  // search for all beads
  BeadList b;
  b.Generate(mapped, "*");

  // create/initialize neighborsearch
  std::unique_ptr<NBList> nb =
      std::unique_ptr<NBList>(OrientCorrApp::CreateNBSearch());
  nb->setCutoff(_cut_off);

  // set callback for each pair found
  nb->SetMatchFunction(this, &MyWorker::FoundPair);

  // execute the search
  nb->Generate(b);
}

// process a pair, since return value is falsed, pairs are not cached which
// saves a lot of memory for the big systems
bool MyWorker::FoundPair(Bead *b1, Bead *b2, const Eigen::Vector3d &,
                         const double dist) {
  double tmp = b1->getV().dot(b2->getV());
  double P2 = 3. / 2. * tmp * tmp - 0.5;

  // calculate average without exclusions
  _cor.Process(dist, P2);
  _count.Process(dist);

  if (b1->getMolecule() == b2->getMolecule()) {
    return false;
  }

  // calculate average with excluding intramolecular contributions
  _cor_excl.Process(dist, P2);
  _count_excl.Process(dist);

  return false;
}

// merge analysed data of a worker into main applications
void OrientCorrApp::MergeWorker(Worker *worker) {
  MyWorker *myWorker = dynamic_cast<MyWorker *>(worker);
  _cor.data().y() += myWorker->_cor.data().y();
  _count.data().y() += myWorker->_count.data().y();
  _cor_excl.data().y() += myWorker->_cor_excl.data().y();
  _count_excl.data().y() += myWorker->_count_excl.data().y();
}

// write out the data
void OrientCorrApp::EndEvaluate() {
  _cor.data().y() = _cor.data().y().cwiseQuotient(_count.data().y());
  _cor.data().Save("correlation.dat");

  _cor_excl.data().y() =
      _cor_excl.data().y().cwiseQuotient(_count_excl.data().y());
  _cor_excl.data().Save("correlation_excl.dat");
}
<commit_msg>Changed getMolecule to getMoleculeId in orientcorr<commit_after>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <stdlib.h>
#include <votca/csg/beadlist.h>
#include <votca/csg/csgapplication.h>
#include <votca/csg/nblist.h>
#include <votca/csg/nblistgrid.h>
#include <votca/tools/histogramnew.h>

using namespace std;
using namespace votca::csg;

class OrientCorrApp : public CsgApplication {

  string ProgramName() override { return "orientcorr"; }

  void HelpText(ostream &out) override {
    out << "Calculates the orientational correlation function\n"
           "    <3/2*u(0)*u(r) - 1/2>\n"
           "for a polymer melt, where u is the vector pointing along a bond "
           "and \n"
           "r the distance between bond segments (centered on middle of "
           "bond).\n\n"
           "The output is correlation.dat (with intra-molecular contributions) "
           "and\n"
           "correlation_excl.dat, where inter-molecular contributions are "
           "excluded.";
  }

  void Initialize() override;

  bool DoTrajectory() override { return true; }
  // do a threaded analyzis, splitting in time domain
  bool DoThreaded() override { return true; }
  // we don't care about the order of the analyzed frames
  bool SynchronizeThreads() override { return false; }

  // called before groing through all frames
  void BeginEvaluate(Topology *top, Topology *top_ref) override;
  // called after all frames were parsed
  void EndEvaluate() override;

  // creates a worker for a thread
  CsgApplication::Worker *ForkWorker(void) override;
  // merge data of worker into main
  void MergeWorker(Worker *worker) override;

 public:
  // helper class to choose nbsearch algorithm
  static NBList *CreateNBSearch();

 protected:
  votca::tools::HistogramNew _cor;
  votca::tools::HistogramNew _count;
  votca::tools::HistogramNew _cor_excl;
  votca::tools::HistogramNew _count_excl;
  static string _nbmethod;
  double _cut_off;
  votca::Index _nbins;
};

string OrientCorrApp::_nbmethod;

// Earch thread has a worker and analysis data
class MyWorker : public CsgApplication::Worker {
 public:
  ~MyWorker() override = default;

  // evaluate the current frame
  void EvalConfiguration(Topology *top, Topology *top_ref) override;

  // callback if neighborsearch finds a pair
  bool FoundPair(Bead *b1, Bead *b2, const Eigen::Vector3d &r,
                 const double dist);

  // accumulator of the 3/2*u(0)u(r) - 1/2
  votca::tools::HistogramNew _cor;
  // number of hits for each bin
  votca::tools::HistogramNew _count;
  // accumulator of the 3/2*u(0)u(r) - 1/2, only inter-molecular
  votca::tools::HistogramNew _cor_excl;
  // number of hits for each bin, only inter-molecular
  votca::tools::HistogramNew _count_excl;
  double _cut_off;
};

int main(int argc, char **argv) {
  OrientCorrApp app;
  return app.Exec(argc, argv);
}

// add some program options
void OrientCorrApp::Initialize() {
  // add all standard application options
  CsgApplication::Initialize();
  // some application specific options
  AddProgramOptions("Neighbor search options")(
      "cutoff,c",
      boost::program_options::value<double>(&_cut_off)->default_value(1.0),
      "cutoff for the neighbor search")(
      "nbins",
      boost::program_options::value<votca::Index>(&_nbins)->default_value(40),
      "number of bins for the grid")(
      "nbmethod",
      boost::program_options::value<string>(&_nbmethod)->default_value("grid"),
      "neighbor search algorithm (simple or grid)");
}

NBList *OrientCorrApp::CreateNBSearch() {
  if (_nbmethod == "simple") {
    return new NBList();
  }
  if (_nbmethod == "grid") {
    return new NBListGrid();
  }

  throw std::runtime_error(
      "unknown neighbor search method, use simple or grid");
  return nullptr;
}

// initialize the histograms
void OrientCorrApp::BeginEvaluate(Topology *, Topology *) {
  _cor.Initialize(0, _cut_off, _nbins);
  _count.Initialize(0, _cut_off, _nbins);
  _cor_excl.Initialize(0, _cut_off, _nbins);
  _count_excl.Initialize(0, _cut_off, _nbins);
}

// creates worker for each thread
CsgApplication::Worker *OrientCorrApp::ForkWorker() {
  MyWorker *worker;
  worker = new MyWorker();
  worker->_cut_off = _cut_off;
  worker->_cor.Initialize(0, worker->_cut_off, _nbins);
  worker->_count.Initialize(0, worker->_cut_off, _nbins);
  worker->_cor_excl.Initialize(0, worker->_cut_off, _nbins);
  worker->_count_excl.Initialize(0, worker->_cut_off, _nbins);
  return worker;
}

// evaluates a frame
void MyWorker::EvalConfiguration(Topology *top, Topology *) {

  // first genearate a mapped topology
  // the beads are sitting on the bonds and have an orientation which
  // is pointing along bond direction
  Topology mapped;
  cout << "generating mapped topology...";

  // copy box size
  mapped.setBox(top->getBox());

  // loop over all molecules
  for (auto mol_src : top->Molecules()) {
    // create a molecule in mapped topology
    Molecule *mol = mapped.CreateMolecule(mol_src->getName());
    // loop over beads in molecule
    for (votca::Index i = 0; i < mol_src->BeadCount() - 1; ++i) {
      // create a bead in mapped topology
      string bead_type = "A";
      if (mapped.BeadTypeExist(bead_type) == false) {
        mapped.RegisterBeadType(bead_type);
      }
      Bead *b =
          mapped.CreateBead(Bead::ellipsoidal, "A", bead_type, 1, 0.0, 0.0);
      Eigen::Vector3d p1 = mol_src->getBead(i)->getPos();
      Eigen::Vector3d p2 = mol_src->getBead(i + 1)->getPos();
      // position is in middle of bond
      Eigen::Vector3d pos = 0.5 * (p1 + p2);
      // orientation pointing along bond
      Eigen::Vector3d v = p2 - p1;
      v.normalize();
      b->setPos(pos);
      b->setV(v);
      mol->AddBead(b, "A");
    }
  }
  cout << "done\n";

  // the neighbor search only finds pairs, add self-self correlation parts here
  _cor.Process(0.0f, (double)mapped.BeadCount());
  _count.Process(0.0f, (double)mapped.BeadCount());

  // search for all beads
  BeadList b;
  b.Generate(mapped, "*");

  // create/initialize neighborsearch
  std::unique_ptr<NBList> nb =
      std::unique_ptr<NBList>(OrientCorrApp::CreateNBSearch());
  nb->setCutoff(_cut_off);

  // set callback for each pair found
  nb->SetMatchFunction(this, &MyWorker::FoundPair);

  // execute the search
  nb->Generate(b);
}

// process a pair, since return value is falsed, pairs are not cached which
// saves a lot of memory for the big systems
bool MyWorker::FoundPair(Bead *b1, Bead *b2, const Eigen::Vector3d &,
                         const double dist) {
  double tmp = b1->getV().dot(b2->getV());
  double P2 = 3. / 2. * tmp * tmp - 0.5;

  // calculate average without exclusions
  _cor.Process(dist, P2);
  _count.Process(dist);

  if (b1->getMoleculeId() == b2->getMoleculeId()) {
    return false;
  }

  // calculate average with excluding intramolecular contributions
  _cor_excl.Process(dist, P2);
  _count_excl.Process(dist);

  return false;
}

// merge analysed data of a worker into main applications
void OrientCorrApp::MergeWorker(Worker *worker) {
  MyWorker *myWorker = dynamic_cast<MyWorker *>(worker);
  _cor.data().y() += myWorker->_cor.data().y();
  _count.data().y() += myWorker->_count.data().y();
  _cor_excl.data().y() += myWorker->_cor_excl.data().y();
  _count_excl.data().y() += myWorker->_count_excl.data().y();
}

// write out the data
void OrientCorrApp::EndEvaluate() {
  _cor.data().y() = _cor.data().y().cwiseQuotient(_count.data().y());
  _cor.data().Save("correlation.dat");

  _cor_excl.data().y() =
      _cor_excl.data().y().cwiseQuotient(_count_excl.data().y());
  _cor_excl.data().Save("correlation_excl.dat");
}
<|endoftext|>


<commit_before>
#include <nstd/Directory.h>

#include "Table.h"
#include "ServerHandler.h"
#include "WorkerHandler.h"

bool_t Table::open()
{
  if(!tableFile.open(name))
    return false;
  lastEntityId = tableFile.getLastId();
  minTimeOffset = tableFile.getTimeOffset();
  return true;
}

bool_t Table::create(const ClientProtocol::Entity* entity)
{
  String dir = File::dirname(name);
  if(dir != ".")
    Directory::create(dir);

  if(!tableFile.create(name))
    return false;
  if(entity && !tableFile.add(*(const TableFile::DataHeader*)entity, 0))
  {
    tableFile.close();
    return false;
  }
  return true;
}

uint32_t Table::getEntitySize() const
{
  return sizeof(ClientProtocol::Table) + name.length();
}

void_t Table::getEntity(ClientProtocol::Table& entity) const
{
  entity.entity.size = sizeof(ClientProtocol::Table) + name.length();
  entity.entity.id = id;
  entity.entity.time = time;
  entity.flags = 0;
  entity.name_size = name.length();
  Memory::copy(&entity + 1, (const char_t*)name, name.length());
}

timestamp_t Table::updateTimeOffset(timestamp_t timeOffset)
{
  if(timeOffset < minTimeOffset)
    minTimeOffset = timeOffset;
  timeOffsets.append(timeOffset);
  while(timeOffsets.size() > 100)
  {
    timestamp_t removedTimeOffset = timeOffsets.front();
    timeOffsets.removeFront();
    if(removedTimeOffset <= minTimeOffset && removedTimeOffset < timeOffset)
    {
      minTimeOffset = timeOffsets.front();
      List<timestamp_t>::Iterator i = timeOffsets.begin(), end = timeOffsets.end();
      for(++i; i != end; ++i)
        if(*i < minTimeOffset)
          minTimeOffset = *i;
    }
  }
  return minTimeOffset;
}
<commit_msg>Initialize table time offset<commit_after>
#include <nstd/Directory.h>

#include "Table.h"
#include "ServerHandler.h"
#include "WorkerHandler.h"

bool_t Table::open()
{
  if(!tableFile.open(name))
    return false;
  lastEntityId = tableFile.getLastId();
  if(lastEntityId != 0)
  {
    minTimeOffset = tableFile.getTimeOffset();
    timeOffsets.append(minTimeOffset);
  }
  return true;
}

bool_t Table::create(const ClientProtocol::Entity* entity)
{
  String dir = File::dirname(name);
  if(dir != ".")
    Directory::create(dir);

  if(!tableFile.create(name))
    return false;
  if(entity && !tableFile.add(*(const TableFile::DataHeader*)entity, 0))
  {
    tableFile.close();
    return false;
  }
  return true;
}

uint32_t Table::getEntitySize() const
{
  return sizeof(ClientProtocol::Table) + name.length();
}

void_t Table::getEntity(ClientProtocol::Table& entity) const
{
  entity.entity.size = sizeof(ClientProtocol::Table) + name.length();
  entity.entity.id = id;
  entity.entity.time = time;
  entity.flags = 0;
  entity.name_size = name.length();
  Memory::copy(&entity + 1, (const char_t*)name, name.length());
}

timestamp_t Table::updateTimeOffset(timestamp_t timeOffset)
{
  if(timeOffset < minTimeOffset)
    minTimeOffset = timeOffset;
  timeOffsets.append(timeOffset);
  while(timeOffsets.size() > 100)
  {
    timestamp_t removedTimeOffset = timeOffsets.front();
    timeOffsets.removeFront();
    if(removedTimeOffset <= minTimeOffset && removedTimeOffset < timeOffset)
    {
      minTimeOffset = timeOffsets.front();
      List<timestamp_t>::Iterator i = timeOffsets.begin(), end = timeOffsets.end();
      for(++i; i != end; ++i)
        if(*i < minTimeOffset)
          minTimeOffset = *i;
    }
  }
  return minTimeOffset;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDiscreteMarchingCubes.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

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

#include "vtkDiscreteMarchingCubes.h"

#include "vtkCellArray.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
#include "vtkLongArray.h"
#include "vtkMarchingCubesTriangleCases.h"
#include "vtkMath.h"
#include "vtkMergePoints.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkCellData.h"
#include "vtkShortArray.h"
#include "vtkStructuredPoints.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"
#include "vtkStreamingDemandDrivenPipeline.h"

#ifndef vtkFloatingPointType
#define vtkFloatingPointType float
#endif

vtkStandardNewMacro(vtkDiscreteMarchingCubes);

// Description:
// Construct object with initial range (0,1) and single contour value
// of 0.0. ComputeNormals is off, ComputeGradients is off and ComputeScalars is on.
vtkDiscreteMarchingCubes::vtkDiscreteMarchingCubes()
{
  this->ComputeNormals = 0;
  this->ComputeGradients = 0;
  this->ComputeScalars = 1;
}

vtkDiscreteMarchingCubes::~vtkDiscreteMarchingCubes()
{
}

//
// Contouring filter specialized for volumes and "short int" data values.
//
template <class T>
void vtkDiscreteMarchingCubesComputeGradient(
  vtkDiscreteMarchingCubes *self,T *scalars, int dims[3],
  vtkFloatingPointType origin[3], vtkFloatingPointType Spacing[3],
  vtkIncrementalPointLocator *locator,
  vtkDataArray *newCellScalars,
  vtkCellArray *newPolys, vtkFloatingPointType *values,
  int numValues)
{
  vtkFloatingPointType s[8], value;
  int i, j, k, sliceSize;
  static int CASE_MASK[8] = {1,2,4,8,16,32,64,128};
  vtkMarchingCubesTriangleCases *triCase, *triCases;
  EDGE_LIST  *edge;
  int contNum, jOffset, kOffset, idx, ii, index, *vert;
  vtkIdType ptIds[3];
  int extent[6];
  int ComputeScalars = newCellScalars != NULL;
  vtkFloatingPointType t, *x1, *x2, x[3], min, max;
  vtkFloatingPointType pts[8][3], xp, yp, zp;
  static int edges[12][2] = { {0,1}, {1,2}, {3,2}, {0,3},
                              {4,5}, {5,6}, {7,6}, {4,7},
                              {0,4}, {1,5}, {3,7}, {2,6}};

  vtkInformation *inInfo = self->GetExecutive()->GetInputInformation(0, 0);
  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);

  triCases =  vtkMarchingCubesTriangleCases::GetCases();

//
// Get min/max contour values
//
  if ( numValues < 1 )
    {
    return;
    }
  for ( min=max=values[0], i=1; i < numValues; i++)
    {
    if ( values[i] < min )
      {
      min = values[i];
      }
    if ( values[i] > max )
      {
      max = values[i];
      }
    }
//
// Traverse all voxel cells, generating triangles
// using marching cubes algorithm.
//
  sliceSize = dims[0] * dims[1];
  for ( k=0; k < (dims[2]-1); k++)
    {
    self->UpdateProgress (static_cast<vtkFloatingPointType>(k)/(dims[2] - 1));
    if (self->GetAbortExecute())
      {
      break;
      }
    kOffset = k*sliceSize;
    pts[0][2] = origin[2] + (k+extent[4])*Spacing[2];
    zp = pts[0][2] + Spacing[2];
    for ( j=0; j < (dims[1]-1); j++)
      {
      jOffset = j*dims[0];
      pts[0][1] = origin[1] + (j+extent[2])*Spacing[1];
      yp = pts[0][1] + Spacing[1];
      for ( i=0; i < (dims[0]-1); i++)
        {
        //get scalar values
        idx = i + jOffset + kOffset;
        s[0] = scalars[idx];
        s[1] = scalars[idx+1];
        s[2] = scalars[idx+1 + dims[0]];
        s[3] = scalars[idx + dims[0]];
        s[4] = scalars[idx + sliceSize];
        s[5] = scalars[idx+1 + sliceSize];
        s[6] = scalars[idx+1 + dims[0] + sliceSize];
        s[7] = scalars[idx + dims[0] + sliceSize];

        if ( (s[0] < min && s[1] < min && s[2] < min && s[3] < min &&
              s[4] < min && s[5] < min && s[6] < min && s[7] < min) ||
             (s[0] > max && s[1] > max && s[2] > max && s[3] > max &&
              s[4] > max && s[5] > max && s[6] > max && s[7] > max) )
          {
          continue; // no contours possible
          }

        //create voxel points
        pts[0][0] = origin[0] + (i+extent[0])*Spacing[0];
        xp = pts[0][0] + Spacing[0];

        pts[1][0] = xp;
        pts[1][1] = pts[0][1];
        pts[1][2] = pts[0][2];

        pts[2][0] = xp;
        pts[2][1] = yp;
        pts[2][2] = pts[0][2];

        pts[3][0] = pts[0][0];
        pts[3][1] = yp;
        pts[3][2] = pts[0][2];

        pts[4][0] = pts[0][0];
        pts[4][1] = pts[0][1];
        pts[4][2] = zp;

        pts[5][0] = xp;
        pts[5][1] = pts[0][1];
        pts[5][2] = zp;

        pts[6][0] = xp;
        pts[6][1] = yp;
        pts[6][2] = zp;

        pts[7][0] = pts[0][0];
        pts[7][1] = yp;
        pts[7][2] = zp;

        for (contNum=0; contNum < numValues; contNum++)
          {
          value = values[contNum];
          // Build the case table
          for ( ii=0, index = 0; ii < 8; ii++)
            {
            // for discrete marching cubes, we are looking for an
            // exact match of a scalar at a vertex to a value
            if ( s[ii] == value )
              {
              index |= CASE_MASK[ii];
              }
            }
          if ( index == 0 || index == 255 ) //no surface
            {
            continue;
            }

          triCase = triCases+ index;
          edge = triCase->edges;

          for ( ; edge[0] > -1; edge += 3 )
            {
            for (ii=0; ii<3; ii++) //insert triangle
              {
              vert = edges[edge[ii]];
              // for discrete marching cubes, the interpolation point
              // is always 0.5.
              t = 0.5;
              x1 = pts[vert[0]];
              x2 = pts[vert[1]];
              x[0] = x1[0] + t * (x2[0] - x1[0]);
              x[1] = x1[1] + t * (x2[1] - x1[1]);
              x[2] = x1[2] + t * (x2[2] - x1[2]);

              // add point
              locator->InsertUniquePoint(x, ptIds[ii]);
              }
            // check for degenerate triangle
            if ( ptIds[0] != ptIds[1] &&
                 ptIds[0] != ptIds[2] &&
                 ptIds[1] != ptIds[2] )
                {
                newPolys->InsertNextCell(3,ptIds);
                // Note that DiscreteMarchingCubes stores the scalar
                // data in the cells. It does not use the point data
                // since cells from different labeled segments may use
                // the same point.
                if (ComputeScalars)
                  {
                  newCellScalars->InsertNextTuple(&value);
                  }
                }
            }//for each triangle
          }//for all contours
        }//for i
      }//for j
    }//for k
}

//
// Contouring filter specialized for volumes and "short int" data values.
//
int vtkDiscreteMarchingCubes::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  vtkPoints *newPts;
  vtkCellArray *newPolys;
  vtkFloatArray *newCellScalars;
  vtkImageData *input = vtkImageData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPointData *pd;
  vtkDataArray *inScalars;
  int dims[3], extent[6];
  int estimatedSize;
  vtkFloatingPointType Spacing[3], origin[3];
  vtkFloatingPointType bounds[6];
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
  int numContours=this->ContourValues->GetNumberOfContours();
  vtkFloatingPointType *values=this->ContourValues->GetValues();

  vtkDebugMacro(<< "Executing marching cubes");

//
// Initialize and check input
//
  pd=input->GetPointData();
  if (pd ==NULL)
    {
    vtkErrorMacro(<<"PointData is NULL");
    return 1;
    }
  inScalars=pd->GetScalars();
  if ( inScalars == NULL )
    {
    vtkErrorMacro(<<"Scalars must be defined for contouring");
    return 1;
    }

  if ( input->GetDataDimension() != 3 )
    {
    vtkErrorMacro(<<"Cannot contour data of dimension != 3");
    return 1;
    }
  input->GetDimensions(dims);
  input->GetOrigin(origin);
  input->GetSpacing(Spacing);

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);

  // estimate the number of points from the volume dimensions
  estimatedSize = static_cast<int>(
    pow (static_cast<vtkFloatingPointType>(dims[0] * dims[1] * dims[2]), .75));
  estimatedSize = estimatedSize / 1024 * 1024; //multiple of 1024
  if (estimatedSize < 1024)
    {
    estimatedSize = 1024;
    }
  vtkDebugMacro(<< "Estimated allocation size is " << estimatedSize);
  newPts = vtkPoints::New(); newPts->Allocate(estimatedSize,estimatedSize/2);
  // compute bounds for merging points
  for ( int i=0; i<3; i++)
    {
    bounds[2*i] = origin[i] + extent[2*i] * Spacing[i];
    bounds[2*i+1] = origin[i] + extent[2*i+1] * Spacing[i];
    }
  if ( this->Locator == NULL )
    {
    this->CreateDefaultLocator();
    }
  this->Locator->InitPointInsertion (newPts, bounds, estimatedSize);

  newPolys = vtkCellArray::New();
  newPolys->Allocate(newPolys->EstimateSize(estimatedSize,3));

  if (this->ComputeScalars)
    {
    newCellScalars = vtkFloatArray::New();
    newCellScalars->Allocate(estimatedSize,3);
    }
  else
    {
    newCellScalars = NULL;
    }

  if (inScalars->GetNumberOfComponents() == 1 )
    {
    void* scalars = inScalars->GetVoidPointer(0);
    switch (inScalars->GetDataType())
      {
      vtkTemplateMacro(
        vtkDiscreteMarchingCubesComputeGradient(this,
                                                static_cast<VTK_TT*>(scalars),
                                                dims, origin, Spacing,
                                                this->Locator, newCellScalars,
                                                newPolys, values, numContours)
        );
      } //switch
    }

  else //multiple components - have to convert
    {
    int dataSize = dims[0] * dims[1] * dims[2];
    vtkDoubleArray *image=vtkDoubleArray::New();
    image->SetNumberOfComponents(inScalars->GetNumberOfComponents());
    image->SetNumberOfTuples(image->GetNumberOfComponents()*dataSize);
    inScalars->GetTuples(0,dataSize,image);

    double *scalars = image->GetPointer(0);
    vtkDiscreteMarchingCubesComputeGradient(this,
                                            scalars,
                                            dims,
                                            origin,
                                            Spacing,
                                            this->Locator,
                                            newCellScalars,
                                            newPolys,
                                            values,
                                            numContours);
    image->Delete();
    }

  vtkDebugMacro(<<"Created: "
                << newPts->GetNumberOfPoints() << " points, "
                << newPolys->GetNumberOfCells() << " triangles");
  //
  // Update ourselves.  Because we don't know up front how many triangles
  // we've created, take care to reclaim memory.
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->SetPolys(newPolys);
  newPolys->Delete();

  if (newCellScalars)
    {
    output->GetCellData()->SetScalars(newCellScalars);
    newCellScalars->Delete();
    }
  output->Squeeze();
  if (this->Locator)
    {
    this->Locator->Initialize(); //free storage
    }

  return 1;
}
<commit_msg>replaced all uses of vtkFloatingPointType with double<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDiscreteMarchingCubes.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

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

#include "vtkDiscreteMarchingCubes.h"

#include "vtkCellArray.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
#include "vtkLongArray.h"
#include "vtkMarchingCubesTriangleCases.h"
#include "vtkMath.h"
#include "vtkMergePoints.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkCellData.h"
#include "vtkShortArray.h"
#include "vtkStructuredPoints.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkStandardNewMacro(vtkDiscreteMarchingCubes);

// Description:
// Construct object with initial range (0,1) and single contour value
// of 0.0. ComputeNormals is off, ComputeGradients is off and ComputeScalars is on.
vtkDiscreteMarchingCubes::vtkDiscreteMarchingCubes()
{
  this->ComputeNormals = 0;
  this->ComputeGradients = 0;
  this->ComputeScalars = 1;
}

vtkDiscreteMarchingCubes::~vtkDiscreteMarchingCubes()
{
}

//
// Contouring filter specialized for volumes and "short int" data values.
//
template <class T>
void vtkDiscreteMarchingCubesComputeGradient(
  vtkDiscreteMarchingCubes *self,T *scalars, int dims[3],
  double origin[3], double Spacing[3],
  vtkIncrementalPointLocator *locator,
  vtkDataArray *newCellScalars,
  vtkCellArray *newPolys, double *values,
  int numValues)
{
  double s[8], value;
  int i, j, k, sliceSize;
  static int CASE_MASK[8] = {1,2,4,8,16,32,64,128};
  vtkMarchingCubesTriangleCases *triCase, *triCases;
  EDGE_LIST  *edge;
  int contNum, jOffset, kOffset, idx, ii, index, *vert;
  vtkIdType ptIds[3];
  int extent[6];
  int ComputeScalars = newCellScalars != NULL;
  double t, *x1, *x2, x[3], min, max;
  double pts[8][3], xp, yp, zp;
  static int edges[12][2] = { {0,1}, {1,2}, {3,2}, {0,3},
                              {4,5}, {5,6}, {7,6}, {4,7},
                              {0,4}, {1,5}, {3,7}, {2,6}};

  vtkInformation *inInfo = self->GetExecutive()->GetInputInformation(0, 0);
  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);

  triCases =  vtkMarchingCubesTriangleCases::GetCases();

//
// Get min/max contour values
//
  if ( numValues < 1 )
    {
    return;
    }
  for ( min=max=values[0], i=1; i < numValues; i++)
    {
    if ( values[i] < min )
      {
      min = values[i];
      }
    if ( values[i] > max )
      {
      max = values[i];
      }
    }
//
// Traverse all voxel cells, generating triangles
// using marching cubes algorithm.
//
  sliceSize = dims[0] * dims[1];
  for ( k=0; k < (dims[2]-1); k++)
    {
    self->UpdateProgress (static_cast<double>(k)/(dims[2] - 1));
    if (self->GetAbortExecute())
      {
      break;
      }
    kOffset = k*sliceSize;
    pts[0][2] = origin[2] + (k+extent[4])*Spacing[2];
    zp = pts[0][2] + Spacing[2];
    for ( j=0; j < (dims[1]-1); j++)
      {
      jOffset = j*dims[0];
      pts[0][1] = origin[1] + (j+extent[2])*Spacing[1];
      yp = pts[0][1] + Spacing[1];
      for ( i=0; i < (dims[0]-1); i++)
        {
        //get scalar values
        idx = i + jOffset + kOffset;
        s[0] = scalars[idx];
        s[1] = scalars[idx+1];
        s[2] = scalars[idx+1 + dims[0]];
        s[3] = scalars[idx + dims[0]];
        s[4] = scalars[idx + sliceSize];
        s[5] = scalars[idx+1 + sliceSize];
        s[6] = scalars[idx+1 + dims[0] + sliceSize];
        s[7] = scalars[idx + dims[0] + sliceSize];

        if ( (s[0] < min && s[1] < min && s[2] < min && s[3] < min &&
              s[4] < min && s[5] < min && s[6] < min && s[7] < min) ||
             (s[0] > max && s[1] > max && s[2] > max && s[3] > max &&
              s[4] > max && s[5] > max && s[6] > max && s[7] > max) )
          {
          continue; // no contours possible
          }

        //create voxel points
        pts[0][0] = origin[0] + (i+extent[0])*Spacing[0];
        xp = pts[0][0] + Spacing[0];

        pts[1][0] = xp;
        pts[1][1] = pts[0][1];
        pts[1][2] = pts[0][2];

        pts[2][0] = xp;
        pts[2][1] = yp;
        pts[2][2] = pts[0][2];

        pts[3][0] = pts[0][0];
        pts[3][1] = yp;
        pts[3][2] = pts[0][2];

        pts[4][0] = pts[0][0];
        pts[4][1] = pts[0][1];
        pts[4][2] = zp;

        pts[5][0] = xp;
        pts[5][1] = pts[0][1];
        pts[5][2] = zp;

        pts[6][0] = xp;
        pts[6][1] = yp;
        pts[6][2] = zp;

        pts[7][0] = pts[0][0];
        pts[7][1] = yp;
        pts[7][2] = zp;

        for (contNum=0; contNum < numValues; contNum++)
          {
          value = values[contNum];
          // Build the case table
          for ( ii=0, index = 0; ii < 8; ii++)
            {
            // for discrete marching cubes, we are looking for an
            // exact match of a scalar at a vertex to a value
            if ( s[ii] == value )
              {
              index |= CASE_MASK[ii];
              }
            }
          if ( index == 0 || index == 255 ) //no surface
            {
            continue;
            }

          triCase = triCases+ index;
          edge = triCase->edges;

          for ( ; edge[0] > -1; edge += 3 )
            {
            for (ii=0; ii<3; ii++) //insert triangle
              {
              vert = edges[edge[ii]];
              // for discrete marching cubes, the interpolation point
              // is always 0.5.
              t = 0.5;
              x1 = pts[vert[0]];
              x2 = pts[vert[1]];
              x[0] = x1[0] + t * (x2[0] - x1[0]);
              x[1] = x1[1] + t * (x2[1] - x1[1]);
              x[2] = x1[2] + t * (x2[2] - x1[2]);

              // add point
              locator->InsertUniquePoint(x, ptIds[ii]);
              }
            // check for degenerate triangle
            if ( ptIds[0] != ptIds[1] &&
                 ptIds[0] != ptIds[2] &&
                 ptIds[1] != ptIds[2] )
                {
                newPolys->InsertNextCell(3,ptIds);
                // Note that DiscreteMarchingCubes stores the scalar
                // data in the cells. It does not use the point data
                // since cells from different labeled segments may use
                // the same point.
                if (ComputeScalars)
                  {
                  newCellScalars->InsertNextTuple(&value);
                  }
                }
            }//for each triangle
          }//for all contours
        }//for i
      }//for j
    }//for k
}

//
// Contouring filter specialized for volumes and "short int" data values.
//
int vtkDiscreteMarchingCubes::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  vtkPoints *newPts;
  vtkCellArray *newPolys;
  vtkFloatArray *newCellScalars;
  vtkImageData *input = vtkImageData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPointData *pd;
  vtkDataArray *inScalars;
  int dims[3], extent[6];
  int estimatedSize;
  double Spacing[3], origin[3];
  double bounds[6];
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
  int numContours=this->ContourValues->GetNumberOfContours();
  double *values=this->ContourValues->GetValues();

  vtkDebugMacro(<< "Executing marching cubes");

//
// Initialize and check input
//
  pd=input->GetPointData();
  if (pd ==NULL)
    {
    vtkErrorMacro(<<"PointData is NULL");
    return 1;
    }
  inScalars=pd->GetScalars();
  if ( inScalars == NULL )
    {
    vtkErrorMacro(<<"Scalars must be defined for contouring");
    return 1;
    }

  if ( input->GetDataDimension() != 3 )
    {
    vtkErrorMacro(<<"Cannot contour data of dimension != 3");
    return 1;
    }
  input->GetDimensions(dims);
  input->GetOrigin(origin);
  input->GetSpacing(Spacing);

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);

  // estimate the number of points from the volume dimensions
  estimatedSize = static_cast<int>(
    pow (static_cast<double>(dims[0] * dims[1] * dims[2]), .75));
  estimatedSize = estimatedSize / 1024 * 1024; //multiple of 1024
  if (estimatedSize < 1024)
    {
    estimatedSize = 1024;
    }
  vtkDebugMacro(<< "Estimated allocation size is " << estimatedSize);
  newPts = vtkPoints::New(); newPts->Allocate(estimatedSize,estimatedSize/2);
  // compute bounds for merging points
  for ( int i=0; i<3; i++)
    {
    bounds[2*i] = origin[i] + extent[2*i] * Spacing[i];
    bounds[2*i+1] = origin[i] + extent[2*i+1] * Spacing[i];
    }
  if ( this->Locator == NULL )
    {
    this->CreateDefaultLocator();
    }
  this->Locator->InitPointInsertion (newPts, bounds, estimatedSize);

  newPolys = vtkCellArray::New();
  newPolys->Allocate(newPolys->EstimateSize(estimatedSize,3));

  if (this->ComputeScalars)
    {
    newCellScalars = vtkFloatArray::New();
    newCellScalars->Allocate(estimatedSize,3);
    }
  else
    {
    newCellScalars = NULL;
    }

  if (inScalars->GetNumberOfComponents() == 1 )
    {
    void* scalars = inScalars->GetVoidPointer(0);
    switch (inScalars->GetDataType())
      {
      vtkTemplateMacro(
        vtkDiscreteMarchingCubesComputeGradient(this,
                                                static_cast<VTK_TT*>(scalars),
                                                dims, origin, Spacing,
                                                this->Locator, newCellScalars,
                                                newPolys, values, numContours)
        );
      } //switch
    }

  else //multiple components - have to convert
    {
    int dataSize = dims[0] * dims[1] * dims[2];
    vtkDoubleArray *image=vtkDoubleArray::New();
    image->SetNumberOfComponents(inScalars->GetNumberOfComponents());
    image->SetNumberOfTuples(image->GetNumberOfComponents()*dataSize);
    inScalars->GetTuples(0,dataSize,image);

    double *scalars = image->GetPointer(0);
    vtkDiscreteMarchingCubesComputeGradient(this,
                                            scalars,
                                            dims,
                                            origin,
                                            Spacing,
                                            this->Locator,
                                            newCellScalars,
                                            newPolys,
                                            values,
                                            numContours);
    image->Delete();
    }

  vtkDebugMacro(<<"Created: "
                << newPts->GetNumberOfPoints() << " points, "
                << newPolys->GetNumberOfCells() << " triangles");
  //
  // Update ourselves.  Because we don't know up front how many triangles
  // we've created, take care to reclaim memory.
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->SetPolys(newPolys);
  newPolys->Delete();

  if (newCellScalars)
    {
    output->GetCellData()->SetScalars(newCellScalars);
    newCellScalars->Delete();
    }
  output->Squeeze();
  if (this->Locator)
    {
    this->Locator->Initialize(); //free storage
    }

  return 1;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *                                                                         *
 *   Copyright: https://code.google.com/p/qsint/                           *
 *   License:   LGPL                                                       *
 *                                                                         *
 ***************************************************************************/

#include "taskheader_p.h"
#include "actionpanelscheme.h"
#include "actionlabel.h"

#include <QtCore/QVariant>
#include <QtCore/QEvent>
#include <QtCore/QTimer>

#include <QHBoxLayout>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>

namespace QSint
{

TaskHeader::TaskHeader(const QIcon &icon, const QString &title, bool expandable, QWidget *parent)
  : BaseClass(parent),
  myExpandable(expandable),
  m_over(false),
  m_buttonOver(false),
  m_fold(true),
  m_opacity(0.1),
  myButton(0)
{
    setProperty("class", "header");

    myTitle = new ActionLabel(this);
    myTitle->setProperty("class", "header");
    myTitle->setText(title);
    myTitle->setIcon(icon);
    myTitle->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);

    connect(myTitle, SIGNAL(clicked()), this, SLOT(fold()));

    QHBoxLayout *hbl = new QHBoxLayout();
    hbl->setMargin(2);
    setLayout(hbl);

    hbl->addWidget(myTitle);

    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

    setScheme(ActionPanelScheme::defaultScheme());
    //myTitle->setSchemePointer(&myLabelScheme);

    setExpandable(myExpandable);
}

void TaskHeader::setExpandable(bool expandable)
{
    if (expandable) {
        myExpandable = true;

        if (myButton)
            return;

        myButton = new QLabel(this);
        myButton->installEventFilter(this);
        myButton->setFixedSize(myScheme->headerButtonSize);
        layout()->addWidget(myButton);
        changeIcons();

    } else {
        myExpandable = false;

        if (!myButton)
            return;

        myButton->removeEventFilter(this);
        myButton->setParent(0);
        delete myButton;
        myButton = 0;
        changeIcons();
    }
}

bool TaskHeader::eventFilter(QObject *obj, QEvent *event)
{
  switch (event->type()) {
    case QEvent::MouseButtonPress:
      if (myExpandable)
        fold();
      return true;

    case QEvent::Enter:
      m_buttonOver = true;
      changeIcons();
      return true;

    case QEvent::Leave:
      m_buttonOver = false;
      changeIcons();
      return true;

    default:;
  }

  return BaseClass::eventFilter(obj, event);
}

void TaskHeader::setScheme(ActionPanelScheme *scheme)
{
  if (scheme) {
    myScheme = scheme;
    //myLabelScheme = &(scheme->headerLabelScheme);
    setStyleSheet(myScheme->actionStyle);

    if (myExpandable) {
      //setCursor(myLabelScheme->cursorOver ? Qt::PointingHandCursor : cursor());
      changeIcons();
    }

    setFixedHeight(scheme->headerSize);

    update();
  }
}

void TaskHeader::paintEvent ( QPaintEvent * event )
{
  QPainter p(this);

  if (myScheme->headerAnimation)
    p.setOpacity(m_opacity+0.7);

//  p.setPen(m_over ? myScheme->headerBorderOver : myScheme->headerBorder);
//  p.setBrush(m_over ? myScheme->headerBackgroundOver : myScheme->headerBackground);

//  myScheme->headerCorners.draw(&p, rect());

  BaseClass::paintEvent(event);
}

void TaskHeader::animate()
{
  if (!myScheme->headerAnimation)
    return;

  if (!isEnabled()) {
    m_opacity = 0.1;
    update();
    return;
  }

  if (m_over) {
    if (m_opacity >= 0.3) {
      m_opacity = 0.3;
      return;
    }
    m_opacity += 0.05;
  } else {
    if (m_opacity <= 0.1) {
      m_opacity = 0.1;
      return;
    }
    m_opacity = qMax(0.1, m_opacity-0.05);
  }

  QTimer::singleShot(100, this, SLOT(animate()));
  update();
}

void TaskHeader::enterEvent ( QEvent * /*event*/ )
{
  m_over = true;

  if (isEnabled())
    QTimer::singleShot(100, this, SLOT(animate()));

  update();
}

void TaskHeader::leaveEvent ( QEvent * /*event*/ )
{
  m_over = false;

  if (isEnabled())
    QTimer::singleShot(100, this, SLOT(animate()));

  update();
}

void TaskHeader::fold()
{
  if (myExpandable) {
    emit activated();

    m_fold = !m_fold;
    changeIcons();
  }
}

void TaskHeader::changeIcons()
{
  if (!myButton)
    return;

  if (m_buttonOver)
  {
    if (m_fold)
      myButton->setPixmap(myScheme->headerButtonFoldOver);
    else
      myButton->setPixmap(myScheme->headerButtonUnfoldOver);
  } else
  {
    if (m_fold)
      myButton->setPixmap(myScheme->headerButtonFold);
    else
      myButton->setPixmap(myScheme->headerButtonUnfold);
  }

  myButton->setFixedSize(myScheme->headerButtonSize);
}

void TaskHeader::mouseReleaseEvent ( QMouseEvent * event )
{
  if (event->button() == Qt::LeftButton) {
    emit activated();
  }
}

void TaskHeader::keyPressEvent ( QKeyEvent * event )
{
  switch (event->key())
  {
    case Qt::Key_Down:
    {
      QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, 0);
      QApplication::sendEvent(this, &ke);
      return;
    }

    case Qt::Key_Up:
    {
      QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier);
      QApplication::sendEvent(this, &ke);
      return;
    }

    default:;
  }

  BaseClass::keyPressEvent(event);
}

void TaskHeader::keyReleaseEvent ( QKeyEvent * event )
{
  switch (event->key())
  {
    case Qt::Key_Down:
    {
      QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, 0);
      QApplication::sendEvent(this, &ke);
      return;
    }

    case Qt::Key_Up:
    {
      QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, Qt::ShiftModifier);
      QApplication::sendEvent(this, &ke);
      return;
    }

    default:;
  }

  BaseClass::keyReleaseEvent(event);
}

}
<commit_msg>+ support dynamic property 'fold' in TaskHeader<commit_after>/***************************************************************************
 *                                                                         *
 *   Copyright: https://code.google.com/p/qsint/                           *
 *   License:   LGPL                                                       *
 *                                                                         *
 ***************************************************************************/

#include "taskheader_p.h"
#include "actionpanelscheme.h"
#include "actionlabel.h"

#include <QtCore/QVariant>
#include <QtCore/QEvent>
#include <QtCore/QTimer>

#include <QHBoxLayout>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QStyle>

namespace QSint
{

TaskHeader::TaskHeader(const QIcon &icon, const QString &title, bool expandable, QWidget *parent)
  : BaseClass(parent),
  myExpandable(expandable),
  m_over(false),
  m_buttonOver(false),
  m_fold(true),
  m_opacity(0.1),
  myButton(0)
{
    setProperty("class", "header");

    myTitle = new ActionLabel(this);
    myTitle->setProperty("class", "header");
    myTitle->setText(title);
    myTitle->setIcon(icon);
    myTitle->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);

    connect(myTitle, SIGNAL(clicked()), this, SLOT(fold()));

    QHBoxLayout *hbl = new QHBoxLayout();
    hbl->setMargin(2);
    setLayout(hbl);

    hbl->addWidget(myTitle);

    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

    setScheme(ActionPanelScheme::defaultScheme());
    //myTitle->setSchemePointer(&myLabelScheme);

    setExpandable(myExpandable);
}

void TaskHeader::setExpandable(bool expandable)
{
    if (expandable) {
        myExpandable = true;

        if (myButton)
            return;

        myButton = new QLabel(this);
        myButton->installEventFilter(this);
        myButton->setFixedSize(myScheme->headerButtonSize);
        layout()->addWidget(myButton);
        changeIcons();
        myButton->setProperty("fold", m_fold);

    } else {
        myExpandable = false;

        if (!myButton)
            return;

        myButton->removeEventFilter(this);
        myButton->setParent(0);
        delete myButton;
        myButton = 0;
        changeIcons();
    }
}

bool TaskHeader::eventFilter(QObject *obj, QEvent *event)
{
  switch (event->type()) {
    case QEvent::MouseButtonPress:
      if (myExpandable)
        fold();
      return true;

    case QEvent::Enter:
      m_buttonOver = true;
      changeIcons();
      return true;

    case QEvent::Leave:
      m_buttonOver = false;
      changeIcons();
      return true;

    default:;
  }

  return BaseClass::eventFilter(obj, event);
}

void TaskHeader::setScheme(ActionPanelScheme *scheme)
{
  if (scheme) {
    myScheme = scheme;
    //myLabelScheme = &(scheme->headerLabelScheme);
    setStyleSheet(myScheme->actionStyle);

    if (myExpandable) {
      //setCursor(myLabelScheme->cursorOver ? Qt::PointingHandCursor : cursor());
      changeIcons();
    }

    setFixedHeight(scheme->headerSize);

    update();
  }
}

void TaskHeader::paintEvent ( QPaintEvent * event )
{
  QPainter p(this);

  if (myScheme->headerAnimation)
    p.setOpacity(m_opacity+0.7);

//  p.setPen(m_over ? myScheme->headerBorderOver : myScheme->headerBorder);
//  p.setBrush(m_over ? myScheme->headerBackgroundOver : myScheme->headerBackground);

//  myScheme->headerCorners.draw(&p, rect());

  BaseClass::paintEvent(event);
}

void TaskHeader::animate()
{
  if (!myScheme->headerAnimation)
    return;

  if (!isEnabled()) {
    m_opacity = 0.1;
    update();
    return;
  }

  if (m_over) {
    if (m_opacity >= 0.3) {
      m_opacity = 0.3;
      return;
    }
    m_opacity += 0.05;
  } else {
    if (m_opacity <= 0.1) {
      m_opacity = 0.1;
      return;
    }
    m_opacity = qMax(0.1, m_opacity-0.05);
  }

  QTimer::singleShot(100, this, SLOT(animate()));
  update();
}

void TaskHeader::enterEvent ( QEvent * /*event*/ )
{
  m_over = true;

  if (isEnabled())
    QTimer::singleShot(100, this, SLOT(animate()));

  update();
}

void TaskHeader::leaveEvent ( QEvent * /*event*/ )
{
  m_over = false;

  if (isEnabled())
    QTimer::singleShot(100, this, SLOT(animate()));

  update();
}

void TaskHeader::fold()
{
  if (myExpandable) {
    emit activated();

    m_fold = !m_fold;
    changeIcons();
    if (myButton) {
      myButton->setProperty("fold", m_fold);
      if (myButton->style()) {
        myButton->style()->unpolish(myButton);
        myButton->style()->polish(myButton);
        myButton->update();
      }
    }
  }
}

void TaskHeader::changeIcons()
{
  if (!myButton)
    return;

  if (m_buttonOver)
  {
    if (m_fold)
      myButton->setPixmap(myScheme->headerButtonFoldOver);
    else
      myButton->setPixmap(myScheme->headerButtonUnfoldOver);
  } else
  {
    if (m_fold)
      myButton->setPixmap(myScheme->headerButtonFold);
    else
      myButton->setPixmap(myScheme->headerButtonUnfold);
  }

  myButton->setFixedSize(myScheme->headerButtonSize);
}

void TaskHeader::mouseReleaseEvent ( QMouseEvent * event )
{
  if (event->button() == Qt::LeftButton) {
    emit activated();
  }
}

void TaskHeader::keyPressEvent ( QKeyEvent * event )
{
  switch (event->key())
  {
    case Qt::Key_Down:
    {
      QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, 0);
      QApplication::sendEvent(this, &ke);
      return;
    }

    case Qt::Key_Up:
    {
      QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier);
      QApplication::sendEvent(this, &ke);
      return;
    }

    default:;
  }

  BaseClass::keyPressEvent(event);
}

void TaskHeader::keyReleaseEvent ( QKeyEvent * event )
{
  switch (event->key())
  {
    case Qt::Key_Down:
    {
      QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, 0);
      QApplication::sendEvent(this, &ke);
      return;
    }

    case Qt::Key_Up:
    {
      QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, Qt::ShiftModifier);
      QApplication::sendEvent(this, &ke);
      return;
    }

    default:;
  }

  BaseClass::keyReleaseEvent(event);
}

}
<|endoftext|>