<commit_before>//===--- Tooling.cpp - Running clang standalone tools ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements functions to run clang tools standalone instead
//  of running them as a plugin.
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

namespace clang {
namespace tooling {

FrontendActionFactory::~FrontendActionFactory() {}

// FIXME: This file contains structural duplication with other parts of the
// code that sets up a compiler to run tools on it, and we should refactor
// it to be based on the same framework.

/// \brief Builds a clang driver initialized for running clang tools.
static clang::driver::Driver *newDriver(clang::DiagnosticsEngine *Diagnostics,
                                        const char *BinaryName) {
  const std::string DefaultOutputName = "a.out";
  clang::driver::Driver *CompilerDriver = new clang::driver::Driver(
      BinaryName, llvm::sys::getDefaultTargetTriple(),
      DefaultOutputName, false, *Diagnostics);
  CompilerDriver->setTitle("clang_based_tool");
  return CompilerDriver;
}

/// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.
///
/// Returns NULL on error.
static const clang::driver::ArgStringList *getCC1Arguments(
    clang::DiagnosticsEngine *Diagnostics,
    clang::driver::Compilation *Compilation) {
  // We expect to get back exactly one Command job, if we didn't something
  // failed. Extract that job from the Compilation.
  const clang::driver::JobList &Jobs = Compilation->getJobs();
  if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
    llvm::SmallString<256> error_msg;
    llvm::raw_svector_ostream error_stream(error_msg);
    Compilation->PrintJob(error_stream, Compilation->getJobs(), "; ", true);
    Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
        << error_stream.str();
    return NULL;
  }

  // The one job we find should be to invoke clang again.
  const clang::driver::Command *Cmd =
      cast<clang::driver::Command>(*Jobs.begin());
  if (StringRef(Cmd->getCreator().getName()) != "clang") {
    Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
    return NULL;
  }

  return &Cmd->getArguments();
}

/// \brief Returns a clang build invocation initialized from the CC1 flags.
static clang::CompilerInvocation *newInvocation(
    clang::DiagnosticsEngine *Diagnostics,
    const clang::driver::ArgStringList &CC1Args) {
  assert(!CC1Args.empty() && "Must at least contain the program name!");
  clang::CompilerInvocation *Invocation = new clang::CompilerInvocation;
  clang::CompilerInvocation::CreateFromArgs(
      *Invocation, CC1Args.data() + 1, CC1Args.data() + CC1Args.size(),
      *Diagnostics);
  Invocation->getFrontendOpts().DisableFree = false;
  return Invocation;
}

bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
                   const Twine &FileName) {
  SmallString<16> FileNameStorage;
  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
  const char *const CommandLine[] = {
      "clang-tool", "-fsyntax-only", FileNameRef.data()
  };
  FileManager Files((FileSystemOptions()));
  ToolInvocation Invocation(
      std::vector<std::string>(
          CommandLine,
          CommandLine + llvm::array_lengthof(CommandLine)),
      ToolAction, &Files);

  SmallString<1024> CodeStorage;
  Invocation.mapVirtualFile(FileNameRef,
                            Code.toNullTerminatedStringRef(CodeStorage));
  return Invocation.run();
}

/// \brief Returns the absolute path of 'File', by prepending it with
/// 'BaseDirectory' if 'File' is not absolute.
///
/// Otherwise returns 'File'.
/// If 'File' starts with "./", the returned path will not contain the "./".
/// Otherwise, the returned path will contain the literal path-concatenation of
/// 'BaseDirectory' and 'File'.
///
/// \param File Either an absolute or relative path.
/// \param BaseDirectory An absolute path.
static std::string getAbsolutePath(
    StringRef File, StringRef BaseDirectory) {
  assert(llvm::sys::path::is_absolute(BaseDirectory));
  if (llvm::sys::path::is_absolute(File)) {
    return File;
  }
  StringRef RelativePath(File);
  if (RelativePath.startswith("./")) {
    RelativePath = RelativePath.substr(strlen("./"));
  }
  llvm::SmallString<1024> AbsolutePath(BaseDirectory);
  llvm::sys::path::append(AbsolutePath, RelativePath);
  return AbsolutePath.str();
}

ToolInvocation::ToolInvocation(
    ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
    FileManager *Files)
    : CommandLine(CommandLine.vec()), ToolAction(ToolAction), Files(Files) {
}

void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {
  MappedFileContents[FilePath] = Content;
}

bool ToolInvocation::run() {
  std::vector<const char*> Argv;
  for (int I = 0, E = CommandLine.size(); I != E; ++I)
    Argv.push_back(CommandLine[I].c_str());
  const char *const BinaryName = Argv[0];
  DiagnosticOptions DefaultDiagnosticOptions;
  TextDiagnosticPrinter DiagnosticPrinter(
      llvm::errs(), DefaultDiagnosticOptions);
  DiagnosticsEngine Diagnostics(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>(
      new DiagnosticIDs()), &DiagnosticPrinter, false);

  const llvm::OwningPtr<clang::driver::Driver> Driver(
      newDriver(&Diagnostics, BinaryName));
  // Since the input might only be virtual, don't check whether it exists.
  Driver->setCheckInputsExist(false);
  const llvm::OwningPtr<clang::driver::Compilation> Compilation(
      Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
  const clang::driver::ArgStringList *const CC1Args = getCC1Arguments(
      &Diagnostics, Compilation.get());
  if (CC1Args == NULL) {
    return false;
  }
  llvm::OwningPtr<clang::CompilerInvocation> Invocation(
      newInvocation(&Diagnostics, *CC1Args));
  return runInvocation(BinaryName, Compilation.get(),
                       Invocation.take(), *CC1Args, ToolAction.take());
}

// Exists solely for the purpose of lookup of the resource path.
static int StaticSymbol;

bool ToolInvocation::runInvocation(
    const char *BinaryName,
    clang::driver::Compilation *Compilation,
    clang::CompilerInvocation *Invocation,
    const clang::driver::ArgStringList &CC1Args,
    clang::FrontendAction *ToolAction) {
  llvm::OwningPtr<clang::FrontendAction> ScopedToolAction(ToolAction);
  // Show the invocation, with -v.
  if (Invocation->getHeaderSearchOpts().Verbose) {
    llvm::errs() << "clang Invocation:\n";
    Compilation->PrintJob(llvm::errs(), Compilation->getJobs(), "\n", true);
    llvm::errs() << "\n";
  }

  // Create a compiler instance to handle the actual work.
  clang::CompilerInstance Compiler;
  Compiler.setInvocation(Invocation);
  Compiler.setFileManager(Files);
  // FIXME: What about LangOpts?

  // Create the compilers actual diagnostics engine.
  Compiler.createDiagnostics(CC1Args.size(),
                             const_cast<char**>(CC1Args.data()));
  if (!Compiler.hasDiagnostics())
    return false;

  Compiler.createSourceManager(*Files);
  addFileMappingsTo(Compiler.getSourceManager());

  // Infer the builtin include path if unspecified.
  if (Compiler.getHeaderSearchOpts().UseBuiltinIncludes &&
      Compiler.getHeaderSearchOpts().ResourceDir.empty()) {
    // This just needs to be some symbol in the binary.
    void *const SymbolAddr = &StaticSymbol;
    Compiler.getHeaderSearchOpts().ResourceDir =
        clang::CompilerInvocation::GetResourcesPath(BinaryName, SymbolAddr);
  }

  const bool Success = Compiler.ExecuteAction(*ToolAction);

  Compiler.resetAndLeakFileManager();
  return Success;
}

void ToolInvocation::addFileMappingsTo(SourceManager &Sources) {
  for (llvm::StringMap<StringRef>::const_iterator
           It = MappedFileContents.begin(), End = MappedFileContents.end();
       It != End; ++It) {
    // Inject the code as the given file name into the preprocessor options.
    const llvm::MemoryBuffer *Input =
        llvm::MemoryBuffer::getMemBuffer(It->getValue());
    // FIXME: figure out what '0' stands for.
    const FileEntry *FromFile = Files->getVirtualFile(
        It->getKey(), Input->getBufferSize(), 0);
    // FIXME: figure out memory management ('true').
    Sources.overrideFileContents(FromFile, Input, true);
  }
}

ClangTool::ClangTool(const CompilationDatabase &Compilations,
                     ArrayRef<std::string> SourcePaths)
    : Files((FileSystemOptions())) {
  StringRef BaseDirectory(::getenv("PWD"));
  for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
    llvm::SmallString<1024> File(getAbsolutePath(
        SourcePaths[I], BaseDirectory));

    std::vector<CompileCommand> CompileCommands =
      Compilations.getCompileCommands(File.str());
    if (!CompileCommands.empty()) {
      for (int I = 0, E = CompileCommands.size(); I != E; ++I) {
        CompileCommand &Command = CompileCommands[I];
        if (!Command.Directory.empty()) {
          // FIXME: What should happen if CommandLine includes -working-directory
          // as well?
          Command.CommandLine.push_back(
            "-working-directory=" + Command.Directory);
        }
        CommandLines.push_back(std::make_pair(File.str(), Command.CommandLine));
      }
    } else {
      // FIXME: There are two use cases here: doing a fuzzy
      // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
      // about the .cc files that were not found, and the use case where I
      // specify all files I want to run over explicitly, where this should
      // be an error. We'll want to add an option for this.
      llvm::outs() << "Skipping " << File << ". Command line not found.\n";
    }
  }
}

void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
  MappedFileContents.push_back(std::make_pair(FilePath, Content));
}

int ClangTool::run(FrontendActionFactory *ActionFactory) {
  bool ProcessingFailed = false;
  for (unsigned I = 0; I < CommandLines.size(); ++I) {
    std::string File = CommandLines[I].first;
    std::vector<std::string> &CommandLine = CommandLines[I].second;
    llvm::outs() << "Processing: " << File << ".\n";
    ToolInvocation Invocation(CommandLine, ActionFactory->create(), &Files);
    for (int I = 0, E = MappedFileContents.size(); I != E; ++I) {
      Invocation.mapVirtualFile(MappedFileContents[I].first,
                                MappedFileContents[I].second);
    }
    if (!Invocation.run()) {
      llvm::outs() << "Error while processing " << File << ".\n";
      ProcessingFailed = true;
    }
  }
  return ProcessingFailed ? 1 : 0;
}

} // end namespace tooling
} // end namespace clang
<commit_msg>Tooling.cpp: Don't refer to $ENV{PWD}. Use llvm::sys::fs instead.<commit_after>//===--- Tooling.cpp - Running clang standalone tools ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements functions to run clang tools standalone instead
//  of running them as a plugin.
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/Support/FileSystem.h"

namespace clang {
namespace tooling {

FrontendActionFactory::~FrontendActionFactory() {}

// FIXME: This file contains structural duplication with other parts of the
// code that sets up a compiler to run tools on it, and we should refactor
// it to be based on the same framework.

/// \brief Builds a clang driver initialized for running clang tools.
static clang::driver::Driver *newDriver(clang::DiagnosticsEngine *Diagnostics,
                                        const char *BinaryName) {
  const std::string DefaultOutputName = "a.out";
  clang::driver::Driver *CompilerDriver = new clang::driver::Driver(
      BinaryName, llvm::sys::getDefaultTargetTriple(),
      DefaultOutputName, false, *Diagnostics);
  CompilerDriver->setTitle("clang_based_tool");
  return CompilerDriver;
}

/// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.
///
/// Returns NULL on error.
static const clang::driver::ArgStringList *getCC1Arguments(
    clang::DiagnosticsEngine *Diagnostics,
    clang::driver::Compilation *Compilation) {
  // We expect to get back exactly one Command job, if we didn't something
  // failed. Extract that job from the Compilation.
  const clang::driver::JobList &Jobs = Compilation->getJobs();
  if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
    llvm::SmallString<256> error_msg;
    llvm::raw_svector_ostream error_stream(error_msg);
    Compilation->PrintJob(error_stream, Compilation->getJobs(), "; ", true);
    Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
        << error_stream.str();
    return NULL;
  }

  // The one job we find should be to invoke clang again.
  const clang::driver::Command *Cmd =
      cast<clang::driver::Command>(*Jobs.begin());
  if (StringRef(Cmd->getCreator().getName()) != "clang") {
    Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
    return NULL;
  }

  return &Cmd->getArguments();
}

/// \brief Returns a clang build invocation initialized from the CC1 flags.
static clang::CompilerInvocation *newInvocation(
    clang::DiagnosticsEngine *Diagnostics,
    const clang::driver::ArgStringList &CC1Args) {
  assert(!CC1Args.empty() && "Must at least contain the program name!");
  clang::CompilerInvocation *Invocation = new clang::CompilerInvocation;
  clang::CompilerInvocation::CreateFromArgs(
      *Invocation, CC1Args.data() + 1, CC1Args.data() + CC1Args.size(),
      *Diagnostics);
  Invocation->getFrontendOpts().DisableFree = false;
  return Invocation;
}

bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
                   const Twine &FileName) {
  SmallString<16> FileNameStorage;
  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
  const char *const CommandLine[] = {
      "clang-tool", "-fsyntax-only", FileNameRef.data()
  };
  FileManager Files((FileSystemOptions()));
  ToolInvocation Invocation(
      std::vector<std::string>(
          CommandLine,
          CommandLine + llvm::array_lengthof(CommandLine)),
      ToolAction, &Files);

  SmallString<1024> CodeStorage;
  Invocation.mapVirtualFile(FileNameRef,
                            Code.toNullTerminatedStringRef(CodeStorage));
  return Invocation.run();
}

/// \brief Returns the absolute path of 'File', by prepending it with
/// 'BaseDirectory' if 'File' is not absolute.
///
/// Otherwise returns 'File'.
/// If 'File' starts with "./", the returned path will not contain the "./".
/// Otherwise, the returned path will contain the literal path-concatenation of
/// 'BaseDirectory' and 'File'.
///
/// \param File Either an absolute or relative path.
/// \param BaseDirectory An absolute path.
static std::string getAbsolutePath(
    StringRef File, StringRef BaseDirectory) {
  assert(llvm::sys::path::is_absolute(BaseDirectory));
  if (llvm::sys::path::is_absolute(File)) {
    return File;
  }
  StringRef RelativePath(File);
  if (RelativePath.startswith("./")) {
    RelativePath = RelativePath.substr(strlen("./"));
  }
  llvm::SmallString<1024> AbsolutePath(BaseDirectory);
  llvm::sys::path::append(AbsolutePath, RelativePath);
  return AbsolutePath.str();
}

ToolInvocation::ToolInvocation(
    ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
    FileManager *Files)
    : CommandLine(CommandLine.vec()), ToolAction(ToolAction), Files(Files) {
}

void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {
  MappedFileContents[FilePath] = Content;
}

bool ToolInvocation::run() {
  std::vector<const char*> Argv;
  for (int I = 0, E = CommandLine.size(); I != E; ++I)
    Argv.push_back(CommandLine[I].c_str());
  const char *const BinaryName = Argv[0];
  DiagnosticOptions DefaultDiagnosticOptions;
  TextDiagnosticPrinter DiagnosticPrinter(
      llvm::errs(), DefaultDiagnosticOptions);
  DiagnosticsEngine Diagnostics(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>(
      new DiagnosticIDs()), &DiagnosticPrinter, false);

  const llvm::OwningPtr<clang::driver::Driver> Driver(
      newDriver(&Diagnostics, BinaryName));
  // Since the input might only be virtual, don't check whether it exists.
  Driver->setCheckInputsExist(false);
  const llvm::OwningPtr<clang::driver::Compilation> Compilation(
      Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
  const clang::driver::ArgStringList *const CC1Args = getCC1Arguments(
      &Diagnostics, Compilation.get());
  if (CC1Args == NULL) {
    return false;
  }
  llvm::OwningPtr<clang::CompilerInvocation> Invocation(
      newInvocation(&Diagnostics, *CC1Args));
  return runInvocation(BinaryName, Compilation.get(),
                       Invocation.take(), *CC1Args, ToolAction.take());
}

// Exists solely for the purpose of lookup of the resource path.
static int StaticSymbol;

bool ToolInvocation::runInvocation(
    const char *BinaryName,
    clang::driver::Compilation *Compilation,
    clang::CompilerInvocation *Invocation,
    const clang::driver::ArgStringList &CC1Args,
    clang::FrontendAction *ToolAction) {
  llvm::OwningPtr<clang::FrontendAction> ScopedToolAction(ToolAction);
  // Show the invocation, with -v.
  if (Invocation->getHeaderSearchOpts().Verbose) {
    llvm::errs() << "clang Invocation:\n";
    Compilation->PrintJob(llvm::errs(), Compilation->getJobs(), "\n", true);
    llvm::errs() << "\n";
  }

  // Create a compiler instance to handle the actual work.
  clang::CompilerInstance Compiler;
  Compiler.setInvocation(Invocation);
  Compiler.setFileManager(Files);
  // FIXME: What about LangOpts?

  // Create the compilers actual diagnostics engine.
  Compiler.createDiagnostics(CC1Args.size(),
                             const_cast<char**>(CC1Args.data()));
  if (!Compiler.hasDiagnostics())
    return false;

  Compiler.createSourceManager(*Files);
  addFileMappingsTo(Compiler.getSourceManager());

  // Infer the builtin include path if unspecified.
  if (Compiler.getHeaderSearchOpts().UseBuiltinIncludes &&
      Compiler.getHeaderSearchOpts().ResourceDir.empty()) {
    // This just needs to be some symbol in the binary.
    void *const SymbolAddr = &StaticSymbol;
    Compiler.getHeaderSearchOpts().ResourceDir =
        clang::CompilerInvocation::GetResourcesPath(BinaryName, SymbolAddr);
  }

  const bool Success = Compiler.ExecuteAction(*ToolAction);

  Compiler.resetAndLeakFileManager();
  return Success;
}

void ToolInvocation::addFileMappingsTo(SourceManager &Sources) {
  for (llvm::StringMap<StringRef>::const_iterator
           It = MappedFileContents.begin(), End = MappedFileContents.end();
       It != End; ++It) {
    // Inject the code as the given file name into the preprocessor options.
    const llvm::MemoryBuffer *Input =
        llvm::MemoryBuffer::getMemBuffer(It->getValue());
    // FIXME: figure out what '0' stands for.
    const FileEntry *FromFile = Files->getVirtualFile(
        It->getKey(), Input->getBufferSize(), 0);
    // FIXME: figure out memory management ('true').
    Sources.overrideFileContents(FromFile, Input, true);
  }
}

ClangTool::ClangTool(const CompilationDatabase &Compilations,
                     ArrayRef<std::string> SourcePaths)
    : Files((FileSystemOptions())) {
  llvm::SmallString<1024> BaseDirectory;
  llvm::sys::fs::current_path(BaseDirectory);
  for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
    llvm::SmallString<1024> File(getAbsolutePath(
        SourcePaths[I], BaseDirectory));

    std::vector<CompileCommand> CompileCommands =
      Compilations.getCompileCommands(File.str());
    if (!CompileCommands.empty()) {
      for (int I = 0, E = CompileCommands.size(); I != E; ++I) {
        CompileCommand &Command = CompileCommands[I];
        if (!Command.Directory.empty()) {
          // FIXME: What should happen if CommandLine includes -working-directory
          // as well?
          Command.CommandLine.push_back(
            "-working-directory=" + Command.Directory);
        }
        CommandLines.push_back(std::make_pair(File.str(), Command.CommandLine));
      }
    } else {
      // FIXME: There are two use cases here: doing a fuzzy
      // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
      // about the .cc files that were not found, and the use case where I
      // specify all files I want to run over explicitly, where this should
      // be an error. We'll want to add an option for this.
      llvm::outs() << "Skipping " << File << ". Command line not found.\n";
    }
  }
}

void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
  MappedFileContents.push_back(std::make_pair(FilePath, Content));
}

int ClangTool::run(FrontendActionFactory *ActionFactory) {
  bool ProcessingFailed = false;
  for (unsigned I = 0; I < CommandLines.size(); ++I) {
    std::string File = CommandLines[I].first;
    std::vector<std::string> &CommandLine = CommandLines[I].second;
    llvm::outs() << "Processing: " << File << ".\n";
    ToolInvocation Invocation(CommandLine, ActionFactory->create(), &Files);
    for (int I = 0, E = MappedFileContents.size(); I != E; ++I) {
      Invocation.mapVirtualFile(MappedFileContents[I].first,
                                MappedFileContents[I].second);
    }
    if (!Invocation.run()) {
      llvm::outs() << "Error while processing " << File << ".\n";
      ProcessingFailed = true;
    }
  }
  return ProcessingFailed ? 1 : 0;
}

} // end namespace tooling
} // end namespace clang
<|endoftext|>


<commit_before>#include <osgDB/ReadFile>

#include "util.h"

Vec3f* ph::computeNormal(Vec3f a, Vec3f b, Vec3f c) {
    Vec3f* r = new Vec3f;
    r->set((b-a)^(c-a));
    r->normalize();
    return r;
}

ref_ptr<Vec3Array> ph::buildNormals(ref_ptr<Vec3Array> vertices, ref_ptr<DrawElementsUInt> indices) {
    ref_ptr<Vec3Array> normals = new Vec3Array(indices->size()/3);
    Vec3f* normal;

    for (int i = 0; i < indices->size(); i += 3) {
        normal = computeNormal((*vertices)[(*indices)[i]],
                               (*vertices)[(*indices)[i+1]],
                               (*vertices)[(*indices)[i+2]]);
        (*normals)[i/3].set(*normal);
        delete normal;
    }

    vertices.release();
    indices.release();
    return normals.release();
}

PositionAttitudeTransform* ph::getDebugAxes(double scale, double dx, double dy, double dz) {
    ref_ptr<PositionAttitudeTransform> axes = new PositionAttitudeTransform;
    axes->setScale(Vec3d(scale, scale, scale));
    axes->setPosition(Vec3d(dx, dy, dz));
    axes->addChild(osgDB::readNodeFile("../resources/axes.osgt"));
    return axes.release();
}

// Funktionszeiger für gängige Funktionstypen

// f(x)= factor* sin(x); mit 2*PI für Kreisbewegungen
double ph::sin_f(const double factor, double x) {
	return factor* sinf(2*PI*x);
}

// f(x)= factor* cos(x); mit 2*PI für Kreisbewegungen
double ph::cos_f(const double factor, double x) {
	return factor* cosf(2*PI*x);
}

// f(x)= factor* x
double ph::lin_f(const double factor, double x) {
    return factor* x;
}

// f(x)= x^factor
double ph::quad_f(const double factor, double x) {
    return pow(x, factor);
}

// f(x)= factor^x
double ph::pot_f(const double factor, double x) {
    return pow(factor, x);
}

// Erstellt einen Animationspfad
/* create AnimationPath(Zeit, Funktion für rotation,
                        Animationsmodus, Rotationsachse,
                        Funktion zur Bewegung in x, Funktionsfaktor in x,
                        Funktion zur Bewegung in y, Funktionsfaktor in y,
                        Funktion zur Bewegung in z, Funktionsfaktor in z)*/
osg::AnimationPath* ph::createAnimationPath( float time, float func,
                                       ph::AnimationMode mode, ph::RotationAxis rAxis,
                                       double (*f_x) (double,double), double fac_x,
                                       double (*f_y) (double,double), double fac_y,
                                       double (*f_z) (double,double), double fac_z) {
    osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;

    // Animationsmodus ermitteln
    switch (mode) {
    case LOOP: path->setLoopMode( osg::AnimationPath::LOOP ); break;
    case SWING: path->setLoopMode( osg::AnimationPath::SWING ); break;
    }

    // Rotationsachse festlegen
    Vec3 tAxis;
    switch (rAxis) {
    case POS_X_AXIS: tAxis = Vec3(1.0, 0.0, 0.0); break;
    case POS_Y_AXIS: tAxis = Vec3(0.0, 1.0, 0.0); break;
    case POS_Z_AXIS: tAxis = Vec3(0.0, 0.0, 1.0); break;
    case NEG_X_AXIS: tAxis = Vec3(-1.0, 0.0, 0.0); break;
    case NEG_Y_AXIS: tAxis = Vec3(0.0, -1.0, 0.0); break;
    case NEG_Z_AXIS: tAxis = Vec3(0.0, 0.0, -1.0); break;
    }

    unsigned int numSamples = (int)time;

    // Iterationsschritte bestimmen
    float delta_rot = func/time; // Rotation um func in time
    float delta_pos = 1 / time; // Bewegung um factor* func in time

    // Pfad zusammensetzen
    for ( unsigned int i=0; i<=numSamples; ++i )
    {
        float yaw = delta_rot * (float)i;
        float d_pos = delta_pos * (float)i;
        Vec3 pos( (float)f_x(fac_x,d_pos), (float)f_y(fac_y,d_pos), (float)f_z(fac_z,d_pos) );
        osg::Quat rot(yaw, tAxis);
        path->insert( (float)i, osg::AnimationPath::ControlPoint(pos,rot) );
    }
    return path.release();
}
<commit_msg>adjusting util.cpp adding default functions in Animationfunction if function pointer is null adding annotations<commit_after>#include <osgDB/ReadFile>

#include "util.h"

Vec3f* ph::computeNormal(Vec3f a, Vec3f b, Vec3f c) {
    Vec3f* r = new Vec3f;
    r->set((b-a)^(c-a));
    r->normalize();
    return r;
}

ref_ptr<Vec3Array> ph::buildNormals(ref_ptr<Vec3Array> vertices, ref_ptr<DrawElementsUInt> indices) {
    ref_ptr<Vec3Array> normals = new Vec3Array(indices->size()/3);
    Vec3f* normal;

    for (int i = 0; i < indices->size(); i += 3) {
        normal = computeNormal((*vertices)[(*indices)[i]],
                               (*vertices)[(*indices)[i+1]],
                               (*vertices)[(*indices)[i+2]]);
        (*normals)[i/3].set(*normal);
        delete normal;
    }

    vertices.release();
    indices.release();
    return normals.release();
}

PositionAttitudeTransform* ph::getDebugAxes(double scale, double dx, double dy, double dz) {
    ref_ptr<PositionAttitudeTransform> axes = new PositionAttitudeTransform;
    axes->setScale(Vec3d(scale, scale, scale));
    axes->setPosition(Vec3d(dx, dy, dz));
    axes->addChild(osgDB::readNodeFile("../resources/axes.osgt"));
    return axes.release();
}

// Funktionszeiger für gängige Funktionstypen

// f(x)= factor* sin(x); mit 2*PI für Kreisbewegungen
double ph::sin_f(const double factor, double x) {
	return factor* sinf(2*PI*x);
}

// f(x)= factor* cos(x); mit 2*PI für Kreisbewegungen
double ph::cos_f(const double factor, double x) {
	return factor* cosf(2*PI*x);
}

// f(x)= factor* x
double ph::lin_f(const double factor, double x) {
    return factor* x;
}

// f(x)= x^factor
double ph::quad_f(const double factor, double x) {
    return pow(x, factor);
}

// f(x)= factor^x
double ph::pot_f(const double factor, double x) {
    return pow(factor, x);
}

// Erstellt einen Animationspfad
/* create AnimationPath(Zeit, Funktion für rotation,
                        Animationsmodus, Rotationsachse,
                        Funktion zur Bewegung in x, Funktionsfaktor in x,
                        Funktion zur Bewegung in y, Funktionsfaktor in y,
                        Funktion zur Bewegung in z, Funktionsfaktor in z)

   Soll in eine Richtung keine Translation durchgeführt werden, muss entsprechende
   Funktion mit NULL aufgerufen werden */
osg::AnimationPath* ph::createAnimationPath( float time, float func,
                                       ph::AnimationMode mode, ph::RotationAxis rAxis,
                                       double (*f_x) (double,double), double fac_x,
                                       double (*f_y) (double,double), double fac_y,
                                       double (*f_z) (double,double), double fac_z) {
    osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;

    // Default: Keine Translation in entsprechende Richtung
    if (f_x == NULL) {f_x = lin_f; fac_x = 0;}
    if (f_y == NULL) {f_y = lin_f; fac_y = 0;}
    if (f_z == NULL) {f_z = lin_f; fac_z = 0;}

    // Animationsmodus ermitteln
    switch (mode) {
    case LOOP: path->setLoopMode( osg::AnimationPath::LOOP ); break;
    case SWING: path->setLoopMode( osg::AnimationPath::SWING ); break;
    }

    // Rotationsachse festlegen
    Vec3 tAxis;
    switch (rAxis) {
    case POS_X_AXIS: tAxis = Vec3(1.0, 0.0, 0.0); break;
    case POS_Y_AXIS: tAxis = Vec3(0.0, 1.0, 0.0); break;
    case POS_Z_AXIS: tAxis = Vec3(0.0, 0.0, 1.0); break;
    case NEG_X_AXIS: tAxis = Vec3(-1.0, 0.0, 0.0); break;
    case NEG_Y_AXIS: tAxis = Vec3(0.0, -1.0, 0.0); break;
    case NEG_Z_AXIS: tAxis = Vec3(0.0, 0.0, -1.0); break;
    }

    unsigned int numSamples = (int)time;

    // Iterationsschritte bestimmen
    float delta_rot = func/time; // Rotation um func in time
    float delta_pos = 1 / time; // Bewegung um factor* func in time

    // Pfad zusammensetzen
    for ( unsigned int i=0; i<=numSamples; ++i )
    {
        float yaw = delta_rot * (float)i;
        float d_pos = delta_pos * (float)i;
        Vec3 pos( (float)f_x(fac_x,d_pos), (float)f_y(fac_y,d_pos), (float)f_z(fac_z,d_pos) );
        osg::Quat rot(yaw, tAxis);
        path->insert( (float)i, osg::AnimationPath::ControlPoint(pos,rot) );
    }
    return path.release();
}
<|endoftext|>


<commit_before>#include "util.h"

#include <iostream>
#include <ctime>
#include <sstream>
#include <iomanip>

#include "enums.h"
#include "jsonhelp.h"

template<unsigned int N>
inline void writeBigEndian(const uint64_t val, unsigned char* buf) {
  constexpr unsigned int maskShift = (N - 1) * 8;
  constexpr uint64_t mask = (uint64_t)0xFF << maskShift;
  *buf = (val & mask) >> maskShift;
  writeBigEndian<N-1>(val, buf + 1);
}

template<>
inline void writeBigEndian<1>(const uint64_t val, unsigned char* buf) {
  *buf = val & 0xff;
}

template<unsigned int N>
inline void readBigEndian(const unsigned char* buf, uint64_t& val) {
  constexpr unsigned int shift = (N - 1) * 8;
  val |= (uint64_t)*buf << shift;
  readBigEndian<N-1>(buf + 1, val);
}

template<>
inline void readBigEndian<1>(const unsigned char* buf, uint64_t& val) {
  val |= *buf;
}

unsigned int vintEncode(unsigned char* buf, uint64_t val) {
  if (val < 241) {
    buf[0] = val;
    return 1;
  }
  else if (val < 2288) {
    const unsigned int diff = val - 240;
    buf[0] = (diff / 256) + 241;
    buf[1] = diff % 256;
    return 2;
  }
  else if (val < 67824) {
    buf[0] = 249;
    const unsigned int diff = val - 2288;
    buf[1] = diff / 256;
    buf[2] = diff % 256;
    return 3;
  }
  else if (val < (1ull << 24)) {
    buf[0] = 250;
    writeBigEndian<3>(val, &buf[1]);
    return 4;
  }
  else if (val < (1ull << 32)) {
    buf[0] = 251;
    writeBigEndian<4>(val, &buf[1]);
    return 5;
  }
  else if (val < (1ull << 40)) {
    buf[0] = 252;
    writeBigEndian<5>(val, &buf[1]);
    return 6;
  }
  else if (val < (1ull << 48)) {
    buf[0] = 253;
    writeBigEndian<6>(val, &buf[1]);
    return 7;
  }
  else if (val < (1ull << 56)) {
    buf[0] = 254;
    writeBigEndian<7>(val, &buf[1]);
    return 8;
  }
  else {
    buf[0] = 255;
    writeBigEndian<8>(val, &buf[1]);
    return 9;
  }
}

unsigned int vintDecode(uint64_t& val, const unsigned char* buf) {
  if (buf == nullptr) {
    return 0;
  }
  val = 0;
  int diff = buf[0] - 241;
  switch (diff) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7: // 241-248
      val = 256*diff + buf[1] + 240;
      return 2;
      break;
    case 8: // 249
      val = 2288 + 256*buf[1] + buf[2];
      return 3;
      break;
    case 9: // 250
      readBigEndian<3>(&buf[1], val);
      return 4;
      break;
    case 10:
      readBigEndian<4>(&buf[1], val);
      return 5;
      break;
    case 11:
      readBigEndian<5>(&buf[1], val);
      return 6;
      break;
    case 12:
      readBigEndian<6>(&buf[1], val);
      return 7;
      break;
    case 13:
      readBigEndian<7>(&buf[1], val);
      return 8;
      break;
    case 14:
      readBigEndian<8>(&buf[1], val);
      return 9;
      break;
    default:
      val = buf[0];
      return 1;
  }
}

std::string appendVarint(const std::string& base, const unsigned int val) {
  unsigned char encoded[9];
  auto bytes = vintEncode(encoded, val);
  std::string ret(base);
  ret += bytesAsString(encoded, encoded + bytes);
  return ret;
}

std::string makeChildID(const unsigned char* parentID, unsigned int len, unsigned int childIndex) {
  std::string ret;
  if (len > 1) {
    ret += "00";
    uint64_t level;
    unsigned int levelLength = vintDecode(level, &parentID[1]);
    if (1 + levelLength > len) {
      return "";
    }
    ++level;
    ret = appendVarint(ret, level);
    ret += bytesAsString(&parentID[1 + levelLength], &parentID[len]);
    ret += appendVarint(ret, childIndex);
  }
  return ret;
}

std::string formatTimestamp(uint32_t unix, uint32_t ns) {
  std::string ret;
  time_t ts = unix;
  tm* tmPtr = gmtime(&ts);
  char tbuf[100];
  size_t len = strftime(tbuf, 100, "%FT%T", tmPtr);
  if (len) {
    ret.append(tbuf);
    std::stringstream buf;
    buf.setf(std::ios::fixed, std::ios::floatfield);
    buf.precision(8);
    buf << double(ns)/1000000000;
    std::string frac = buf.str();
    frac.erase(0, 1); // leading 0
    std::string::iterator zeroItr(frac.end());
    --zeroItr;
    while (zeroItr != frac.begin() && *zeroItr == '0') {
      --zeroItr;
    }
    ++zeroItr;
    frac.erase(zeroItr, frac.end());
    ret.append(frac);
    ret.append("Z");
  }
  return ret;
}

std::string bytesAsString(const unsigned char* idBeg, const unsigned char* idEnd) {
  std::stringstream buf;
  unsigned short val;
  for (const unsigned char* cur = idBeg; cur < idEnd; ++cur) {
    val = *cur;
    buf.width(2);
    buf.fill('0');
    buf << std::hex;
    buf << val;
  }
  return buf.str();
}

std::string makeInodeID(uint32_t volIndex, uint64_t inum) {
  std::stringstream buf;
  buf.width(2);
  buf.fill('0');
  buf << std::hex << RecordTypes::INODE;
  buf.width(2 * sizeof(volIndex));
  buf.fill('0');
  buf << std::hex << volIndex;
  buf.width(2 * sizeof(inum));
  buf.fill('0');
  buf << std::hex << inum;
  return buf.str();
}

std::string makeDiskMapID(uint64_t offset) {
  std::stringstream buf;
  buf.width(2);
  buf.fill('0');
  buf << std::hex << RecordTypes::DISK_MAP;
  buf.width(2 * sizeof(offset));
  buf.fill('0');
  buf << offset;
  return buf.str();
}

std::string j(const std::string& x) {
  std::string s("\"");
  s += x;
  s += "\"";
  return s;
}

// template<>
// std::string j<char>(const char* x) {
//   return j(std::string(x));
// }
<commit_msg>If there's no fractional part, remove the decimal point entirely.<commit_after>#include "util.h"

#include <iostream>
#include <ctime>
#include <sstream>
#include <iomanip>

#include "enums.h"
#include "jsonhelp.h"

template<unsigned int N>
inline void writeBigEndian(const uint64_t val, unsigned char* buf) {
  constexpr unsigned int maskShift = (N - 1) * 8;
  constexpr uint64_t mask = (uint64_t)0xFF << maskShift;
  *buf = (val & mask) >> maskShift;
  writeBigEndian<N-1>(val, buf + 1);
}

template<>
inline void writeBigEndian<1>(const uint64_t val, unsigned char* buf) {
  *buf = val & 0xff;
}

template<unsigned int N>
inline void readBigEndian(const unsigned char* buf, uint64_t& val) {
  constexpr unsigned int shift = (N - 1) * 8;
  val |= (uint64_t)*buf << shift;
  readBigEndian<N-1>(buf + 1, val);
}

template<>
inline void readBigEndian<1>(const unsigned char* buf, uint64_t& val) {
  val |= *buf;
}

unsigned int vintEncode(unsigned char* buf, uint64_t val) {
  if (val < 241) {
    buf[0] = val;
    return 1;
  }
  else if (val < 2288) {
    const unsigned int diff = val - 240;
    buf[0] = (diff / 256) + 241;
    buf[1] = diff % 256;
    return 2;
  }
  else if (val < 67824) {
    buf[0] = 249;
    const unsigned int diff = val - 2288;
    buf[1] = diff / 256;
    buf[2] = diff % 256;
    return 3;
  }
  else if (val < (1ull << 24)) {
    buf[0] = 250;
    writeBigEndian<3>(val, &buf[1]);
    return 4;
  }
  else if (val < (1ull << 32)) {
    buf[0] = 251;
    writeBigEndian<4>(val, &buf[1]);
    return 5;
  }
  else if (val < (1ull << 40)) {
    buf[0] = 252;
    writeBigEndian<5>(val, &buf[1]);
    return 6;
  }
  else if (val < (1ull << 48)) {
    buf[0] = 253;
    writeBigEndian<6>(val, &buf[1]);
    return 7;
  }
  else if (val < (1ull << 56)) {
    buf[0] = 254;
    writeBigEndian<7>(val, &buf[1]);
    return 8;
  }
  else {
    buf[0] = 255;
    writeBigEndian<8>(val, &buf[1]);
    return 9;
  }
}

unsigned int vintDecode(uint64_t& val, const unsigned char* buf) {
  if (buf == nullptr) {
    return 0;
  }
  val = 0;
  int diff = buf[0] - 241;
  switch (diff) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7: // 241-248
      val = 256*diff + buf[1] + 240;
      return 2;
      break;
    case 8: // 249
      val = 2288 + 256*buf[1] + buf[2];
      return 3;
      break;
    case 9: // 250
      readBigEndian<3>(&buf[1], val);
      return 4;
      break;
    case 10:
      readBigEndian<4>(&buf[1], val);
      return 5;
      break;
    case 11:
      readBigEndian<5>(&buf[1], val);
      return 6;
      break;
    case 12:
      readBigEndian<6>(&buf[1], val);
      return 7;
      break;
    case 13:
      readBigEndian<7>(&buf[1], val);
      return 8;
      break;
    case 14:
      readBigEndian<8>(&buf[1], val);
      return 9;
      break;
    default:
      val = buf[0];
      return 1;
  }
}

std::string appendVarint(const std::string& base, const unsigned int val) {
  unsigned char encoded[9];
  auto bytes = vintEncode(encoded, val);
  std::string ret(base);
  ret += bytesAsString(encoded, encoded + bytes);
  return ret;
}

std::string makeChildID(const unsigned char* parentID, unsigned int len, unsigned int childIndex) {
  std::string ret;
  if (len > 1) {
    ret += "00";
    uint64_t level;
    unsigned int levelLength = vintDecode(level, &parentID[1]);
    if (1 + levelLength > len) {
      return "";
    }
    ++level;
    ret = appendVarint(ret, level);
    ret += bytesAsString(&parentID[1 + levelLength], &parentID[len]);
    ret += appendVarint(ret, childIndex);
  }
  return ret;
}

std::string formatTimestamp(uint32_t unix, uint32_t ns) {
  std::string ret;
  time_t ts = unix;
  tm* tmPtr = gmtime(&ts);
  char tbuf[100];
  size_t len = strftime(tbuf, 100, "%FT%T", tmPtr);
  if (len) {
    ret.append(tbuf);
    if (ns) {
      std::stringstream buf;
      buf.setf(std::ios::fixed, std::ios::floatfield);
      buf.precision(8);
      buf << double(ns)/1000000000;
      std::string frac = buf.str();
      frac.erase(0, 1); // leading 0
      std::string::iterator zeroItr(frac.end());
      --zeroItr;
      while (zeroItr != frac.begin() && *zeroItr == '0') {
        --zeroItr;
      }
      ++zeroItr;
      frac.erase(zeroItr, frac.end()); // kill trailing zeroes
      ret.append(frac);
    }
    ret.append("Z");
  }
  return ret;
}

std::string bytesAsString(const unsigned char* idBeg, const unsigned char* idEnd) {
  std::stringstream buf;
  unsigned short val;
  for (const unsigned char* cur = idBeg; cur < idEnd; ++cur) {
    val = *cur;
    buf.width(2);
    buf.fill('0');
    buf << std::hex;
    buf << val;
  }
  return buf.str();
}

std::string makeInodeID(uint32_t volIndex, uint64_t inum) {
  std::stringstream buf;
  buf.width(2);
  buf.fill('0');
  buf << std::hex << RecordTypes::INODE;
  buf.width(2 * sizeof(volIndex));
  buf.fill('0');
  buf << std::hex << volIndex;
  buf.width(2 * sizeof(inum));
  buf.fill('0');
  buf << std::hex << inum;
  return buf.str();
}

std::string makeDiskMapID(uint64_t offset) {
  std::stringstream buf;
  buf.width(2);
  buf.fill('0');
  buf << std::hex << RecordTypes::DISK_MAP;
  buf.width(2 * sizeof(offset));
  buf.fill('0');
  buf << offset;
  return buf.str();
}

std::string j(const std::string& x) {
  std::string s("\"");
  s += x;
  s += "\"";
  return s;
}

// template<>
// std::string j<char>(const char* x) {
//   return j(std::string(x));
// }
<|endoftext|>


<commit_before>#include "TexturePainter.h"
#include <qlabel.h>
#include <QFileDialog>
#include <QSettings>

TexturePainter::TexturePainter(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	load();
	this->showMaximized();
	p_colordlg = new QColorDialog(this);
	p_colordlg->setWindowTitle(QColorDialog::tr("Select color"));
	ui.colorButton->setAutoFillBackground(true);
	QString styleSheet = QString("background-color: rgb(0, 0, 0);");
	ui.colorButton->setStyleSheet(styleSheet);

	//ui.cmdField->appendPlainText(QString("start"));
}

TexturePainter::~TexturePainter()
{

}

void TexturePainter::load()
{
	m_fileDir = QDir::currentPath();
	QSettings settings("TexturePainter.ini", QSettings::IniFormat);
	m_fileDir = settings.value("filepath").toString();

	QList<QAction*> windowactions = ui.menuWindows->actions();
	foreach(QAction* action , windowactions)
	{
		action->setChecked(!settings.value(action->objectName()).toBool());
		action->trigger();
	}
}

void TexturePainter::save()
{
	QSettings settings("TexturePainter.ini", QSettings::IniFormat);
    settings.setValue("filepath", m_fileDir);
	QList<QAction*> windowactions = ui.menuWindows->actions();
	foreach(QAction* action , windowactions)
	{
		settings.setValue(action->objectName(), action->isChecked());
	}
	settings.sync();
}

void TexturePainter::selectColor()
{
	QPalette pal = ui.colorButton->palette();
	QColor input = pal.color(QPalette::Button);
	p_colordlg->setCurrentColor(input);
	int resultCode = p_colordlg->exec();
	QColor result = input;
	if (resultCode == QDialog::Accepted)
		result = p_colordlg->currentColor();
	QString styleSheet = QString("background-color: rgb(%1, %2, %3);").arg(result.red()).arg(result.green()).arg(result.blue());
	ui.colorButton->setStyleSheet(styleSheet);
}

void TexturePainter::pipetteColorPicked()
{
	QColor result;
	result.setRgbF(ui.centralWidget->m_pixel[0], ui.centralWidget->m_pixel[1], ui.centralWidget->m_pixel[2]);
	QString styleSheet = QString("background-color: rgb(%1, %2, %3);").arg(result.red()).arg(result.green()).arg(result.blue());
	ui.colorButton->setStyleSheet(styleSheet);
}

void TexturePainter::updateOutputError()
{
	QByteArray data;
	//ui.cmdField->appendPlainText(QString(data));
}

void TexturePainter::updateOutputText()
{
	QByteArray data;
	//ui.cmdField->appendPlainText(QString(data));
}

#include "meshIO/OBJMeshLoader.h"
#include "renderer/OpenGL/ImmediateMeshRenderer.h"
#include "renderer/OpenGL/VBOMeshRenderer.h"
#include "geometry/RenderManager.h"
#include "QGLRenderer/QTTextureLoader.h"

void TexturePainter::addMesh()
{
	QString name = QFileDialog::getOpenFileName(this, tr("Open File"),"",tr("Mesh (*.obj)"));
	OBJMeshLoader loader;
	QTTextureLoader qtextureLoader;
	loader.setTextureLoader(&qtextureLoader);

	RenderMesh* mesh = new RenderMesh(name.toStdString());
	loader.loadFromFile(name.toStdString(), mesh);

	VBOMeshRenderer* renderer = new VBOMeshRenderer();
	renderer->setRenderMesh(mesh);

	Entity* entity = new Entity(name.toStdString());
	entity->setComponent(ComponentType::RENDER_COMPONENT, renderer);
	RenderManager::getInstance()->addIntoObjectRendererList(renderer);

}

void TexturePainter::closeEvent(QCloseEvent *event)
{
	save();
}<commit_msg>restore<commit_after>#include "TexturePainter.h"
#include <qlabel.h>
#include <QFileDialog>
#include <QSettings>

TexturePainter::TexturePainter(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	load();
	this->showMaximized();
	p_colordlg = new QColorDialog(this);
	p_colordlg->setWindowTitle(QColorDialog::tr("Select color"));
	ui.colorButton->setAutoFillBackground(true);
	QString styleSheet = QString("background-color: rgb(0, 0, 0);");
	ui.colorButton->setStyleSheet(styleSheet);

	//ui.cmdField->appendPlainText(QString("start"));
}

TexturePainter::~TexturePainter()
{

}

void TexturePainter::load()
{
	m_fileDir = QDir::currentPath();
	QSettings settings("TexturePainter.ini", QSettings::IniFormat);
	m_fileDir = settings.value("filepath").toString();
	restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());

	QList<QAction*> windowactions = ui.menuWindows->actions();
	foreach(QAction* action , windowactions)
	{
		action->setChecked(!settings.value(action->objectName()).toBool());
		action->trigger();
	}
}

void TexturePainter::save()
{
	QSettings settings("TexturePainter.ini", QSettings::IniFormat);
    settings.setValue("filepath", m_fileDir);
	QList<QAction*> windowactions = ui.menuWindows->actions();
	foreach(QAction* action , windowactions)
	{
		settings.setValue(action->objectName(), action->isChecked());
	}
	settings.setValue("geometry", saveGeometry());
    settings.setValue("windowState", saveState());
	settings.sync();

}

void TexturePainter::selectColor()
{
	QPalette pal = ui.colorButton->palette();
	QColor input = pal.color(QPalette::Button);
	p_colordlg->setCurrentColor(input);
	int resultCode = p_colordlg->exec();
	QColor result = input;
	if (resultCode == QDialog::Accepted)
		result = p_colordlg->currentColor();
	QString styleSheet = QString("background-color: rgb(%1, %2, %3);").arg(result.red()).arg(result.green()).arg(result.blue());
	ui.colorButton->setStyleSheet(styleSheet);
}

void TexturePainter::pipetteColorPicked()
{
	QColor result;
	result.setRgbF(ui.centralWidget->m_pixel[0], ui.centralWidget->m_pixel[1], ui.centralWidget->m_pixel[2]);
	QString styleSheet = QString("background-color: rgb(%1, %2, %3);").arg(result.red()).arg(result.green()).arg(result.blue());
	ui.colorButton->setStyleSheet(styleSheet);
}

void TexturePainter::updateOutputError()
{
	QByteArray data;
	//ui.cmdField->appendPlainText(QString(data));
}

void TexturePainter::updateOutputText()
{
	QByteArray data;
	//ui.cmdField->appendPlainText(QString(data));
}

#include "meshIO/OBJMeshLoader.h"
#include "renderer/OpenGL/ImmediateMeshRenderer.h"
#include "renderer/OpenGL/VBOMeshRenderer.h"
#include "geometry/RenderManager.h"
#include "QGLRenderer/QTTextureLoader.h"

void TexturePainter::addMesh()
{
	QString name = QFileDialog::getOpenFileName(this, tr("Open File"),"",tr("Mesh (*.obj)"));
	OBJMeshLoader loader;
	QTTextureLoader qtextureLoader;
	loader.setTextureLoader(&qtextureLoader);

	RenderMesh* mesh = new RenderMesh(name.toStdString());
	loader.loadFromFile(name.toStdString(), mesh);

	VBOMeshRenderer* renderer = new VBOMeshRenderer();
	renderer->setRenderMesh(mesh);

	Entity* entity = new Entity(name.toStdString());
	entity->setComponent(ComponentType::RENDER_COMPONENT, renderer);
	RenderManager::getInstance()->addIntoObjectRendererList(renderer);

}

void TexturePainter::closeEvent(QCloseEvent *event)
{
	save();
	QMainWindow::closeEvent(event);
}<|endoftext|>


<commit_before>#include <vector>
#include "Halide.h"

using namespace Halide;

namespace {

// Generator class for BLAS gemm operations.
template<class T>
class GEMMGenerator :
        public Generator<GEMMGenerator<T>> {
  public:
    typedef Generator<GEMMGenerator<T>> Base;
    using Base::target;
    using Base::get_target;
    using Base::natural_vector_size;

    GeneratorParam<bool> transpose_A_ = {"transpose_A", false};
    GeneratorParam<bool> transpose_B_ = {"transpose_B", false};

    // Standard ordering of parameters in GEMM functions.
    Param<T>   a_ = {"a", 1.0};
    ImageParam A_ = {type_of<T>(), 2, "A"};
    ImageParam B_ = {type_of<T>(), 2, "B"};
    Param<T>   b_ = {"b", 1.0};
    ImageParam C_ = {type_of<T>(), 2, "C"};

    Var i, j, ii, ji, jii, io, jo, ti, tj, t;

    Func build() {
        const Expr num_rows = (A_.width()/32)*32;
        const Expr num_cols = (B_.height()/32)*32;
        const Expr sum_size = (A_.height()/32)*32;

        // Instead of transposing B, swap A and B, transpose A, and
        // then transpose AB.
        bool transpose_AB = false;
        if (transpose_B_) {
            std::swap(A_, B_);
            transpose_A_.set(!transpose_A_);
            transpose_B_.set(false);
            transpose_AB = true;
        }

        Var ti[3], tj[3];
        Func result("result");

        // Swizzle A for better memory order in the inner loop.
        Func A("A"), B("B"), As("As"), Atmp("Atmp");
        Atmp(i, j) = A_(i, j);
        if (transpose_A_) {
            As(i, j, io) = Atmp(j, io*16 + i);
        } else {
            As(i, j, io) = Atmp(io*16 + i, j);
        }
        A(i, j) = As(i % 16, j, i / 16);

        As.compute_root()
            .split(j, jo, ji, 16).reorder(i, ji, io, jo)
            .unroll(i).vectorize(ji)
            .specialize(A_.width() >= 256 && A_.height() >= 256).parallel(jo, 4);
        Atmp.compute_at(As, io).vectorize(i).unroll(j);

        if (transpose_B_) {
            Func tmp;
            tmp(i, j) = B_(j, i);
            B(i, j) = tmp(i, j);

            B.compute_at(result, Var::outermost()).tile(i, j, ii, ji, 4, 4).vectorize(ii).unroll(ji).parallel(j);
            B.bound(i, 0, sum_size).bound(j, 0, num_cols);
            tmp.compute_at(B, i).vectorize(j).unroll(i);
        } else {
            B(i, j) = B_(i, j);
        }

        Var k("k");
        Func prod;
        // Express all the products we need to do a matrix multiply as a 3D Func.
        prod(k, i, j) = A(i, k) * B(k, j);

        // Reduce the products along k.
        Func AB("AB");
        RDom rv(0, sum_size);
        AB(i, j) += prod(rv, i, j);

        Func ABt("ABt");
        if (transpose_AB) {
            // Transpose A*B if necessary.
            ABt(i, j) = AB(j, i);
        } else {
            ABt(i, j) = AB(i, j);
        }

        // Do the part that makes it a 'general' matrix multiply.
        result(i, j) = (a_ * ABt(i, j) + b_ * C_(i, j));

        if (transpose_AB) {
            result
                .tile(i, j, ii, ji, 4, 16).vectorize(ii).unroll(ji)
                .tile(i, j, ti[0], tj[0], i, j, 4, 1);
        } else {
            result
                .tile(i, j, ii, ji, 16, 4).vectorize(ii).unroll(ji)
                .tile(i, j, ti[0], tj[0], i, j, 1, 4);
        }
        result.tile(ti[0], tj[0], ti[0], tj[0], ti[1], tj[1], 2, 2);

        // If we have enough work per task, parallelize over these tiles.
        result.specialize(num_rows >= 256 && num_cols >= 256)
            .fuse(tj[0], ti[0], t).parallel(t);

        // Otherwise tile one more time before parallelizing, or don't
        // parallelize at all.
        result.specialize(num_rows >= 128 && num_cols >= 128)
            .tile(ti[0], tj[0], ti[0], tj[0], ti[2], tj[2], 2, 2)
            .fuse(tj[0], ti[0], t).parallel(t);

        result.bound(i, 0, num_rows).bound(j, 0, num_cols);

        AB
            .compute_at(result, i).unroll(j).vectorize(i)
            .update().reorder(i, j, rv).unroll(j).unroll(rv, 2).vectorize(i);

        if (transpose_AB) {
            ABt.compute_at(result, i).unroll(i).vectorize(j);
        }

        A_.set_min(0, 0).set_min(1, 0);
        B_.set_bounds(0, 0, sum_size).set_min(1, 0);
        C_.set_bounds(0, 0, num_rows).set_bounds(1, 0, num_cols);
        result.output_buffer().set_bounds(0, 0, num_rows).set_bounds(1, 0, num_cols);

        return result;
    }
};

RegisterGenerator<GEMMGenerator<float>>    register_sgemm("sgemm");
RegisterGenerator<GEMMGenerator<double>>   register_dgemm("dgemm");

}  // namespace
<commit_msg>Fix dgemm<commit_after>#include <vector>
#include "Halide.h"

using namespace Halide;

namespace {

// Generator class for BLAS gemm operations.
template<class T>
class GEMMGenerator :
        public Generator<GEMMGenerator<T>> {
  public:
    typedef Generator<GEMMGenerator<T>> Base;
    using Base::target;
    using Base::get_target;
    using Base::natural_vector_size;

    GeneratorParam<bool> transpose_A_ = {"transpose_A", false};
    GeneratorParam<bool> transpose_B_ = {"transpose_B", false};

    // Standard ordering of parameters in GEMM functions.
    Param<T>   a_ = {"a", 1.0};
    ImageParam A_ = {type_of<T>(), 2, "A"};
    ImageParam B_ = {type_of<T>(), 2, "B"};
    Param<T>   b_ = {"b", 1.0};
    ImageParam C_ = {type_of<T>(), 2, "C"};

    Var i, j, ii, ji, jii, io, jo, ti, tj, t;

    Func build() {
        const Expr num_rows = (A_.width()/32)*32;
        const Expr num_cols = (B_.height()/32)*32;
        const Expr sum_size = (A_.height()/32)*32;

        const int vec = natural_vector_size(a_.type());
        const int s = vec * 2;

        // Instead of transposing B, swap A and B, transpose A, and
        // then transpose AB.
        bool transpose_AB = false;
        if (transpose_B_) {
            std::swap(A_, B_);
            transpose_A_.set(!transpose_A_);
            transpose_B_.set(false);
            transpose_AB = true;
        }

        Var ti[3], tj[3];
        Func result("result");

        // Swizzle A for better memory order in the inner loop.
        Func A("A"), B("B"), As("As"), Atmp("Atmp");
        Atmp(i, j) = A_(i, j);
        if (transpose_A_) {
            As(i, j, io) = Atmp(j, io*s + i);
        } else {
            As(i, j, io) = Atmp(io*s + i, j);
        }
        A(i, j) = As(i % s, j, i / s);

        As.compute_root()
            .split(j, jo, ji, s).reorder(i, ji, io, jo)
            .unroll(i).vectorize(ji)
            .specialize(A_.width() >= 256 && A_.height() >= 256).parallel(jo, 4);
        Atmp.compute_at(As, io).vectorize(i).unroll(j);

        if (transpose_B_) {
            Func tmp;
            tmp(i, j) = B_(j, i);
            B(i, j) = tmp(i, j);

            B.compute_at(result, Var::outermost()).tile(i, j, ii, ji, 4, 4).vectorize(ii).unroll(ji).parallel(j);
            B.bound(i, 0, sum_size).bound(j, 0, num_cols);
            tmp.compute_at(B, i).vectorize(j).unroll(i);
        } else {
            B(i, j) = B_(i, j);
        }

        Var k("k");
        Func prod;
        // Express all the products we need to do a matrix multiply as a 3D Func.
        prod(k, i, j) = A(i, k) * B(k, j);

        // Reduce the products along k.
        Func AB("AB");
        RDom rv(0, sum_size);
        AB(i, j) += prod(rv, i, j);

        Func ABt("ABt");
        if (transpose_AB) {
            // Transpose A*B if necessary.
            ABt(i, j) = AB(j, i);
        } else {
            ABt(i, j) = AB(i, j);
        }

        // Do the part that makes it a 'general' matrix multiply.
        result(i, j) = (a_ * ABt(i, j) + b_ * C_(i, j));

        if (transpose_AB) {
            result
                .tile(i, j, ii, ji, 4, s).vectorize(ii).unroll(ji)
                .tile(i, j, ti[0], tj[0], i, j, s/4, 1);
        } else {
            result
                .tile(i, j, ii, ji, s, 4).vectorize(ii).unroll(ji)
                .tile(i, j, ti[0], tj[0], i, j, 1, s/4);
        }
        result.tile(ti[0], tj[0], ti[0], tj[0], ti[1], tj[1], 2, 2);

        // If we have enough work per task, parallelize over these tiles.
        result.specialize(num_rows >= 256 && num_cols >= 256)
            .fuse(tj[0], ti[0], t).parallel(t);

        // Otherwise tile one more time before parallelizing, or don't
        // parallelize at all.
        result.specialize(num_rows >= 128 && num_cols >= 128)
            .tile(ti[0], tj[0], ti[0], tj[0], ti[2], tj[2], 2, 2)
            .fuse(tj[0], ti[0], t).parallel(t);

        result.bound(i, 0, num_rows).bound(j, 0, num_cols);

        AB
            .compute_at(result, i).unroll(j).vectorize(i)
            .update().reorder(i, j, rv).unroll(j).unroll(rv, 2).vectorize(i);

        if (transpose_AB) {
            ABt.compute_at(result, i).unroll(i).vectorize(j);
        }

        A_.set_min(0, 0).set_min(1, 0);
        B_.set_bounds(0, 0, sum_size).set_min(1, 0);
        C_.set_bounds(0, 0, num_rows).set_bounds(1, 0, num_cols);
        result.output_buffer().set_bounds(0, 0, num_rows).set_bounds(1, 0, num_cols);

        return result;
    }
};

RegisterGenerator<GEMMGenerator<float>>    register_sgemm("sgemm");
RegisterGenerator<GEMMGenerator<double>>   register_dgemm("dgemm");

}  // namespace
<|endoftext|>


<commit_before>// -*- c-file-style: "cc-mode" -*-

#include "hemi.hpp"

extern "C" void Context_dealloc(Context* self) {
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" int Context_init(Context *self, PyObject *args, PyObject *kwds) {
    using namespace v8;

    HandleScope handle_scope;

    self->context = v8::Context::New();

    v8::Context::Scope context_scope(self->context);

    char* _source;

    if(!PyArg_ParseTuple(args, "es", "utf-8", &_source))
        return -1;

    Handle<String> source = String::New(_source);

    PyMem_Free(_source);

    TryCatch trycatch;

    Handle<Script> script = Script::Compile(source);

    if(script.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return -1;
    }

    script->Run();

    return 0;
}

extern "C" PyObject * Context_getglobals(Context *self, void *closure) {
    using namespace v8;

    v8::Context::Scope context_scope(self->context);

    HandleScope handle_scope;

    Handle<Value> object(self->context->Global());

    PyObject *wrapped = wrap(self->context, Handle<v8::Object>(), object);

    return wrapped;
}

extern "C" void Object_dealloc(Object* self) {
    self->object.Dispose();
    self->parent.Dispose();
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Object_getitem(Object *self, PyObject *item) {
    using namespace v8;

    if(PyUnicode_Check(item)) {
        PyObject *_item = PyUnicode_AsUTF8String(item);

        v8::Context::Scope context_scope(self->context);

        Handle<Value> result = self->object->GetRealNamedProperty(String::New(PyString_AS_STRING(_item)));

        Py_DECREF(_item);

        if(!result.IsEmpty())
            return wrap(self->context, self->object, result);
    }

    PyErr_SetObject(PyExc_KeyError, item);

    return NULL;
};

extern "C" PyObject * Object_getattr(Object *self, PyObject *name) {
    using namespace v8;

    PyObject *value = PyObject_GenericGetAttr((PyObject *)self, name);

    if(value != NULL)
        return value;

    char *_name = PyString_AsString(name);

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<Value> result = self->object->GetRealNamedProperty(String::New(_name));

    if(result.IsEmpty()) {
        // Exception already set by GetAttr
        return NULL;
    }

    // Have to reset exception raised by GetAttr
    PyErr_Clear();

    return wrap(self->context, self->object, result);
};

extern "C" PyObject * Function_call(Object *self, PyObject *args, PyObject *kw) {
    int argc = (int)PySequence_Size(args);

    v8::HandleScope handle_scope;

    v8::Handle<v8::Value> argv[argc];

    for(int i = 0; i < argc; i++) {
        argv[i] = py_to_json(PySequence_GetItem(args, i));
    }

    v8::Handle<v8::Value> result = self->object.As<v8::Function>()->Call(self->parent, argc, argv);

    return wrap(self->context, v8::Handle<v8::Object>(), result);
};

v8::Handle<v8::Value> py_to_json(PyObject *py) {
    if(py == Py_True)
        return v8::True();

    if(py == Py_False)
        return v8::False();

    if(py == Py_None)
        return v8::Null();

    if(PyInt_Check(py)) {
        long value = PyInt_AS_LONG(py);

        if(sizeof(long) == sizeof(int32_t)) {
            return v8::Integer::New(value);
        } else {
            if(-value < 1 << 16 && value < 1 << 16)
                return v8::Integer::New(value);

            if(value > 0 && value < 1 << 32)
                return v8::Integer::NewFromUnsigned(value);
        }
    }

    if(PyFloat_Check(py))
        return v8::Number::New(PyFloat_AS_DOUBLE(py));

    if(PyUnicode_Check(py)) {
        PyObject *py_string = PyUnicode_AsUTF8String(py);

        v8::Handle<v8::String> js_string = v8::String::New(PyString_AS_STRING(py_string));

        return js_string;
    }

    if(PyList_Check(py)) {
        uint32_t length = PyList_GET_SIZE(py);

        v8::Handle<v8::Array> array = v8::Array::New(length);

        for(uint32_t i = 0; i < length; i++) {
            v8::Handle<v8::Value> item = py_to_json(PyList_GET_ITEM(py, i));

            array->Set(i, item);
        }

        return array;
    }

    if(PyDict_Check(py)) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;

        v8::Handle<v8::Object> object = v8::Object::New();

        while(PyDict_Next(py, &pos, &key, &value)) {
            v8::Handle<v8::Value> js_key = py_to_json(key);

            object->Set(js_key, py_to_json(value));
        }

        return object;
    }

    throw "hello";
};

PyObject * wrap(v8::Handle<v8::Context> context, v8::Handle<v8::Object> parent, v8::Handle<v8::Value> value) {
    if(value->IsInt32())
        return PyInt_FromLong(value->Int32Value());

    if(value->IsNumber())
        return PyFloat_FromDouble(value->NumberValue());

    if(value->IsBoolean())
        return PyBool_FromLong(value->BooleanValue());

    if(value->IsNull())
        Py_RETURN_NONE;

    if(value->IsUndefined()) {
        return Py_INCREF(Undefined), Undefined;
    }

    if(value->IsString()) {
        v8::String::Utf8Value utf_string(value);
        return PyUnicode_FromString(*utf_string);
    }

    Object *object;

    if (value->IsFunction()) {
        object = PyObject_New(Object, &FunctionType);
    } else {
        object = PyObject_New(Object, &ObjectType);
    }

    object->context = v8::Persistent<v8::Context>::New(context);
    object->parent = v8::Persistent<v8::Object>::New(parent);
    object->object = v8::Persistent<v8::Object>::New(value.As<v8::Object>());

    return (PyObject *)object;
}

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
inithemi(void)
{
    PyObject* m;

    ContextType.tp_new = PyType_GenericNew;

    if (PyType_Ready(&ContextType) < 0)
        return;

    if (PyType_Ready(&ObjectType) < 0)
        return;

    if (PyType_Ready(&FunctionType) < 0)
        return;

    if (PyType_Ready(&UndefinedType) < 0)
        return;

    Undefined = PyObject_New(PyObject, &UndefinedType);

    m = Py_InitModule3("hemi", module_methods,
                       "Lightweight V8 wrapper.");

    Py_INCREF(&ContextType);
    PyModule_AddObject(m, "Context", (PyObject *)&ContextType);
}
<commit_msg>Test for reuse<commit_after>// -*- c-file-style: "cc-mode" -*-

#include "hemi.hpp"

extern "C" void Context_dealloc(Context* self) {
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" int Context_init(Context *self, PyObject *args, PyObject *kwds) {
    using namespace v8;

    HandleScope handle_scope;

    self->context = v8::Context::New();

    v8::Context::Scope context_scope(self->context);

    char* _source;

    if(!PyArg_ParseTuple(args, "es", "utf-8", &_source))
        return -1;

    Handle<String> source = String::New(_source);

    PyMem_Free(_source);

    TryCatch trycatch;

    Handle<Script> script = Script::Compile(source);

    if(script.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return -1;
    }

    script->Run();

    return 0;
}

extern "C" PyObject * Context_getglobals(Context *self, void *closure) {
    using namespace v8;

    v8::Context::Scope context_scope(self->context);

    HandleScope handle_scope;

    Handle<Value> object(self->context->Global());

    PyObject *wrapped = wrap(self->context, Handle<v8::Object>(), object);

    return wrapped;
}

extern "C" void Object_dealloc(Object* self) {
    v8::HandleScope handle_scope;

    self->object->DeleteHiddenValue(v8::String::New("hemi::wrapper"));

    self->object.Dispose();
    self->parent.Dispose();
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Object_getitem(Object *self, PyObject *item) {
    using namespace v8;

    if(PyUnicode_Check(item)) {
        PyObject *_item = PyUnicode_AsUTF8String(item);

        v8::Context::Scope context_scope(self->context);

        Handle<Value> result = self->object->GetRealNamedProperty(String::New(PyString_AS_STRING(_item)));

        Py_DECREF(_item);

        if(!result.IsEmpty())
            return wrap(self->context, self->object, result);
    }

    PyErr_SetObject(PyExc_KeyError, item);

    return NULL;
};

extern "C" PyObject * Object_getattr(Object *self, PyObject *name) {
    using namespace v8;

    PyObject *value = PyObject_GenericGetAttr((PyObject *)self, name);

    if(value != NULL)
        return value;

    char *_name = PyString_AsString(name);

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<Value> result = self->object->GetRealNamedProperty(String::New(_name));

    if(result.IsEmpty()) {
        // Exception already set by GetAttr
        return NULL;
    }

    // Have to reset exception raised by GetAttr
    PyErr_Clear();

    return wrap(self->context, self->object, result);
};

extern "C" PyObject * Function_call(Object *self, PyObject *args, PyObject *kw) {
    int argc = (int)PySequence_Size(args);

    v8::HandleScope handle_scope;

    v8::Handle<v8::Value> argv[argc];

    for(int i = 0; i < argc; i++) {
        argv[i] = py_to_json(PySequence_GetItem(args, i));
    }

    v8::Handle<v8::Value> result = self->object.As<v8::Function>()->Call(self->parent, argc, argv);

    return wrap(self->context, v8::Handle<v8::Object>(), result);
};

v8::Handle<v8::Value> py_to_json(PyObject *py) {
    if(py == Py_True)
        return v8::True();

    if(py == Py_False)
        return v8::False();

    if(py == Py_None)
        return v8::Null();

    if(PyInt_Check(py)) {
        long value = PyInt_AS_LONG(py);

        if(sizeof(long) == sizeof(int32_t)) {
            return v8::Integer::New(value);
        } else {
            if(-value < 1 << 16 && value < 1 << 16)
                return v8::Integer::New(value);

            if(value > 0 && value < 1 << 32)
                return v8::Integer::NewFromUnsigned(value);
        }
    }

    if(PyFloat_Check(py))
        return v8::Number::New(PyFloat_AS_DOUBLE(py));

    if(PyUnicode_Check(py)) {
        PyObject *py_string = PyUnicode_AsUTF8String(py);

        v8::Handle<v8::String> js_string = v8::String::New(PyString_AS_STRING(py_string));

        return js_string;
    }

    if(PyList_Check(py)) {
        uint32_t length = PyList_GET_SIZE(py);

        v8::Handle<v8::Array> array = v8::Array::New(length);

        for(uint32_t i = 0; i < length; i++) {
            v8::Handle<v8::Value> item = py_to_json(PyList_GET_ITEM(py, i));

            array->Set(i, item);
        }

        return array;
    }

    if(PyDict_Check(py)) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;

        v8::Handle<v8::Object> object = v8::Object::New();

        while(PyDict_Next(py, &pos, &key, &value)) {
            v8::Handle<v8::Value> js_key = py_to_json(key);

            object->Set(js_key, py_to_json(value));
        }

        return object;
    }

    throw "hello";
};

PyObject * wrap(v8::Handle<v8::Context> context, v8::Handle<v8::Object> parent, v8::Handle<v8::Value> value) {
    if(value->IsInt32())
        return PyInt_FromLong(value->Int32Value());

    if(value->IsNumber())
        return PyFloat_FromDouble(value->NumberValue());

    if(value->IsBoolean())
        return PyBool_FromLong(value->BooleanValue());

    if(value->IsNull())
        Py_RETURN_NONE;

    if(value->IsUndefined()) {
        return Py_INCREF(Undefined), Undefined;
    }

    if(value->IsString()) {
        v8::String::Utf8Value utf_string(value);
        return PyUnicode_FromString(*utf_string);
    }

    Object *object;

    v8::Handle<v8::Value> wrapper = value->ToObject()->GetHiddenValue(v8::String::New("hemi::wrapper"));

    if(!wrapper.IsEmpty()) {
        object = (Object *)v8::External::Unwrap(wrapper);

        Py_INCREF(object);

        return (PyObject *)object;
    }

    if (value->IsFunction()) {
        object = PyObject_New(Object, &FunctionType);
    } else {
        object = PyObject_New(Object, &ObjectType);
    }

    object->context = v8::Persistent<v8::Context>::New(context);
    object->parent = v8::Persistent<v8::Object>::New(parent);
    object->object = v8::Persistent<v8::Object>::New(value.As<v8::Object>());

    object->object->SetHiddenValue(v8::String::New("hemi::wrapper"), v8::External::Wrap(object));

    return (PyObject *)object;
}

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
inithemi(void)
{
    PyObject* m;

    ContextType.tp_new = PyType_GenericNew;

    if (PyType_Ready(&ContextType) < 0)
        return;

    if (PyType_Ready(&ObjectType) < 0)
        return;

    if (PyType_Ready(&FunctionType) < 0)
        return;

    if (PyType_Ready(&UndefinedType) < 0)
        return;

    Undefined = PyObject_New(PyObject, &UndefinedType);

    m = Py_InitModule3("hemi", module_methods,
                       "Lightweight V8 wrapper.");

    Py_INCREF(&ContextType);
    PyModule_AddObject(m, "Context", (PyObject *)&ContextType);
}
<|endoftext|>


<commit_before>#include <glob.h>
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <unordered_map>
#include <map>
#include <math.h>
using namespace std;

//#define CDEBUG 1

// util for debug
#ifdef CDEBUG
#define LOG(m,x,y,z) log_message(m,x,y,z)
#else
#define LOG(m,x,y,z)
#endif

void log_message(string m, double x, double y, double z) {
  cerr << m << "," << x << "," << y  << "," << z << "," << "\n";
}

// main
int main (int argc, char* argv[])
{
  // parameters
  if(argc != 3) {
    return 1;
  }
  const char* path = argv[1];
  int64_t max_size(atoll(argv[2]));

  ifstream infile;
  infile.open(path);

  long t, id, size;

  std::string line;

  unordered_map<long,long> cache;
  int64_t cache_size = 0;

  long reqs = 0, hits = 0;
  long long rbytes = 0, hbytes = 0;

  bool logStatistics=true; // start empty, no warmup

  uint64_t counter = 0;

  while (infile >> t >> id >> size)
    {
      if (logStatistics)
	{
	  reqs++;
	  rbytes += size;
	}
      if (cache.count(id) > 0)
	{
	  // hit: already in cache
	  if (logStatistics)
	    {
	      hits ++;
	      hbytes += size;
	    }
	  LOG("hit",id,size,cache_size);
	}
      else
	{
	  // miss: admit and follow Belady's rule for eviction
	  cache[id] = size;
	  cache_size += size;
	  LOG("miss",id,size,cache_size);
	  if (cache_size > max_size) {
	    // find next requests for all
	    map<long,long> futureReqs;
	    unordered_map<long,long> tobefound (cache); // copy cache map
	    // save current position
	    int len = infile.tellg();
	    long reqdist = 0;
	    while (!tobefound.empty())
	      {
		if (++reqdist > 100000)
		  {
		    for (auto it: tobefound)
		      {
			futureReqs[reqdist] = get<0>(it);
			// bug?:			futureReqs[reqdist++] = get<0>(it);
			//			LOG("forloop",reqdist-1,get<0>(it),get<1>(it));
		      }
		    break;
		  }

		// peak ahead and if found cached object: record how many reqdist
		infile >> t >> id >> size;
		unordered_map<long,long>::const_iterator got = tobefound.find (id);
		if ( got != tobefound.end() )
		  {
		    //		    LOG("found",id,tobefound[id],cache[id]);
		    futureReqs[reqdist] = id;
		    tobefound.erase(got);
		  }
	      }
	    // remove objects with requests furthest in future (highest reqdist) from cache
	    map<long,long>::const_iterator it = futureReqs.end();
	    unordered_map<int,int> classlist;
	    while (--it != futureReqs.begin())
	      {
		long eid = (it)->second;
		long esize = cache[eid];
		// evict up to two object from each size class
		if ( ++classlist[floor(log2(esize))] < 3)
		  {
		    LOG("evict",floor(log2(esize)),eid,esize);
		    cache_size -= esize;
		    cache.erase(eid);
		  }
		futureReqs.erase(it);
	      }
	    LOG("cachesize",max_size,cache_size,double(cache_size)/max_size);
	    // return to saved position
	    infile.seekg(len ,std::ios_base::beg);
	  }
	}
      if(counter++ > 10000) {
	cout << "OFMA " << max_size << " hitc " << hits << " reqc " << reqs << " OHR " << double(hits)/reqs << "\n";
	counter=0;
      }
    }
  infile.close();

  cout << "OFMA " << max_size << " hitc " << hits << " reqc " << reqs << " OHR " << double(hits)/reqs << "\n";

  return 0;
}
<commit_msg>ofma restructured<commit_after>#include <glob.h>
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <unordered_map>
#include <map>
#include <math.h>
using namespace std;

//#define CDEBUG 1

// util for debug
#ifdef CDEBUG
#define LOG(m,x,y,z) log_message(m,x,y,z)
#else
#define LOG(m,x,y,z)
#endif

void log_message(string m, double x, double y, double z) {
  cerr << m << "," << x << "," << y  << "," << z << "," << "\n";
}

// main
int main (int argc, char* argv[])
{
  // parameters
  if(argc != 3) {
    return 1;
  }
  const char* path = argv[1];
  int64_t max_size(atoll(argv[2]));

  ifstream infile;
  infile.open(path);

  long t, id, size;

  std::string line;

  unordered_map<long,long> cache;
  int64_t cache_size = 0;

  long reqs = 0, hits = 0;
  long long rbytes = 0, hbytes = 0;

  bool logStatistics=true; // start empty, no warmup

  uint64_t counter = 0;

  while (infile >> t >> id >> size)
    {
      if (logStatistics)
	{
	  reqs++;
	  rbytes += size;
	}
      if (cache.count(id) > 0)
	{
	  // hit: already in cache
	  if (logStatistics)
	    {
	      hits ++;
	      hbytes += size;
	    }
	  LOG("hit",id,size,cache_size);
	}
      else
	{
	  // miss: admit and follow Belady's rule for eviction
	  cache[id] = size;
	  cache_size += size;
	  LOG("miss",id,size,cache_size);
	  if (cache_size > max_size) {
	    // find next requests for all
	    map<long,long> futureReqs;
	    unordered_map<long,long> tobefound (cache); // copy cache map
	    // save current position
	    int len = infile.tellg();
	    long reqdist = 0;
	    while (!tobefound.empty())
	      {
		if (++reqdist > 100000)
		  {
		    for (auto it: tobefound)
		      {
			futureReqs[reqdist] = get<0>(it);
			// bug?:			futureReqs[reqdist++] = get<0>(it);
			//			LOG("forloop",reqdist-1,get<0>(it),get<1>(it));
		      }
		    break;
		  }

		// peak ahead and if found cached object: record how many reqdist
		infile >> t >> id >> size;
		unordered_map<long,long>::const_iterator got = tobefound.find (id);
		if ( got != tobefound.end() )
		  {
		    //		    LOG("found",id,tobefound[id],cache[id]);
		    futureReqs[reqdist] = id;
		    tobefound.erase(got);
		  }
	      }
	    // remove objects with requests furthest in future (highest reqdist) from cache
	    map<long,long>::const_iterator it = futureReqs.end();
	    unordered_map<int,int> classlist;
	    while (--it != futureReqs.begin())
	      {
		long eid = (it)->second;
		long esize = cache[eid];
		// evict up to two object from each size class
		if ( ++classlist[floor(log2(esize))] < 3)
		  {
		    LOG("evict",floor(log2(esize)),eid,esize);
		    cache_size -= esize;
		    cache.erase(eid);
		  }
		futureReqs.erase(it);
	      }
	    LOG("cachesize",max_size,cache_size,double(cache_size)/max_size);
	    // return to saved position
	    infile.seekg(len ,std::ios_base::beg);
	  }
	}
      if(counter++ > 1000) {
	cout << "OFMA " << max_size << " hitc " << hits << " reqc " << reqs << " OHR " << double(hits)/reqs << "\n";
	counter=0;
      }
    }
  infile.close();

  cout << "OFMA " << max_size << " hitc " << hits << " reqc " << reqs << " OHR " << double(hits)/reqs << "\n";

  return 0;
}
<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read Secretfile
    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    printf("before read secretfile \n");
    init_time_at(time,"# read Secret file",t);

    Secret=read_Secretfile(F.Secretfile,F);
    printf("# Read %d galaxies from %s \n",Secret.size(),F.Secretfile.c_str());
	print_time(time,"# ... took :");
    std::vector<int> count(10);
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    init_time_at(time,"# read target, SS, SF files",t);
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());
    F.Ngal=M.size();

    //establish priority classes
    init_time_at(time,"# establish priority clasess",t);
    assign_priority_class(M);
        std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
        count_class[M[i].priority_class]+=1;
        }
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }
	print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F);
    pp.compute_fibsofsp(F);

    //P is original list of plates
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf(" full number of plates %d\n",F.Nplate);
    printf("# Read %d plates from %s and %d fibers from %s\n",F.Nplate,F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,P,pp,F);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);
	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                inv_count++;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                //and otherwise the position of plate j in list of used plates
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);/*
    for (int j=0;j<F.Nplate;++j){
        printf(" j %d A.inv_order[j]  %d\n",j,A.inv_order[j]);
    }
    for (int jused=0;jused<F.NUsedplate;++jused){
        printf("jused %d  A.suborder[jused] %d\n",jused,A.suborder[jused]);
    }
    */
    if(F.diagnose)diagnostic(M,Secret,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A,0);
		redistribute_tf(M,P,pp,F,A,0);
	}
	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){

        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }
    if(F.diagnose)diagnostic(M,Secret,F,A);
    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals
    for(int i=0;i<F.pass_intervals.size();i++)printf(" i=%d interval %d \n",i,F.pass_intervals[i]);
    std::vector <int> update_intervals=F.pass_intervals;
    update_intervals.push_back(F.NUsedplate);//to end intervals at last plate
    for(int i=0;i<update_intervals.size()-1;++i){//go plate by used plate
        int starter=update_intervals[i];
        for (int jused=starter; jused<update_intervals[i+1]; jused++) {
            if (0<=jused-F.Analysis) update_plan_from_one_obs(jused,Secret,M,P,pp,F,A); else printf("\n no update\n");
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
        }
        redistribute_tf(M,P,pp,F,A,starter);
        improve(M,P,pp,F,A,starter);
        redistribute_tf(M,P,pp,F,A,starter);
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }
    // check on SS and SF

    List SS_hist=initList(10,0);
    List SF_hist=initList(40,0);
    for(int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        for (int p=0;p<F.Npetal;++p){
            int count_SS=0;
            int count_SF=0;
            for (int k=0;k<F.Nfbp;++k){
                int kk=pp.fibers_of_sp[p][k];
                int g=A.TF[j][kk];
                if(g!=-1 && M[g].SS)count_SS++;
                if(g!=-1 && M[g].SF)count_SF++;

            }
            SS_hist[count_SS]++;
            SF_hist[count_SF]++;
        }
    }
    printf(" SS distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SS_hist[i]);
    printf("\n %8d \n",SS_hist[10]);

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int jused=0; jused<F.NUsedplate; jused++){
        write_FAtile_ascii(A.suborder[jused],F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int jused=0; jused<F.NUsedplate; jused++){
        fa_write(A.suborder[jused],F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>move ++inv_count<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read Secretfile
    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    printf("before read secretfile \n");
    init_time_at(time,"# read Secret file",t);

    Secret=read_Secretfile(F.Secretfile,F);
    printf("# Read %d galaxies from %s \n",Secret.size(),F.Secretfile.c_str());
	print_time(time,"# ... took :");
    std::vector<int> count(10);
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    init_time_at(time,"# read target, SS, SF files",t);
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());
    F.Ngal=M.size();

    //establish priority classes
    init_time_at(time,"# establish priority clasess",t);
    assign_priority_class(M);
        std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
        count_class[M[i].priority_class]+=1;
        }
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }
	print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F);
    pp.compute_fibsofsp(F);

    //P is original list of plates
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf(" full number of plates %d\n",F.Nplate);
    printf("# Read %d plates from %s and %d fibers from %s\n",F.Nplate,F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,P,pp,F);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);
	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                inv_count++;

                //and otherwise the position of plate j in list of used plates
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);/*
    for (int j=0;j<F.Nplate;++j){
        printf(" j %d A.inv_order[j]  %d\n",j,A.inv_order[j]);
    }
    for (int jused=0;jused<F.NUsedplate;++jused){
        printf("jused %d  A.suborder[jused] %d\n",jused,A.suborder[jused]);
    }
    */
    if(F.diagnose)diagnostic(M,Secret,F,A);

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A,0);
		redistribute_tf(M,P,pp,F,A,0);
	}
	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){

        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }
    if(F.diagnose)diagnostic(M,Secret,F,A);
    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals
    for(int i=0;i<F.pass_intervals.size();i++)printf(" i=%d interval %d \n",i,F.pass_intervals[i]);
    std::vector <int> update_intervals=F.pass_intervals;
    update_intervals.push_back(F.NUsedplate);//to end intervals at last plate
    for(int i=0;i<update_intervals.size()-1;++i){//go plate by used plate
        int starter=update_intervals[i];
        for (int jused=starter; jused<update_intervals[i+1]; jused++) {
            if (0<=jused-F.Analysis) update_plan_from_one_obs(jused,Secret,M,P,pp,F,A); else printf("\n no update\n");
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
        }
        redistribute_tf(M,P,pp,F,A,starter);
        improve(M,P,pp,F,A,starter);
        redistribute_tf(M,P,pp,F,A,starter);
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }
    // check on SS and SF

    List SS_hist=initList(10,0);
    List SF_hist=initList(40,0);
    for(int jused=0;jused<F.NUsedplate;++jused){
        int j=A.suborder[jused];
        for (int p=0;p<F.Npetal;++p){
            int count_SS=0;
            int count_SF=0;
            for (int k=0;k<F.Nfbp;++k){
                int kk=pp.fibers_of_sp[p][k];
                int g=A.TF[j][kk];
                if(g!=-1 && M[g].SS)count_SS++;
                if(g!=-1 && M[g].SF)count_SF++;

            }
            SS_hist[count_SS]++;
            SF_hist[count_SF]++;
        }
    }
    printf(" SS distribution \n");
    for(int i=0;i<10;i++)printf("%8d",SS_hist[i]);
    printf("\n %8d \n",SS_hist[10]);

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int jused=0; jused<F.NUsedplate; jused++){
        write_FAtile_ascii(A.suborder[jused],F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int jused=0; jused<F.NUsedplate; jused++){
        fa_write(A.suborder[jused],F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>