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

Program:   vtkINRIA3D
Module:    $Id: vtkKWPreviewPage.cxx 572 2007-12-21 15:52:58Z ntoussaint $
Language:  C++
Author:    $Author: ntoussaint $
Date:      $Date: 2007-12-21 16:52:58 +0100 (Fri, 21 Dec 2007) $
Version:   $Revision: 572 $

Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved.
See Copyright.txt for details.

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

=========================================================================*/
#include "vtkKWPreviewPage.h"
#include "vtkObjectFactory.h"

#include <vtkImageView/vtkImageViewCollection.h>
#include <vtkImageView/vtkImageView2D.h>

#include "vtkKWApplication.h"
#include "vtkKWRenderWidget.h"
#include <vtkKWSeparator.h>
#include "vtkKWIcon.h"
#include "vtkKWFrameWithScrollbar.h"

#include <vtkImageView2D.h>
#include <vtkImageView3D.h>
#include <vtkLookupTableManager.h>
#include <vtkImageViewCornerAnnotation.h>

#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCollection.h>
#include <vtkImageData.h>
#include <vtkLookupTable.h>
#include <vtkRendererCollection.h>
#include <vtkActor.h>
#include <vtkKWWidgetSet.h>
#include <vtkKWTopLevel.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro( vtkKWPreviewPage );
vtkCxxRevisionMacro( vtkKWPreviewPage, "$Revision: 1 $");

//----------------------------------------------------------------------------
vtkKWPreviewPage::vtkKWPreviewPage()
{

  this->InternalFrame = vtkKWFrameWithScrollbar::New();

  this->ViewList = vtkImageViewCollection::New();
  this->ViewList->LinkZoomOff();
  this->ViewList->LinkPanOff();

  this->GlobalView = vtkImageView3D::New();
  this->GlobalView->SetShowAnnotations (false);
  this->GlobalView->ShowScalarBarOff();

  this->ViewList->AddItem (this->GlobalView);

  this->GlobalRenderWidget = vtkKWRenderWidget::New();
  this->GlobalRenderWidget->SetRenderState(0);

  this->RenderWidgetList = vtkCollection::New();

  vtkLookupTable* lut = vtkLookupTableManager::GetLookupTable (vtkLookupTableManager::LUT_BW);
  this->SetLookupTable (lut);
  lut->Delete();

  this->LinkViews = true;
  this->OrientationMode = 2;
  this->MaxNumberOfColumns = 5;
  this->InteractionMode = vtkInteractorStyleImageView2D::InteractionTypeSlice;
}

//----------------------------------------------------------------------------
vtkKWPreviewPage::~vtkKWPreviewPage()
{
  std::cout<<"deleting vtkKWPreviewPage "<<std::endl;

  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    widget->SetParent (NULL);
  }
  this->GlobalRenderWidget->SetParent (NULL);

  this->ViewList->RemoveAllItems();
  this->ViewList->Delete();
  this->RenderWidgetList->Delete();
  this->InternalFrame->Delete();
  this->GlobalView->Delete();
  this->GlobalRenderWidget->Delete();

}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::ConfigureView(vtkImageView* view, vtkKWRenderWidget* widget)
{
  view->SetupInteractor (widget->GetRenderWindow()->GetInteractor());
  vtkRenderer* renderer = vtkRenderer::New();
  view->SetRenderer(renderer);

  vtkRendererCollection* collection = widget->GetRenderWindow()->GetRenderers();
  collection->RemoveAllItems();
  widget->GetRenderWindow()->AddRenderer (renderer);
  widget->RemoveAllRenderers();
  widget->AddRenderer (renderer);
  view->SetRenderWindow (widget->GetRenderWindow());
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::AddPreviewImage (vtkImageData* image, const char* name, vtkMatrix4x4* matrix )
{
  vtkImageView2D* view = vtkImageView2D::New();
  vtkKWRenderWidget* widget = vtkKWRenderWidget::New();

  widget->SetParent (this->InternalFrame->GetFrame());
  widget->Create();
  //widget->SetWidth (800);
  //widget->SetHeight (800);
  widget->SetBorderWidth (1);
  widget->SetRenderState(0);

  this->ConfigureView (view, widget);

  view->SetInput (image);
  view->GetCornerAnnotation()->SetText (1, name);
  view->SetBackground (0,0,0);
  view->ShowAnnotationsOff ();
  view->ShowScalarBarOff();
  view->ShowRulerWidgetOff();

  if (matrix)
    view->SetOrientationMatrix (matrix);

  this->ViewList->AddItem (view);
  this->RenderWidgetList->AddItem (widget);

  this->GlobalView->AddExtraPlane (view->GetImageActor());

  view->Delete();
  widget->Delete();

  this->Update();
  this->Render();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::RemovePreviewImage (vtkImageData* image)
{

  int id = -1;

  this->FindView (image, id);

  if (id == -1)
    return;

  vtkImageView2D* view = vtkImageView2D::SafeDownCast (this->ViewList->GetItemAsObject (id));
  vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (id));
  this->GlobalView->RemoveExtraPlane (view->GetImageActor());
  this->ViewList->RemoveItem (view);
  widget->SetParent (NULL);
  this->RenderWidgetList->RemoveItem (widget);
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetEnableViews(unsigned int arg)
{
  this->GlobalRenderWidget->SetRenderState(arg);
  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    widget->SetRenderState(arg);
  }
}

//----------------------------------------------------------------------------
unsigned int vtkKWPreviewPage::GetEnableViews(void)
{
  return this->GlobalRenderWidget->GetRenderState();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::Render (void)
{

  if (!this->GetEnableViews())
    return;

  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    if (!widget->IsMapped())
      continue;
    vtkImageView* view = this->ViewList->GetItem (i+1);
    view->Render();
  }
  if (this->GlobalRenderWidget->IsMapped())
    this->GlobalRenderWidget->Render();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetOrientationMode (int mode)
{
//   this->Render();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetInteractionMode (int mode)
{
  // for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  // {
  //   vtkImageView2D* view = vtkImageView2D::SafeDownCast (this->ViewList->GetItemAsObject (i));
  //   view->SetInteractionStyle (mode);
  // }

  // this->InteractionMode = mode;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetLookupTable (vtkLookupTable* lut)
{
  this->ViewList->SyncSetLookupTable (lut);
  this->LookupTable = lut;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::Update (void)
{
  if (!this->IsCreated())
    return;

  this->PackSelf();
  this->Render();
}

//----------------------------------------------------------------------------
vtkImageView2D* vtkKWPreviewPage::FindView(vtkImageData* imagedata, int &cookie)
{
  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkImageView2D* view = vtkImageView2D::SafeDownCast(this->ViewList->GetItemAsObject(i));
    if (view)
    {
      if (view->GetInput() == imagedata)
      {
	cookie = i;
	return view;
      }
    }
  }

  return NULL;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::CreateWidget()
{
  // Check if already created

  if (this->IsCreated())
  {
    vtkErrorMacro("class already created");
    return;
  }

  // Call the superclass to create the whole widget
  this->Superclass::CreateWidget();

  this->InternalFrame->SetParent (this);
  this->InternalFrame->HorizontalScrollbarVisibilityOff();
  this->InternalFrame->VerticalScrollbarVisibilityOff();
  this->InternalFrame->Create();

  this->Script("pack %s -side top -expand t -fill both",
	       this->InternalFrame->GetWidgetName());

  this->GlobalRenderWidget->SetParent (this->InternalFrame->GetFrame());
  this->GlobalRenderWidget->Create();
  this->GlobalRenderWidget->SetBorderWidth (1);

  this->PackSelf();

  this->ConfigureView (this->GlobalView, this->GlobalRenderWidget);
  this->GlobalView->SetBackground (1,1,1);

  this->GlobalRenderWidget->SetBinding("<Expose>", this, "Render");
}

void vtkKWPreviewPage::PackSelf()
{
  if (!this->IsCreated())
  {
    //vtkErrorMacro("don't call this method before calling Create() : no effect !");
    return;
  }

  this->InternalFrame->GetFrame()->UnpackChildren();
  unsigned int N = this->GetNumberOfPreviews();
  this->InternalFrame->VerticalScrollbarVisibilityOff();
  this->InternalFrame->HorizontalScrollbarVisibilityOff();
  // if (N > 3)
  // {
  //   this->InternalFrame->VerticalScrollbarVisibilityOn();
  // }

  unsigned int NumberOfCols = 0;
  if (N == 0)
    NumberOfCols = 1;
  else
    NumberOfCols = 2;

  unsigned int iter_row = 0;
  unsigned int size = 350;
  vtkKWTopLevel* parent = this->GetParentTopLevel();

  if (parent)
  {
    size = (unsigned int)( (double)(parent->GetWidth() * 4.0)/(double)(4.0 * 5.0) );
  }

  for (unsigned int i=0; i<N; i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));

    this->Script ("grid %s -column %u -row %u -sticky news",
		  widget->GetWidgetName(), 0, iter_row);

    iter_row++;
  }
  unsigned NumberOfRows = iter_row;

  vtkKWRenderWidget* widget = this->GlobalRenderWidget;

  this->Script ("grid %s -column %u -row %u -rowspan %u -sticky news",
		widget->GetWidgetName(), 1, 0, iter_row+1);

  for (unsigned int i=0; i<NumberOfRows; i++)
  {
    this->Script ("grid rowconfigure %s %d -weight 1",
  		  this->InternalFrame->GetFrame()->GetWidgetName(), i);
  }

  this->Script ("grid columnconfigure %s 0 -weight 2",
  		  this->InternalFrame->GetFrame()->GetWidgetName());
  this->Script ("grid columnconfigure %s 1 -weight 5",
  		  this->InternalFrame->GetFrame()->GetWidgetName());

  this->Render();
}

<commit_msg>another attempt for flickering removed, high expectations now, 4<commit_after>/*=========================================================================

Program:   vtkINRIA3D
Module:    $Id: vtkKWPreviewPage.cxx 572 2007-12-21 15:52:58Z ntoussaint $
Language:  C++
Author:    $Author: ntoussaint $
Date:      $Date: 2007-12-21 16:52:58 +0100 (Fri, 21 Dec 2007) $
Version:   $Revision: 572 $

Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved.
See Copyright.txt for details.

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

=========================================================================*/
#include "vtkKWPreviewPage.h"
#include "vtkObjectFactory.h"

#include <vtkImageView/vtkImageViewCollection.h>
#include <vtkImageView/vtkImageView2D.h>

#include "vtkKWApplication.h"
#include "vtkKWRenderWidget.h"
#include <vtkKWSeparator.h>
#include "vtkKWIcon.h"
#include "vtkKWFrameWithScrollbar.h"

#include <vtkImageView2D.h>
#include <vtkImageView3D.h>
#include <vtkLookupTableManager.h>
#include <vtkImageViewCornerAnnotation.h>

#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCollection.h>
#include <vtkImageData.h>
#include <vtkLookupTable.h>
#include <vtkRendererCollection.h>
#include <vtkActor.h>
#include <vtkKWWidgetSet.h>
#include <vtkKWTopLevel.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro( vtkKWPreviewPage );
vtkCxxRevisionMacro( vtkKWPreviewPage, "$Revision: 1 $");

//----------------------------------------------------------------------------
vtkKWPreviewPage::vtkKWPreviewPage()
{

  this->InternalFrame = vtkKWFrameWithScrollbar::New();

  this->ViewList = vtkImageViewCollection::New();
  this->ViewList->LinkZoomOff();
  this->ViewList->LinkPanOff();

  this->GlobalView = vtkImageView3D::New();
  this->GlobalView->SetShowAnnotations (false);
  this->GlobalView->ShowScalarBarOff();

  this->ViewList->AddItem (this->GlobalView);

  this->GlobalRenderWidget = vtkKWRenderWidget::New();
  this->GlobalRenderWidget->SetRenderState(0);

  this->RenderWidgetList = vtkCollection::New();

  vtkLookupTable* lut = vtkLookupTableManager::GetLookupTable (vtkLookupTableManager::LUT_BW);
  this->SetLookupTable (lut);
  lut->Delete();

  this->LinkViews = true;
  this->OrientationMode = 2;
  this->MaxNumberOfColumns = 5;
  this->InteractionMode = vtkInteractorStyleImageView2D::InteractionTypeSlice;
}

//----------------------------------------------------------------------------
vtkKWPreviewPage::~vtkKWPreviewPage()
{
  std::cout<<"deleting vtkKWPreviewPage "<<std::endl;

  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    widget->SetParent (NULL);
  }
  this->GlobalRenderWidget->SetParent (NULL);

  this->ViewList->RemoveAllItems();
  this->ViewList->Delete();
  this->RenderWidgetList->Delete();
  this->InternalFrame->Delete();
  this->GlobalView->Delete();
  this->GlobalRenderWidget->Delete();

}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::ConfigureView(vtkImageView* view, vtkKWRenderWidget* widget)
{
  view->SetupInteractor (widget->GetRenderWindow()->GetInteractor());
  vtkRenderer* renderer = vtkRenderer::New();
  view->SetRenderer(renderer);

  vtkRendererCollection* collection = widget->GetRenderWindow()->GetRenderers();
  collection->RemoveAllItems();
  widget->GetRenderWindow()->AddRenderer (renderer);
  widget->RemoveAllRenderers();
  widget->AddRenderer (renderer);
  view->SetRenderWindow (widget->GetRenderWindow());
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::AddPreviewImage (vtkImageData* image, const char* name, vtkMatrix4x4* matrix )
{
  vtkImageView2D* view = vtkImageView2D::New();
  vtkKWRenderWidget* widget = vtkKWRenderWidget::New();

  widget->SetParent (this->InternalFrame->GetFrame());
  widget->Create();
  //widget->SetWidth (800);
  //widget->SetHeight (800);
  widget->SetBorderWidth (1);
  widget->SetRenderState(0);

  this->ConfigureView (view, widget);

  view->SetInput (image);
  view->GetCornerAnnotation()->SetText (1, name);
  view->SetBackground (0,0,0);
  view->ShowAnnotationsOff ();
  view->ShowScalarBarOff();
  view->ShowRulerWidgetOff();

  if (matrix)
    view->SetOrientationMatrix (matrix);

  this->ViewList->AddItem (view);
  this->RenderWidgetList->AddItem (widget);

  this->GlobalView->AddExtraPlane (view->GetImageActor());
  widget->SetBinding("<Expose>", this, "Render");

  view->Delete();
  widget->Delete();

  this->Update();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::RemovePreviewImage (vtkImageData* image)
{

  int id = -1;

  this->FindView (image, id);

  if (id == -1)
    return;

  vtkImageView2D* view = vtkImageView2D::SafeDownCast (this->ViewList->GetItemAsObject (id));
  vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (id));
  this->GlobalView->RemoveExtraPlane (view->GetImageActor());
  this->ViewList->RemoveItem (view);
  widget->SetParent (NULL);
  this->RenderWidgetList->RemoveItem (widget);
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetEnableViews(unsigned int arg)
{
  this->GlobalRenderWidget->SetRenderState(arg);
  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    widget->SetRenderState(arg);
  }
}

//----------------------------------------------------------------------------
unsigned int vtkKWPreviewPage::GetEnableViews(void)
{
  return this->GlobalRenderWidget->GetRenderState();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::Render (void)
{

  if (!this->GetEnableViews())
    return;

  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));
    if (!widget->IsMapped())
      continue;
    vtkImageView* view = this->ViewList->GetItem (i+1);
    view->Render();
  }
  if (this->GlobalRenderWidget->IsMapped())
    this->GlobalRenderWidget->Render();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetOrientationMode (int mode)
{
//   this->Render();
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetInteractionMode (int mode)
{
  // for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  // {
  //   vtkImageView2D* view = vtkImageView2D::SafeDownCast (this->ViewList->GetItemAsObject (i));
  //   view->SetInteractionStyle (mode);
  // }

  // this->InteractionMode = mode;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::SetLookupTable (vtkLookupTable* lut)
{
  this->ViewList->SyncSetLookupTable (lut);
  this->LookupTable = lut;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::Update (void)
{
  if (!this->IsCreated())
    return;

  this->PackSelf();
  this->Render();
}

//----------------------------------------------------------------------------
vtkImageView2D* vtkKWPreviewPage::FindView(vtkImageData* imagedata, int &cookie)
{
  for (unsigned int i=0; i<this->GetNumberOfPreviews(); i++)
  {
    vtkImageView2D* view = vtkImageView2D::SafeDownCast(this->ViewList->GetItemAsObject(i));
    if (view)
    {
      if (view->GetInput() == imagedata)
      {
	cookie = i;
	return view;
      }
    }
  }

  return NULL;
}

//----------------------------------------------------------------------------
void vtkKWPreviewPage::CreateWidget()
{
  // Check if already created

  if (this->IsCreated())
  {
    vtkErrorMacro("class already created");
    return;
  }

  // Call the superclass to create the whole widget
  this->Superclass::CreateWidget();

  this->InternalFrame->SetParent (this);
  this->InternalFrame->HorizontalScrollbarVisibilityOff();
  this->InternalFrame->VerticalScrollbarVisibilityOff();
  this->InternalFrame->Create();

  this->Script("pack %s -side top -expand t -fill both",
	       this->InternalFrame->GetWidgetName());

  this->GlobalRenderWidget->SetParent (this->InternalFrame->GetFrame());
  this->GlobalRenderWidget->Create();
  this->GlobalRenderWidget->SetBorderWidth (1);

  this->PackSelf();

  this->ConfigureView (this->GlobalView, this->GlobalRenderWidget);
  this->GlobalView->SetBackground (1,1,1);

  this->GlobalRenderWidget->SetBinding("<Expose>", this, "Render");
}

void vtkKWPreviewPage::PackSelf()
{
  if (!this->IsCreated())
  {
    //vtkErrorMacro("don't call this method before calling Create() : no effect !");
    return;
  }

  this->InternalFrame->GetFrame()->UnpackChildren();
  unsigned int N = this->GetNumberOfPreviews();
  this->InternalFrame->VerticalScrollbarVisibilityOff();
  this->InternalFrame->HorizontalScrollbarVisibilityOff();
  // if (N > 3)
  // {
  //   this->InternalFrame->VerticalScrollbarVisibilityOn();
  // }

  unsigned int NumberOfCols = 0;
  if (N == 0)
    NumberOfCols = 1;
  else
    NumberOfCols = 2;

  unsigned int iter_row = 0;
  unsigned int size = 350;
  vtkKWTopLevel* parent = this->GetParentTopLevel();

  if (parent)
  {
    size = (unsigned int)( (double)(parent->GetWidth() * 4.0)/(double)(4.0 * 5.0) );
  }

  for (unsigned int i=0; i<N; i++)
  {
    vtkKWRenderWidget* widget = vtkKWRenderWidget::SafeDownCast (this->RenderWidgetList->GetItemAsObject (i));

    this->Script ("grid %s -column %u -row %u -sticky news",
		  widget->GetWidgetName(), 0, iter_row);

    iter_row++;
  }
  unsigned NumberOfRows = iter_row;

  vtkKWRenderWidget* widget = this->GlobalRenderWidget;

  this->Script ("grid %s -column %u -row %u -rowspan %u -sticky news",
		widget->GetWidgetName(), 1, 0, iter_row+1);

  for (unsigned int i=0; i<NumberOfRows; i++)
  {
    this->Script ("grid rowconfigure %s %d -weight 1",
  		  this->InternalFrame->GetFrame()->GetWidgetName(), i);
  }

  this->Script ("grid columnconfigure %s 0 -weight 2",
  		  this->InternalFrame->GetFrame()->GetWidgetName());
  this->Script ("grid columnconfigure %s 1 -weight 5",
  		  this->InternalFrame->GetFrame()->GetWidgetName());

  this->Render();
}

<|endoftext|>


<commit_before>// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include <hspp/Cards/Cards.h>

#include <better-enums/enum.h>
#include <clara.hpp>

#ifdef HEARTHSTONEPP_WINDOWS
#include <filesystem>
#endif
#ifdef HEARTHSTONEPP_LINUX
#include <experimental/filesystem>
#endif
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace Hearthstonepp;

#ifndef HEARTHSTONEPP_MACOSX
namespace filesystem = std::experimental::filesystem;
#endif

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<GameTag> CheckAbilityImpl(const std::string& path)
{
    std::map<std::string, GameTag> abilityStrMap = {
        { "Adapt", GameTag::ADAPT },
        { "Charge", GameTag::CHARGE },
        { "DivineShield", GameTag::DIVINE_SHIELD },
        { "Freeze", GameTag::FREEZE },
        { "Poisonous", GameTag::POISONOUS },
        { "Stealth", GameTag::STEALTH },
        { "Taunt", GameTag::TAUNT },
        { "Windfury", GameTag::WINDFURY }
    };

    std::vector<GameTag> result;

#ifndef HEARTHSTONEPP_MACOSX
    const filesystem::path p(
        path + "/Tests/UnitTests/Tasks/BasicTasks/CombatTaskTests.cpp");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_regular_file(p))
    {
        std::cerr << p << " exists, but is not regular file\n";
        exit(EXIT_FAILURE);
    }

    std::ifstream abilityFile;
    abilityFile.open(p.string());

    if (!abilityFile.is_open())
    {
        std::cerr << p << " couldn't open\n";
        exit(EXIT_FAILURE);
    }

    std::string line;
    while (std::getline(abilityFile, line))
    {
        for (auto& ability : abilityStrMap)
        {
            std::string sentence = "TEST(CombatTask, " + ability.first + ")";
            if (line.find(sentence, 0) != std::string::npos)
            {
                result.emplace_back(ability.second);
                break;
            }
        }
    }

#else
    std::cerr
        << "CheckAbilityImpl skip: apple-clang doesn't support <filesystem>\n";
    exit(EXIT_FAILURE);
#endif

    return result;
}

inline std::vector<Card> QueryCardSetList(const std::string& projectPath,
                                          CardSet cardSet, bool implCardOnly)
{
    // Excludes this cards because it has power that doesn't appear in ability
    // EX1_508: Grimscale Oracle (CORE)
    // CS2_146: Southsea Deckhand (EXPERT1)
    // DS1_188: Gladiator's Longbow (EXPERT1)
    // EX1_105: Mountain Giant (EXPERT1)
    // EX1_335: Lightspawn (EXPERT1)
    // EX1_350: Prophet Velen (EXPERT1)
    // EX1_411: Gorehowl (EXPERT1)
    // EX1_560: Nozdormu (EXPERT1)
    // EX1_586: Sea Giant (EXPERT1)
    // NEW1_022: Dread Corsair (EXPERT1)
    std::vector<std::string> excludeCardList = {
        "EX1_508", "CS2_146", "DS1_188", "EX1_105", "EX1_335",
        "EX1_350", "EX1_411", "EX1_560", "EX1_586", "NEW1_022",
    };

    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    std::vector<GameTag> abilityList{};
    if (implCardOnly)
    {
        abilityList = CheckAbilityImpl(projectPath);
    }

    std::vector<Card> result;
    for (auto& card : Cards::GetInstance()->FindCardBySet(cardSet))
    {
        if (implCardOnly)
        {
            // Excludes cards that its power doesn't appear in ability
            if (std::find(excludeCardList.begin(), excludeCardList.end(),
                          card.id) != excludeCardList.end())
            {
                continue;
            }

            bool isAbilityImpl = true;
            for (auto& mechanic : card.mechanics)
            {
                if (std::find(abilityList.begin(), abilityList.end(),
                              mechanic) == abilityList.end())
                {
                    isAbilityImpl = false;
                    break;
                }
            }

            // Counts minion and weapon card only
            if (isAbilityImpl && (card.cardType == +CardType::MINION ||
                                  card.cardType == +CardType::WEAPON))
            {
                result.emplace_back(card);
            }
        }
        else
        {
            result.emplace_back(card);
        }
    }

    return result;
}

inline bool CheckCardImpl(const std::string& path, std::vector<Card>& cards,
                          const std::string& id)
{
#ifndef HEARTHSTONEPP_MACOSX
    auto iter = std::find_if(cards.begin(), cards.end(),
                             [&id](const Card& c) { return c.id == id; });
    if (iter != cards.end())
    {
        return true;
    }

    const filesystem::path p(path + "/Tests/UnitTests/CardSets");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_directory(p))
    {
        std::cerr << p << " exists, but is not directory\n";
        exit(EXIT_FAILURE);
    }

    for (auto&& file : filesystem::recursive_directory_iterator(p))
    {
        std::regex fileNamePattern(R"(.*\\(.*)\..*$)");
        std::smatch match;

        std::string pathStr = file.path().string();

        if (std::regex_match(pathStr, match, fileNamePattern))
        {
            if (match[1] == id)
            {
                return true;
            }
        }
    }
#else
    std::cerr
        << "CheckCardImpl skip: apple-clang doesn't support <filesystem>\n";
    exit(EXIT_FAILURE);
#endif

    return false;
}

inline void ExportFile(const std::string& projectPath, CardSet cardSet,
                       std::vector<Card>& cards)
{
    std::ofstream outputFile("result.md");
    if (outputFile)
    {
        auto cardsInCardSet = Cards::GetInstance()->FindCardBySet(cardSet);

        // Excludes cards that is not collectible
        cardsInCardSet.erase(
            std::remove_if(cardsInCardSet.begin(), cardsInCardSet.end(),
                           [](const Card& c) { return !c.isCollectible; }),
            cardsInCardSet.end());

        // Excludes 9 hero cards from CardSet::CORE
        if (cardSet == +CardSet::CORE)
        {
            cardsInCardSet.erase(
                std::remove_if(cardsInCardSet.begin(), cardsInCardSet.end(),
                               [](const Card& c) {
                                   return c.cardType == +CardType::HERO;
                               }),
                cardsInCardSet.end());
        }

        size_t impledCardNum = 0;
        const size_t allCardNum = cardsInCardSet.size();

        outputFile << "Set | ID | Name | Implemented\n";
        outputFile << ":---: | :---: | :---: | :---:\n";

        for (auto& card : cardsInCardSet)
        {
            std::string mechanicStr;
            for (auto& mechanic : card.mechanics)
            {
                mechanicStr += mechanic._to_string();
            }

            const bool isImplemented =
                CheckCardImpl(projectPath, cards, card.id);
            if (isImplemented)
            {
                impledCardNum++;
            }

            outputFile << card.cardSet._to_string() << " | " << card.id << " | "
                       << card.name << " | " << (isImplemented ? 'O' : ' ')
                       << '\n';
        }

        // Adds the number of card that implemented by ability
        const size_t implPercent = static_cast<size_t>(
            static_cast<double>(impledCardNum) / allCardNum * 100);
        outputFile << '\n';
        outputFile << "- Progress: " << implPercent << "% (" << impledCardNum
                   << " of " << allCardNum << " Cards)";

        std::cout << "Export file is completed.\n";
        exit(EXIT_SUCCESS);
    }

    std::cerr << "Failed to write file result.md\n";
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool isExportAllCard = false;
    bool implCardOnly = false;
    std::string cardSetName;
    std::string projectPath;

    // Parsing
    auto parser = clara::Help(showHelp) |
                  clara::Opt(isExportAllCard)["-a"]["--all"](
                      "Export a list of all expansion cards") |
                  clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
                      "Export a list of specific expansion cards") |
                  clara::Opt(implCardOnly)["-i"]["--implcardonly"](
                      "Export a list of cards that need to be implemented") |
                  clara::Opt(projectPath, "path")["-p"]["--path"](
                      "Specify Hearthstone++ project path");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    if (projectPath.empty())
    {
        std::cout << "You should input Hearthstone++ project path\n";
        exit(EXIT_FAILURE);
    }

    CardSet cardSet = CardSet::INVALID;

    if (isExportAllCard)
    {
        cardSet = CardSet::ALL;
    }
    else if (!cardSetName.empty())
    {
        const auto convertedCardSet =
            CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!convertedCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cardSet = *convertedCardSet;
    }

    std::vector<Card> cards =
        QueryCardSetList(projectPath, cardSet, implCardOnly);

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    ExportFile(projectPath, cardSet, cards);

    exit(EXIT_SUCCESS);
}<commit_msg>feat(improve-tool): Fix Codacy issues<commit_after>// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include <hspp/Cards/Cards.h>

#include <better-enums/enum.h>
#include <clara.hpp>

#ifdef HEARTHSTONEPP_WINDOWS
#include <filesystem>
#endif
#ifdef HEARTHSTONEPP_LINUX
#include <experimental/filesystem>
#endif
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace Hearthstonepp;

#ifndef HEARTHSTONEPP_MACOSX
namespace filesystem = std::experimental::filesystem;
#endif

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<GameTag> CheckAbilityImpl(const std::string& path)
{
    std::vector<GameTag> result;

#ifndef HEARTHSTONEPP_MACOSX
    std::map<std::string, GameTag> abilityStrMap = {
        { "Adapt", GameTag::ADAPT },
        { "Charge", GameTag::CHARGE },
        { "DivineShield", GameTag::DIVINE_SHIELD },
        { "Freeze", GameTag::FREEZE },
        { "Poisonous", GameTag::POISONOUS },
        { "Stealth", GameTag::STEALTH },
        { "Taunt", GameTag::TAUNT },
        { "Windfury", GameTag::WINDFURY }
    };

    const filesystem::path p(
        path + "/Tests/UnitTests/Tasks/BasicTasks/CombatTaskTests.cpp");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_regular_file(p))
    {
        std::cerr << p << " exists, but is not regular file\n";
        exit(EXIT_FAILURE);
    }

    std::ifstream abilityFile;
    abilityFile.open(p.string());

    if (!abilityFile.is_open())
    {
        std::cerr << p << " couldn't open\n";
        exit(EXIT_FAILURE);
    }

    std::string line;
    while (std::getline(abilityFile, line))
    {
        for (auto& ability : abilityStrMap)
        {
            std::string sentence = "TEST(CombatTask, " + ability.first + ")";
            if (line.find(sentence, 0) != std::string::npos)
            {
                result.emplace_back(ability.second);
                break;
            }
        }
    }

#else
    std::cerr
        << "CheckAbilityImpl skip: apple-clang doesn't support <filesystem>\n";
    exit(EXIT_FAILURE);
#endif

    return result;
}

inline std::vector<Card> QueryCardSetList(const std::string& projectPath,
                                          CardSet cardSet, bool implCardOnly)
{
    // Excludes this cards because it has power that doesn't appear in ability
    // EX1_508: Grimscale Oracle (CORE)
    // CS2_146: Southsea Deckhand (EXPERT1)
    // DS1_188: Gladiator's Longbow (EXPERT1)
    // EX1_105: Mountain Giant (EXPERT1)
    // EX1_335: Lightspawn (EXPERT1)
    // EX1_350: Prophet Velen (EXPERT1)
    // EX1_411: Gorehowl (EXPERT1)
    // EX1_560: Nozdormu (EXPERT1)
    // EX1_586: Sea Giant (EXPERT1)
    // NEW1_022: Dread Corsair (EXPERT1)
    std::vector<std::string> excludeCardList = {
        "EX1_508", "CS2_146", "DS1_188", "EX1_105", "EX1_335",
        "EX1_350", "EX1_411", "EX1_560", "EX1_586", "NEW1_022",
    };

    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    std::vector<GameTag> abilityList{};
    if (implCardOnly)
    {
        abilityList = CheckAbilityImpl(projectPath);
    }

    std::vector<Card> result;
    for (auto& card : Cards::GetInstance()->FindCardBySet(cardSet))
    {
        if (implCardOnly)
        {
            // Excludes cards that its power doesn't appear in ability
            if (std::find(excludeCardList.begin(), excludeCardList.end(),
                          card.id) != excludeCardList.end())
            {
                continue;
            }

            bool isAbilityImpl = true;
            for (auto& mechanic : card.mechanics)
            {
                if (std::find(abilityList.begin(), abilityList.end(),
                              mechanic) == abilityList.end())
                {
                    isAbilityImpl = false;
                    break;
                }
            }

            // Counts minion and weapon card only
            if (isAbilityImpl && (card.cardType == +CardType::MINION ||
                                  card.cardType == +CardType::WEAPON))
            {
                result.emplace_back(card);
            }
        }
        else
        {
            result.emplace_back(card);
        }
    }

    return result;
}

inline bool CheckCardImpl(const std::string& path, std::vector<Card>& cards,
                          const std::string& id)
{
#ifndef HEARTHSTONEPP_MACOSX
    auto iter = std::find_if(cards.begin(), cards.end(),
                             [&id](const Card& c) { return c.id == id; });
    if (iter != cards.end())
    {
        return true;
    }

    const filesystem::path p(path + "/Tests/UnitTests/CardSets");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_directory(p))
    {
        std::cerr << p << " exists, but is not directory\n";
        exit(EXIT_FAILURE);
    }

    for (auto&& file : filesystem::recursive_directory_iterator(p))
    {
        std::regex fileNamePattern(R"(.*\\(.*)\..*$)");
        std::smatch match;

        std::string pathStr = file.path().string();

        if (std::regex_match(pathStr, match, fileNamePattern))
        {
            if (match[1] == id)
            {
                return true;
            }
        }
    }
#else
    std::cerr
        << "CheckCardImpl skip: apple-clang doesn't support <filesystem>\n";
    exit(EXIT_FAILURE);
#endif

    return false;
}

inline void ExportFile(const std::string& projectPath, CardSet cardSet,
                       std::vector<Card>& cards)
{
    std::ofstream outputFile("result.md");
    if (outputFile)
    {
        auto cardsInCardSet = Cards::GetInstance()->FindCardBySet(cardSet);

        // Excludes cards that is not collectible
        cardsInCardSet.erase(
            std::remove_if(cardsInCardSet.begin(), cardsInCardSet.end(),
                           [](const Card& c) { return !c.isCollectible; }),
            cardsInCardSet.end());

        // Excludes 9 hero cards from CardSet::CORE
        if (cardSet == +CardSet::CORE)
        {
            cardsInCardSet.erase(
                std::remove_if(cardsInCardSet.begin(), cardsInCardSet.end(),
                               [](const Card& c) {
                                   return c.cardType == +CardType::HERO;
                               }),
                cardsInCardSet.end());
        }

        size_t impledCardNum = 0;
        const size_t allCardNum = cardsInCardSet.size();

        outputFile << "Set | ID | Name | Implemented\n";
        outputFile << ":---: | :---: | :---: | :---:\n";

        for (auto& card : cardsInCardSet)
        {
            std::string mechanicStr;
            for (auto& mechanic : card.mechanics)
            {
                mechanicStr += mechanic._to_string();
            }

            const bool isImplemented =
                CheckCardImpl(projectPath, cards, card.id);
            if (isImplemented)
            {
                impledCardNum++;
            }

            outputFile << card.cardSet._to_string() << " | " << card.id << " | "
                       << card.name << " | " << (isImplemented ? 'O' : ' ')
                       << '\n';
        }

        // Adds the number of card that implemented by ability
        const size_t implPercent = static_cast<size_t>(
            static_cast<double>(impledCardNum) / allCardNum * 100);
        outputFile << '\n';
        outputFile << "- Progress: " << implPercent << "% (" << impledCardNum
                   << " of " << allCardNum << " Cards)";

        std::cout << "Export file is completed.\n";
        exit(EXIT_SUCCESS);
    }

    std::cerr << "Failed to write file result.md\n";
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool isExportAllCard = false;
    bool implCardOnly = false;
    std::string cardSetName;
    std::string projectPath;

    // Parsing
    auto parser = clara::Help(showHelp) |
                  clara::Opt(isExportAllCard)["-a"]["--all"](
                      "Export a list of all expansion cards") |
                  clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
                      "Export a list of specific expansion cards") |
                  clara::Opt(implCardOnly)["-i"]["--implcardonly"](
                      "Export a list of cards that need to be implemented") |
                  clara::Opt(projectPath, "path")["-p"]["--path"](
                      "Specify Hearthstone++ project path");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    if (projectPath.empty())
    {
        std::cout << "You should input Hearthstone++ project path\n";
        exit(EXIT_FAILURE);
    }

    CardSet cardSet = CardSet::INVALID;

    if (isExportAllCard)
    {
        cardSet = CardSet::ALL;
    }
    else if (!cardSetName.empty())
    {
        const auto convertedCardSet =
            CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!convertedCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cardSet = *convertedCardSet;
    }

    std::vector<Card> cards =
        QueryCardSetList(projectPath, cardSet, implCardOnly);

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    ExportFile(projectPath, cardSet, cards);

    exit(EXIT_SUCCESS);
}<|endoftext|>


<commit_before>// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include <hspp/Cards/Cards.h>

#include <better-enums/enum.h>
#include <clara.hpp>

#ifdef HEARTHSTONEPP_WINDOWS
#include <filesystem>
#endif
#ifdef HEARTHSTONEPP_LINUX
#include <experimental/filesystem>
#endif
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace Hearthstonepp;

#ifndef HEARTHSTONEPP_MACOSX
namespace filesystem = std::experimental::filesystem;
#endif

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<Card> QueryCardSetList(CardSet cardSet, bool implCardOnly)
{
    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    return Cards::GetInstance()->FindCardBySet(cardSet);
}

inline bool CheckCardImpl(const std::string& path, const std::string& id)
{
#ifndef HEARTHSTONEPP_MACOSX
    const filesystem::path p(path + "/Tests/UnitTests/CardSets");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_directory(p))
    {
        std::cerr << p << " exists, but is not directory\n";
    }

    for (auto&& file : filesystem::recursive_directory_iterator(p))
    {
        std::regex fileNamePattern(R"(.*\\(.*)\..*$)");
        std::smatch match;

        std::string pathStr = file.path().string();

        if (std::regex_match(pathStr, match, fileNamePattern))
        {
            if (match[1] == id)
            {
                return true;
            }
        }
    }
#else
    std::cerr
        << "CheckCardImpl skip: apple-clang doesn't support <filesystem>\n";
#endif
    return false;
}

inline void ExportFile(const std::string& projectPath, std::vector<Card>& cards)
{
    std::ofstream outputFile("result.md");
    if (outputFile)
    {
        size_t collectibleCardNum = 0;
        size_t implementedCardNum = 0;

        outputFile << "Set | ID | Name | Tag | Implemented\n";
        outputFile << ":---: | :---: | :---: | :---: | :---:\n";

        for (auto& card : cards)
        {
            if (!card.isCollectible)
            {
                continue;
            }

            collectibleCardNum++;

            std::string mechanicStr;
            for (auto& mechanic : card.mechanics)
            {
                mechanicStr += mechanic._to_string();
            }

            const bool isImplemented = CheckCardImpl(projectPath, card.id);
            if (isImplemented)
            {
                implementedCardNum++;
            }

            outputFile << card.cardSet._to_string() << " | " << card.id << " | "
                       << card.name << " | " << mechanicStr << " | "
                       << (isImplemented ? 'O' : ' ') << '\n';
        }

        const size_t implPercent = static_cast<size_t>(
            static_cast<double>(implementedCardNum) / collectibleCardNum * 100);
        outputFile << '\n';
        outputFile << "- Progress: " << implPercent << "% ("
                   << implementedCardNum << " of " << collectibleCardNum
                   << " Cards)";

        std::cout << "Export file is completed.\n";
        exit(EXIT_SUCCESS);
    }

    std::cerr << "Failed to write file result.md\n";
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool isExportAllCard = false;
    bool implCardOnly = false;
    std::string cardSetName;
    std::string projectPath;

    // Parsing
    auto parser =
        clara::Help(showHelp) |
        clara::Opt(isExportAllCard)["-a"]["--all"](
            "Export a list of all expansion cards") |
        clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
            "Export a list of specific expansion cards") |
        clara::Opt(implCardOnly, "implCardOnly")["-i"]["--implcardonly"](
            "Export a list of cards that need to be implemented") |
        clara::Opt(projectPath, "path")["-p"]["--path"](
            "Specify Hearthstone++ project path");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    if (projectPath.empty())
    {
        std::cout << "You should input Hearthstone++ project path\n";
        exit(EXIT_FAILURE);
    }

    std::vector<Card> cards;

    if (isExportAllCard)
    {
        cards = QueryCardSetList(CardSet::ALL, implCardOnly);
    }
    else if (!cardSetName.empty())
    {
        const auto maybeCardSet =
            CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!maybeCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cards = QueryCardSetList(*maybeCardSet, implCardOnly);
    }

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    ExportFile(projectPath, cards);

    exit(EXIT_SUCCESS);
}<commit_msg>[ci skip] [WIP] feat(improve-tool): Add logic to check implemented card<commit_after>// Copyright (c) 2018 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include <hspp/Cards/Cards.h>

#include <better-enums/enum.h>
#include <clara.hpp>

#ifdef HEARTHSTONEPP_WINDOWS
#include <filesystem>
#endif
#ifdef HEARTHSTONEPP_LINUX
#include <experimental/filesystem>
#endif
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace Hearthstonepp;

#ifndef HEARTHSTONEPP_MACOSX
namespace filesystem = std::experimental::filesystem;
#endif

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<GameTag> CheckAbilityImpl()
{
    // TODO: Check ability tests in CombatTaskTests.cpp
}

inline std::vector<Card> QueryCardSetList(CardSet cardSet, bool implCardOnly)
{
    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    std::vector<GameTag> implementedAbilityList;
    if (implCardOnly)
    {
        implementedAbilityList = CheckAbilityImpl();
    }

    std::vector<Card> result;
    for (auto& card : Cards::GetInstance()->FindCardBySet(cardSet))
    {
        if (implCardOnly)
        {
            // TODO: Check abilities in card are all implemented
        }
        else
        {
            result.emplace_back(card);
        }
    }

    return result;
}

inline bool CheckCardImpl(const std::string& path, const std::string& id)
{
#ifndef HEARTHSTONEPP_MACOSX
    const filesystem::path p(path + "/Tests/UnitTests/CardSets");

    if (!filesystem::exists(p))
    {
        std::cerr << p << " does not exist\n";
        exit(EXIT_FAILURE);
    }

    if (!filesystem::is_directory(p))
    {
        std::cerr << p << " exists, but is not directory\n";
    }

    for (auto&& file : filesystem::recursive_directory_iterator(p))
    {
        std::regex fileNamePattern(R"(.*\\(.*)\..*$)");
        std::smatch match;

        std::string pathStr = file.path().string();

        if (std::regex_match(pathStr, match, fileNamePattern))
        {
            if (match[1] == id)
            {
                return true;
            }
        }
    }
#else
    std::cerr
        << "CheckCardImpl skip: apple-clang doesn't support <filesystem>\n";
#endif
    return false;
}

inline void ExportFile(const std::string& projectPath, std::vector<Card>& cards)
{
    std::ofstream outputFile("result.md");
    if (outputFile)
    {
        size_t collectibleCardNum = 0;
        size_t implementedCardNum = 0;

        outputFile << "Set | ID | Name | Tag | Implemented\n";
        outputFile << ":---: | :---: | :---: | :---: | :---:\n";

        for (auto& card : cards)
        {
            if (!card.isCollectible)
            {
                continue;
            }

            collectibleCardNum++;

            std::string mechanicStr;
            for (auto& mechanic : card.mechanics)
            {
                mechanicStr += mechanic._to_string();
            }

            const bool isImplemented = CheckCardImpl(projectPath, card.id);
            if (isImplemented)
            {
                implementedCardNum++;
            }

            outputFile << card.cardSet._to_string() << " | " << card.id << " | "
                       << card.name << " | " << mechanicStr << " | "
                       << (isImplemented ? 'O' : ' ') << '\n';
        }

        const size_t implPercent = static_cast<size_t>(
            static_cast<double>(implementedCardNum) / collectibleCardNum * 100);
        outputFile << '\n';
        outputFile << "- Progress: " << implPercent << "% ("
                   << implementedCardNum << " of " << collectibleCardNum
                   << " Cards)";

        std::cout << "Export file is completed.\n";
        exit(EXIT_SUCCESS);
    }

    std::cerr << "Failed to write file result.md\n";
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool isExportAllCard = false;
    bool implCardOnly = false;
    std::string cardSetName;
    std::string projectPath;

    // Parsing
    auto parser =
        clara::Help(showHelp) |
        clara::Opt(isExportAllCard)["-a"]["--all"](
            "Export a list of all expansion cards") |
        clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
            "Export a list of specific expansion cards") |
        clara::Opt(implCardOnly, "implCardOnly")["-i"]["--implcardonly"](
            "Export a list of cards that need to be implemented") |
        clara::Opt(projectPath, "path")["-p"]["--path"](
            "Specify Hearthstone++ project path");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    if (projectPath.empty())
    {
        std::cout << "You should input Hearthstone++ project path\n";
        exit(EXIT_FAILURE);
    }

    std::vector<Card> cards;

    if (isExportAllCard)
    {
        cards = QueryCardSetList(CardSet::ALL, implCardOnly);
    }
    else if (!cardSetName.empty())
    {
        const auto maybeCardSet =
            CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!maybeCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cards = QueryCardSetList(*maybeCardSet, implCardOnly);
    }

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    ExportFile(projectPath, cards);

    exit(EXIT_SUCCESS);
}<|endoftext|>


<commit_before>#include "FPSCounter.h"
#include "../Application.h"

namespace fse
{
	FPSCounter::FPSCounter(Scene* scene) : FPSCounter(scene, sf::Vector2f(0, 0))
	{
	}

	FPSCounter::FPSCounter(Scene* scene, const sf::Vector2f& spawnPos) : FSEObject(scene, spawnPos)
	{
		font_.loadFromFile("./data/fonts/bitstream-vera/VeraMoBd.ttf");

		fps_text_.setFont(font_);
		fps_text_.setFillColor(sf::Color::Green);
		fps_text_.setString(L"FPS: 0");
		fps_text_.setCharacterSize(16);

		sf::FloatRect rekt = fps_text_.getLocalBounds();
		background_.setSize(sf::Vector2f(rekt.width + 10, rekt.height + 10));
		background_.setPosition(rekt.left - 10, rekt.top - 10);
		background_.setFillColor(sf::Color(0, 0, 0, 128));

		setZOrder(257);

		counter_view_ = sf::View(sf::FloatRect(0.f, 0.f, getScene()->getApplication()->getWindow()->getSize().x, getScene()->getApplication()->getWindow()->getSize().y));
		on_resize_connection_ = getScene()->getApplication()->on_window_resized_.connect([this]()
		{
			counter_view_ = sf::View(sf::FloatRect(0.f, 0.f, getScene()->getApplication()->getWindow()->getSize().x, getScene()->getApplication()->getWindow()->getSize().y));
		});

	}

	FPSCounter::~FPSCounter()
	{
		getScene()->getApplication()->on_window_resized_.disconnect(on_resize_connection_);
	}

	void FPSCounter::update(float deltaTime)
	{
	}

	void FPSCounter::draw(sf::RenderTarget& target)
	{
		current_time_ = measureclock_.restart().asSeconds();
		fps_ = static_cast<int>((fps_ * smoothing_) + ((1 / current_time_) * (1.0 - smoothing_)));
		if (updclock_.getElapsedTime().asMilliseconds() > 250)
		{
			fps_text_.setString(std::wstring(L"FPS: " + std::to_wstring(static_cast<int>(fps_))));
			sf::FloatRect rekt = fps_text_.getLocalBounds();
			background_.setSize(sf::Vector2f(rekt.width + 10, rekt.height + 10));
			background_.setPosition(rekt.left - 5, rekt.top - 5);
			updclock_.restart();
		}

		sf::View origView = target.getView();
		target.setView(counter_view_);
		target.draw(background_);
		target.draw(fps_text_);
		target.setView(origView);

	}

	void FPSCounter::spawned()
	{
	}
}
<commit_msg>fix FPSCounter<commit_after>#include "FPSCounter.h"
#include "../Application.h"

namespace fse
{
	FPSCounter::FPSCounter(Scene* scene) : FPSCounter(scene, sf::Vector2f(0, 0))
	{
	}

	FPSCounter::FPSCounter(Scene* scene, const sf::Vector2f& spawnPos) : FSEObject(scene, spawnPos)
	{
		font_.loadFromFile("./data/fonts/bitstream-vera/VeraMoBd.ttf");

		fps_text_.setFont(font_);
		fps_text_.setFillColor(sf::Color::Green);
		fps_text_.setString(L"FPS: 0");
		fps_text_.setCharacterSize(16);

		sf::FloatRect rekt = fps_text_.getLocalBounds();
		background_.setSize(sf::Vector2f(rekt.width + 10, rekt.height + 10));
		background_.setPosition(rekt.left - 10, rekt.top - 10);
		background_.setFillColor(sf::Color(0, 0, 0, 128));

		setZOrder(257);

		counter_view_ = sf::View(sf::FloatRect(0.f, 0.f, getScene()->getApplication()->getWindow()->getSize().x, getScene()->getApplication()->getWindow()->getSize().y));
		on_resize_connection_ = getScene()->getApplication()->on_window_resized_.connect([this]()
		{
			counter_view_ = sf::View(sf::FloatRect(0.f, 0.f, getScene()->getApplication()->getWindow()->getSize().x, getScene()->getApplication()->getWindow()->getSize().y));
		});

	}

	FPSCounter::~FPSCounter()
	{
		getScene()->getApplication()->on_window_resized_.disconnect(on_resize_connection_);
	}

	void FPSCounter::update(float deltaTime)
	{
	}

	void FPSCounter::draw(sf::RenderTarget& target)
	{
		current_time_ = measureclock_.restart().asSeconds();
		fps_ = (fps_ * smoothing_) + ((1 / current_time_) * (1.0 - smoothing_));
		if (updclock_.getElapsedTime().asMilliseconds() > 250)
		{
			fps_text_.setString(std::wstring(L"FPS: " + std::to_wstring(static_cast<int>(fps_))));
			sf::FloatRect rekt = fps_text_.getLocalBounds();
			background_.setSize(sf::Vector2f(rekt.width + 10, rekt.height + 10));
			background_.setPosition(rekt.left - 5, rekt.top - 5);
			updclock_.restart();
		}

		sf::View origView = target.getView();
		target.setView(counter_view_);
		target.draw(background_);
		target.draw(fps_text_);
		target.setView(origView);

	}

	void FPSCounter::spawned()
	{
	}
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "TopologicalChangeManager.h"

#include <sofa/component/collision/TriangleModel.h>

#include <sofa/component/MechanicalObject.h>
#include <sofa/simulation/tree/GNode.h>

#include <sofa/core/componentmodel/topology/TopologicalMapping.h>

#include <sofa/component/topology/EdgeSetTopologyContainer.h>
#include <sofa/component/topology/TriangleSetTopologyContainer.h>
#include <sofa/component/topology/TriangleSetTopologyModifier.h>
#include <sofa/component/topology/TetrahedronSetTopologyContainer.h>
#include <sofa/component/topology/QuadSetTopologyContainer.h>
#include <sofa/component/topology/HexahedronSetTopologyContainer.h>

namespace sofa
{

namespace component
{

namespace collision
{

using namespace sofa::defaulttype;
using namespace sofa::component::topology;

TopologicalChangeManager::TopologicalChangeManager()
{
}

TopologicalChangeManager::~TopologicalChangeManager()
{
}

void TopologicalChangeManager::removeItemsFromTriangleModel(sofa::core::CollisionElementIterator elem2) const
{
    TriangleModel* my_triangle_model = (dynamic_cast<TriangleModel*>(elem2.getCollisionModel()));
    if (my_triangle_model)
    {
        sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
        topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology();

        unsigned int ind_curr = elem2.getIndex();

        simulation::tree::GNode *node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());

        std::set< unsigned int > items;
        items.insert(ind_curr);

        bool is_topoMap = true;

        while(is_topoMap)
        {

            is_topoMap = false;
            for(simulation::tree::GNode::ObjectIterator it = node_curr->object.begin(); it != node_curr->object.end(); ++it)
            {

                sofa::core::componentmodel::topology::TopologicalMapping *topoMap = dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it);
                if(topoMap != NULL)
                {

                    is_topoMap = true;
                    //unsigned int ind_glob = topoMap->getGlobIndex(ind_curr);
                    //ind_curr = topoMap->getFromIndex(ind_glob);
                    std::set< unsigned int > loc_items = items;
                    items.clear();
                    for (std::set< unsigned int >::const_iterator it=loc_items.begin(); it != loc_items.end(); ++it)
                    {
                        unsigned int ind_glob = topoMap->getGlobIndex(*it);
                        unsigned int ind = topoMap->getFromIndex(ind_glob);
                        //std::cout << *it << " -> "<<ind_glob << " -> "<<ind<<std::endl;
                        items.insert(ind);
                    }

                    topo_curr = topoMap->getFrom()->getContext()->getMeshTopology();
                    node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());

                    break;
                }
            }
        }
        sofa::helper::vector<unsigned int> vitems;
        vitems.reserve(items.size());
        vitems.insert(vitems.end(), items.rbegin(), items.rend());

        sofa::core::componentmodel::topology::TopologyModifier* topoMod;
        topo_curr->getContext()->get(topoMod);

        topoMod->removeItems(vitems);

        topoMod->notifyEndingEvent();

        topoMod->propagateTopologicalChanges();

        /*
        //// For APPLICATION 1 : renumber the mesh vertices with the optimal vertex permutation according to the Reverse CuthillMckee algorithm

        sofa::helper::vector<int> init_inverse_permutation;
        sofa::helper::vector<int>& inverse_permutation = init_inverse_permutation;

        sofa::component::topology::EdgeSetTopologyModifier* edgeMod;
        topo_curr->getContext()->get(edgeMod);

        edgeMod->resortCuthillMckee(inverse_permutation);

        //std::cout << "inverse_permutation : " << std::endl;
        sofa::helper::vector<int> permutation;
        permutation.resize(inverse_permutation.size());
        for (unsigned int i=0; i<inverse_permutation.size(); ++i){
        	permutation[inverse_permutation[i]]=i;
        	//std::cout << i << " -> " << inverse_permutation[i] << std::endl;
        }

        //std::cout << "permutation : " << std::endl;
        //for (unsigned int i=0; i<permutation.size(); ++i){
        	//std::cout << i << " -> " << permutation[i] << std::endl;
        //}

        sofa::core::componentmodel::topology::TopologyModifier* topoMod;
        topo_curr->getContext()->get(topoMod);
        topoMod->renumberPoints((const sofa::helper::vector<unsigned int> &) inverse_permutation, (const sofa::helper::vector<unsigned int> &) permutation);

        */
    }
}

// Handle Removing of topological element (from any type of topology)
void TopologicalChangeManager::removeItemsFromCollisionModel(sofa::core::CollisionElementIterator elem2) const
{
    if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
    {
        removeItemsFromTriangleModel(elem2);
    }
}

// Intermediate method to handle cutting
bool TopologicalChangeManager::incisionTriangleSetTopology(sofa::core::componentmodel::topology::BaseMeshTopology* _topology)
{
    const Vec<3,double>& a= (const Vec<3,double>) incision.a_init;
    const Vec<3,double>& b= (const Vec<3,double>) incision.b_init;

    const unsigned int &ind_ta = (const unsigned int) incision.ind_ta_init;
    const unsigned int &ind_tb = (const unsigned int) incision.ind_tb_init;

    unsigned int& a_last = incision.a_last_init;
    sofa::helper::vector< unsigned int >& a_p12_last = incision.a_p12_last_init;
    sofa::helper::vector< unsigned int >& a_i123_last = incision.a_i123_last_init;

    unsigned int& b_last = incision.b_last_init;
    sofa::helper::vector< unsigned int >& b_p12_last = incision.b_p12_last_init;
    sofa::helper::vector< unsigned int >& b_i123_last = incision.b_i123_last_init;

    bool is_prepared=!((a[0]==b[0] && a[1]==b[1] && a[2]==b[2]) || (incision.ind_ta_init == incision.ind_tb_init));

    if(is_prepared)
    {
        sofa::helper::vector< sofa::helper::vector<unsigned int> > new_points_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > closest_vertices_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > &new_points = new_points_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > &closest_vertices = closest_vertices_init;

        sofa::component::topology::TriangleSetTopologyModifier* triangleMod;
        _topology->getContext()->get(triangleMod);

        sofa::component::topology::TriangleSetTopologyAlgorithms<Vec3Types>* triangleAlg;
        _topology->getContext()->get(triangleAlg);

        bool is_fully_cut = triangleAlg->InciseAlongPointsList(incision.is_first_cut, a, b, ind_ta, ind_tb, a_last, a_p12_last, a_i123_last, b_last, b_p12_last, b_i123_last, new_points, closest_vertices);

        // notify the end for the current sequence of topological change events
        triangleMod->notifyEndingEvent();

        triangleMod->propagateTopologicalChanges();

        incision.is_first_cut = false;

        return is_fully_cut;
    }
    else
    {
        return false;
    }
}

// Handle Cutting (activated only for a triangular topology), using global variables to register the two last input points
bool TopologicalChangeManager::incisionCollisionModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
        const bool firstInput, const bool isCut)
{
    if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
    {
        return incisionTriangleModel(elem2, pos, firstInput, isCut);
    }

    return false;
}

bool TopologicalChangeManager::incisionTriangleModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
        const bool firstInput, const bool isCut)
{
    Triangle triangle(elem2);
    TriangleModel* model2 = triangle.getCollisionModel();

    // Test if a TopologicalMapping (by default from TetrahedronSetTopology to TriangleSetTopology) exists :

    bool is_TopologicalMapping = false;

    sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
    topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology();

    simulation::tree::GNode* parent2 = dynamic_cast<simulation::tree::GNode*>(model2->getContext());

    for (simulation::tree::GNode::ObjectIterator it = parent2->object.begin(); it != parent2->object.end(); ++it)
    {
        //std::cout << "INFO : name of GNode = " << (*it)->getName() <<  std::endl;

        if (dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it)!= NULL)
        {
            is_TopologicalMapping=true;
        }

    }

    // try to catch the topology associated to the detected object (a TriangleSetTopology is expected)

    sofa::component::topology::TriangleSetTopologyContainer* triangleCont;
    topo_curr->getContext()->get(triangleCont);

    if(!is_TopologicalMapping)
    {
        // no TopologicalMapping

        if (triangleCont) // TriangleSetTopologyContainer
        {
            if (firstInput)
            {
                incision.a_init[0] = pos[0];
                incision.a_init[1] = pos[1];
                incision.a_init[2] = pos[2];
                incision.ind_ta_init = elem2.getIndex();

                incision.is_first_cut = true;
            }
            else if (isCut)
            {
                incision.b_init[0] = pos[0];
                incision.b_init[1] = pos[1];
                incision.b_init[2] = pos[2];

                incision.ind_tb_init = elem2.getIndex();

                if(incisionTriangleSetTopology(topo_curr))
                {
                    // full cut
                    incision.a_init[0] = pos[0];
                    incision.a_init[1] = pos[1];
                    incision.a_init[2] = pos[2];
                    incision.ind_ta_init = elem2.getIndex();

                    sofa::helper::vector<unsigned int> components_init;
                    sofa::helper::vector<unsigned int>& components = components_init;

                    sofa::component::topology::EdgeSetTopologyContainer* edgeCont;
                    topo_curr->getContext()->get(edgeCont);

                    int num = edgeCont->getNumberConnectedComponents(components);
                    std::cout << "Number of connected components : " << num << endl;
                    //sofa::helper::vector<int>::size_type i;
                    //for (i = 0; i != components.size(); ++i)
                    //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
                }
                else
                {
                    sofa::helper::vector<unsigned int> components_init;
                    sofa::helper::vector<unsigned int>& components = components_init;

                    sofa::component::topology::EdgeSetTopologyContainer* edgeCont;
                    topo_curr->getContext()->get(edgeCont);

                    int num = edgeCont->getNumberConnectedComponents(components);
                    std::cout << "Number of connected components : " << num << endl;
                    //sofa::helper::vector<int>::size_type i;
                    //for (i = 0; i != components.size(); ++i)
                    //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
                    return true; // change state to ATTACHED;
                }
            }
        }
    }
    else
    {
        // there may be a TetrahedronSetTopology over the TriangleSetTopology

    }

    return false;
}

} // namespace collision

} // namespace component

} // namespace sofa
<commit_msg>r2946/sofa-dev : FIX : missing include of TriangleSetTopologyAlgorithms.h<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "TopologicalChangeManager.h"

#include <sofa/component/collision/TriangleModel.h>

#include <sofa/component/MechanicalObject.h>
#include <sofa/simulation/tree/GNode.h>

#include <sofa/core/componentmodel/topology/TopologicalMapping.h>

#include <sofa/component/topology/EdgeSetTopologyContainer.h>
#include <sofa/component/topology/TriangleSetTopologyContainer.h>
#include <sofa/component/topology/TriangleSetTopologyModifier.h>
#include <sofa/component/topology/TriangleSetTopologyAlgorithms.h>
#include <sofa/component/topology/TetrahedronSetTopologyContainer.h>
#include <sofa/component/topology/QuadSetTopologyContainer.h>
#include <sofa/component/topology/HexahedronSetTopologyContainer.h>

#include <sofa/defaulttype/VecTypes.h>

namespace sofa
{

namespace component
{

namespace collision
{

using namespace sofa::defaulttype;
using namespace sofa::component::topology;

TopologicalChangeManager::TopologicalChangeManager()
{
}

TopologicalChangeManager::~TopologicalChangeManager()
{
}

void TopologicalChangeManager::removeItemsFromTriangleModel(sofa::core::CollisionElementIterator elem2) const
{
    TriangleModel* my_triangle_model = (dynamic_cast<TriangleModel*>(elem2.getCollisionModel()));
    if (my_triangle_model)
    {
        sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
        topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology();

        unsigned int ind_curr = elem2.getIndex();

        simulation::tree::GNode *node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());

        std::set< unsigned int > items;
        items.insert(ind_curr);

        bool is_topoMap = true;

        while(is_topoMap)
        {

            is_topoMap = false;
            for(simulation::tree::GNode::ObjectIterator it = node_curr->object.begin(); it != node_curr->object.end(); ++it)
            {

                sofa::core::componentmodel::topology::TopologicalMapping *topoMap = dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it);
                if(topoMap != NULL)
                {

                    is_topoMap = true;
                    //unsigned int ind_glob = topoMap->getGlobIndex(ind_curr);
                    //ind_curr = topoMap->getFromIndex(ind_glob);
                    std::set< unsigned int > loc_items = items;
                    items.clear();
                    for (std::set< unsigned int >::const_iterator it=loc_items.begin(); it != loc_items.end(); ++it)
                    {
                        unsigned int ind_glob = topoMap->getGlobIndex(*it);
                        unsigned int ind = topoMap->getFromIndex(ind_glob);
                        //std::cout << *it << " -> "<<ind_glob << " -> "<<ind<<std::endl;
                        items.insert(ind);
                    }

                    topo_curr = topoMap->getFrom()->getContext()->getMeshTopology();
                    node_curr = dynamic_cast<simulation::tree::GNode*>(topo_curr->getContext());

                    break;
                }
            }
        }
        sofa::helper::vector<unsigned int> vitems;
        vitems.reserve(items.size());
        vitems.insert(vitems.end(), items.rbegin(), items.rend());

        sofa::core::componentmodel::topology::TopologyModifier* topoMod;
        topo_curr->getContext()->get(topoMod);

        topoMod->removeItems(vitems);

        topoMod->notifyEndingEvent();

        topoMod->propagateTopologicalChanges();

        /*
        //// For APPLICATION 1 : renumber the mesh vertices with the optimal vertex permutation according to the Reverse CuthillMckee algorithm

        sofa::helper::vector<int> init_inverse_permutation;
        sofa::helper::vector<int>& inverse_permutation = init_inverse_permutation;

        sofa::component::topology::EdgeSetTopologyModifier* edgeMod;
        topo_curr->getContext()->get(edgeMod);

        edgeMod->resortCuthillMckee(inverse_permutation);

        //std::cout << "inverse_permutation : " << std::endl;
        sofa::helper::vector<int> permutation;
        permutation.resize(inverse_permutation.size());
        for (unsigned int i=0; i<inverse_permutation.size(); ++i){
        	permutation[inverse_permutation[i]]=i;
        	//std::cout << i << " -> " << inverse_permutation[i] << std::endl;
        }

        //std::cout << "permutation : " << std::endl;
        //for (unsigned int i=0; i<permutation.size(); ++i){
        	//std::cout << i << " -> " << permutation[i] << std::endl;
        //}

        sofa::core::componentmodel::topology::TopologyModifier* topoMod;
        topo_curr->getContext()->get(topoMod);
        topoMod->renumberPoints((const sofa::helper::vector<unsigned int> &) inverse_permutation, (const sofa::helper::vector<unsigned int> &) permutation);

        */
    }
}

// Handle Removing of topological element (from any type of topology)
void TopologicalChangeManager::removeItemsFromCollisionModel(sofa::core::CollisionElementIterator elem2) const
{
    if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
    {
        removeItemsFromTriangleModel(elem2);
    }
}

// Intermediate method to handle cutting
bool TopologicalChangeManager::incisionTriangleSetTopology(sofa::core::componentmodel::topology::BaseMeshTopology* _topology)
{
    const Vec<3,double>& a= (const Vec<3,double>) incision.a_init;
    const Vec<3,double>& b= (const Vec<3,double>) incision.b_init;

    const unsigned int &ind_ta = (const unsigned int) incision.ind_ta_init;
    const unsigned int &ind_tb = (const unsigned int) incision.ind_tb_init;

    unsigned int& a_last = incision.a_last_init;
    sofa::helper::vector< unsigned int >& a_p12_last = incision.a_p12_last_init;
    sofa::helper::vector< unsigned int >& a_i123_last = incision.a_i123_last_init;

    unsigned int& b_last = incision.b_last_init;
    sofa::helper::vector< unsigned int >& b_p12_last = incision.b_p12_last_init;
    sofa::helper::vector< unsigned int >& b_i123_last = incision.b_i123_last_init;

    bool is_prepared=!((a[0]==b[0] && a[1]==b[1] && a[2]==b[2]) || (incision.ind_ta_init == incision.ind_tb_init));

    if(is_prepared)
    {
        sofa::helper::vector< sofa::helper::vector<unsigned int> > new_points_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > closest_vertices_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > &new_points = new_points_init;
        sofa::helper::vector< sofa::helper::vector<unsigned int> > &closest_vertices = closest_vertices_init;

        sofa::component::topology::TriangleSetTopologyModifier* triangleMod;
        _topology->getContext()->get(triangleMod);

        sofa::component::topology::TriangleSetTopologyAlgorithms<Vec3Types>* triangleAlg;
        _topology->getContext()->get(triangleAlg);

        bool is_fully_cut = triangleAlg->InciseAlongPointsList(incision.is_first_cut, a, b, ind_ta, ind_tb, a_last, a_p12_last, a_i123_last, b_last, b_p12_last, b_i123_last, new_points, closest_vertices);

        // notify the end for the current sequence of topological change events
        triangleMod->notifyEndingEvent();

        triangleMod->propagateTopologicalChanges();

        incision.is_first_cut = false;

        return is_fully_cut;
    }
    else
    {
        return false;
    }
}

// Handle Cutting (activated only for a triangular topology), using global variables to register the two last input points
bool TopologicalChangeManager::incisionCollisionModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
        const bool firstInput, const bool isCut)
{
    if(dynamic_cast<TriangleModel*>(elem2.getCollisionModel())!= NULL)
    {
        return incisionTriangleModel(elem2, pos, firstInput, isCut);
    }

    return false;
}

bool TopologicalChangeManager::incisionTriangleModel(sofa::core::CollisionElementIterator elem2, Vector3& pos,
        const bool firstInput, const bool isCut)
{
    Triangle triangle(elem2);
    TriangleModel* model2 = triangle.getCollisionModel();

    // Test if a TopologicalMapping (by default from TetrahedronSetTopology to TriangleSetTopology) exists :

    bool is_TopologicalMapping = false;

    sofa::core::componentmodel::topology::BaseMeshTopology* topo_curr;
    topo_curr = elem2.getCollisionModel()->getContext()->getMeshTopology();

    simulation::tree::GNode* parent2 = dynamic_cast<simulation::tree::GNode*>(model2->getContext());

    for (simulation::tree::GNode::ObjectIterator it = parent2->object.begin(); it != parent2->object.end(); ++it)
    {
        //std::cout << "INFO : name of GNode = " << (*it)->getName() <<  std::endl;

        if (dynamic_cast<sofa::core::componentmodel::topology::TopologicalMapping *>(*it)!= NULL)
        {
            is_TopologicalMapping=true;
        }

    }

    // try to catch the topology associated to the detected object (a TriangleSetTopology is expected)

    sofa::component::topology::TriangleSetTopologyContainer* triangleCont;
    topo_curr->getContext()->get(triangleCont);

    if(!is_TopologicalMapping)
    {
        // no TopologicalMapping

        if (triangleCont) // TriangleSetTopologyContainer
        {
            if (firstInput)
            {
                incision.a_init[0] = pos[0];
                incision.a_init[1] = pos[1];
                incision.a_init[2] = pos[2];
                incision.ind_ta_init = elem2.getIndex();

                incision.is_first_cut = true;
            }
            else if (isCut)
            {
                incision.b_init[0] = pos[0];
                incision.b_init[1] = pos[1];
                incision.b_init[2] = pos[2];

                incision.ind_tb_init = elem2.getIndex();

                if(incisionTriangleSetTopology(topo_curr))
                {
                    // full cut
                    incision.a_init[0] = pos[0];
                    incision.a_init[1] = pos[1];
                    incision.a_init[2] = pos[2];
                    incision.ind_ta_init = elem2.getIndex();

                    sofa::helper::vector<unsigned int> components_init;
                    sofa::helper::vector<unsigned int>& components = components_init;

                    sofa::component::topology::EdgeSetTopologyContainer* edgeCont;
                    topo_curr->getContext()->get(edgeCont);

                    int num = edgeCont->getNumberConnectedComponents(components);
                    std::cout << "Number of connected components : " << num << endl;
                    //sofa::helper::vector<int>::size_type i;
                    //for (i = 0; i != components.size(); ++i)
                    //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
                }
                else
                {
                    sofa::helper::vector<unsigned int> components_init;
                    sofa::helper::vector<unsigned int>& components = components_init;

                    sofa::component::topology::EdgeSetTopologyContainer* edgeCont;
                    topo_curr->getContext()->get(edgeCont);

                    int num = edgeCont->getNumberConnectedComponents(components);
                    std::cout << "Number of connected components : " << num << endl;
                    //sofa::helper::vector<int>::size_type i;
                    //for (i = 0; i != components.size(); ++i)
                    //  std::cout << "Vertex " << i <<" is in component " << components[i] << endl;
                    return true; // change state to ATTACHED;
                }
            }
        }
    }
    else
    {
        // there may be a TetrahedronSetTopology over the TriangleSetTopology

    }

    return false;
}

} // namespace collision

} // namespace component

} // namespace sofa
<|endoftext|>


<commit_before>#include "NoncentralChiSquared.h"

NoncentralChiSquared::NoncentralChiSquared(double degree, double noncentrality)
{
    setParameters(degree, noncentrality);
}

std::string NoncentralChiSquared::name()
{
    return "Noncentral Chi-Squared(" + toStringWithPrecision(getDegree()) + ", "
            + toStringWithPrecision(getNoncentrality()) + ")";
}

void NoncentralChiSquared::setParameters(double degree, double noncentrality)
{
    k = degree;
    if (k <= 0)
        k = 1;

    lambda = std::max(noncentrality, 0.0);
    sqrtLambda = std::sqrt(lambda);

    if (k > 1)
        X.setParameters(0.5 * (k - 1), 0.5);
    else {
        X.setParameters(0.5 * k, 0.5);
        Y.setRate(0.5 * lambda);
    }
}

double NoncentralChiSquared::f(double x) const
{
    if (x < 0)
        return 0.0;
    double halfkm1 = 0.5 * k - 1;
    double y = RandMath::modifiedBesselFirstKind(std::sqrt(lambda * x), halfkm1);
    y *= std::pow(x / lambda, 0.5 * halfkm1);
    return 0.5 * y * std::exp(-0.5 * (x + lambda));
}

double NoncentralChiSquared::F(double x) const
{
    if (x <= 0)
        return 0.0;
    if (k >= 2) {
        return RandMath::integral([this] (double t)
        {
            return f(t);
        }, 0, x);
    }

    // TODO: improve
    if (x <= MIN_POSITIVE)
        return 0;
    return RandMath::integral([this] (double t)
    {
        return f(t);
    }, MIN_POSITIVE, x);
}

double NoncentralChiSquared::variateForDegreeEqualOne() const
{
    double y = sqrtLambda + NormalRand::standardVariate();
    return y * y;
}

double NoncentralChiSquared::variate() const
{
    double y = (k == 1) ? X.variate() : 0.0;
    return variateForDegreeEqualOne() + y;
}

void NoncentralChiSquared::sample(std::vector<double> &outputData) const
{
    if (k != 1)
        X.sample(outputData);
    else
        std::fill(outputData.begin(), outputData.end(), 0.0);
    if (k >= 1)
    {
        for (double & var : outputData)
            var += variateForDegreeEqualOne();
    }
    else
    {
        for (double & var : outputData)
            var += GammaRand::variate(Y.variate(), 0.5);
    }
}

double NoncentralChiSquared::Mean() const
{
    return k + lambda;
}

double NoncentralChiSquared::Variance() const
{
    return 2 * (k + 2 * lambda);
}

std::complex<double> NoncentralChiSquared::CF(double t) const
{
    if (t == 0)
        return std::complex<double>(1, 0);
    std::complex<double> aux(1, -2 * t);
    std::complex<double> y(0, lambda * t);
    y = std::exp(y / aux);
    return y / std::pow(aux, 0.5 * k);
}

double NoncentralChiSquared::Skewness() const
{
    double y = k + 2 * lambda;
    y = std::pow(2 / y, 1.5);
    return y * (k + 3 * lambda);
}

double NoncentralChiSquared::ExcessKurtosis() const
{
    double y = k + 2 * lambda;
    return 12 * (k + 4 * lambda) / (y * y);
}
<commit_msg>Improved noncentral chi-squared cdf<commit_after>#include "NoncentralChiSquared.h"

NoncentralChiSquared::NoncentralChiSquared(double degree, double noncentrality)
{
    setParameters(degree, noncentrality);
}

std::string NoncentralChiSquared::name()
{
    return "Noncentral Chi-Squared(" + toStringWithPrecision(getDegree()) + ", "
            + toStringWithPrecision(getNoncentrality()) + ")";
}

void NoncentralChiSquared::setParameters(double degree, double noncentrality)
{
    k = degree;
    if (k <= 0)
        k = 1;

    lambda = std::max(noncentrality, 0.0);
    sqrtLambda = std::sqrt(lambda);

    if (k > 1)
        X.setParameters(0.5 * (k - 1), 0.5);
    else {
        X.setParameters(0.5 * k, 0.5);
        Y.setRate(0.5 * lambda);
    }
}

double NoncentralChiSquared::f(double x) const
{
    if (x < 0)
        return 0.0;
    double halfkm1 = 0.5 * k - 1;
    double y = RandMath::modifiedBesselFirstKind(std::sqrt(lambda * x), halfkm1);
    y *= std::pow(x / lambda, 0.5 * halfkm1);
    return 0.5 * y * std::exp(-0.5 * (x + lambda));
}

double NoncentralChiSquared::F(double x) const
{
    if (x <= 0)
        return 0.0;
    if (k >= 2) {
        return RandMath::integral([this] (double t)
        {
            return f(t);
        }, 0, x);
    }

    // TODO: find a min for bessel function
    static constexpr double minBound = 0.01;
    if (x < minBound) {
        return RandMath::integral([this] (double t)
        {
            return f(t);
        }, -MIN_POSITIVE, x);
    }

    // TODO: this value can be counted only once for fixed parameters
    double y1 = RandMath::integral([this] (double t)
    {
        return f(t);
    }, -MIN_POSITIVE, minBound);

    return y1 + RandMath::integral([this] (double t)
    {
        return f(t);
    }, minBound, x);
}

double NoncentralChiSquared::variateForDegreeEqualOne() const
{
    double y = sqrtLambda + NormalRand::standardVariate();
    return y * y;
}

double NoncentralChiSquared::variate() const
{
    double y = (k == 1) ? X.variate() : 0.0;
    return variateForDegreeEqualOne() + y;
}

void NoncentralChiSquared::sample(std::vector<double> &outputData) const
{
    if (k != 1)
        X.sample(outputData);
    else
        std::fill(outputData.begin(), outputData.end(), 0.0);
    if (k >= 1)
    {
        for (double & var : outputData)
            var += variateForDegreeEqualOne();
    }
    else
    {
        for (double & var : outputData)
            var += GammaRand::variate(Y.variate(), 0.5);
    }
}

double NoncentralChiSquared::Mean() const
{
    return k + lambda;
}

double NoncentralChiSquared::Variance() const
{
    return 2 * (k + 2 * lambda);
}

std::complex<double> NoncentralChiSquared::CF(double t) const
{
    if (t == 0)
        return std::complex<double>(1, 0);
    std::complex<double> aux(1, -2 * t);
    std::complex<double> y(0, lambda * t);
    y = std::exp(y / aux);
    return y / std::pow(aux, 0.5 * k);
}

double NoncentralChiSquared::Skewness() const
{
    double y = k + 2 * lambda;
    y = std::pow(2 / y, 1.5);
    return y * (k + 3 * lambda);
}

double NoncentralChiSquared::ExcessKurtosis() const
{
    double y = k + 2 * lambda;
    return 12 * (k + 4 * lambda) / (y * y);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmobilityglobal.h"
#include <qfeedbackactuator.h>
#include <qfeedbackeffect.h>

QTM_USE_NAMESPACE

void completeExample();

void completeExample()
{
    //TODO..
//! [Complete example]
    // Coming soon...
//! [COMPLETE example]
}
<commit_msg>Fix error in feedback doc sample snippet tag<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmobilityglobal.h"
#include <qfeedbackactuator.h>
#include <qfeedbackeffect.h>

QTM_USE_NAMESPACE

void completeExample();

void completeExample()
{
    //TODO..
//! [Complete example]
    // Coming soon...
//! [Complete example]
}
<|endoftext|>