<commit_before>#include "slicerconfigurationprivate.h"

namespace conveyor
{

    SlicerConfiguration *
    SlicerConfigurationPrivate::defaultConfiguration(SlicerConfiguration::Quality quality)
    {
        Json::Value null;
        SlicerConfiguration * const config(new SlicerConfiguration(null));

        switch(quality)
        {
        case SlicerConfiguration::LowQuality:
            config->setSlicer(SlicerConfiguration::MiracleGrue);
            config->setLayerHeight(.3);
            break;
        case SlicerConfiguration::MediumQuality:
            config->setSlicer(SlicerConfiguration::MiracleGrue);
            break;
        case SlicerConfiguration::HighQuality:
            config->setSlicer(SlicerConfiguration::Skeinforge);
            break;
        }
        return config;
    }

    SlicerConfigurationPrivate::SlicerConfigurationPrivate(Json::Value &) :
        m_slicer(SlicerConfiguration::MiracleGrue),
        m_extruder(SlicerConfiguration::Left),
        m_raft(true),
        m_supports(false),
        m_infill(0.90),
        m_layerHeight(0.2),
        m_shells(3),
        m_extruderTemperature(220),
        m_platformTemperature(220),
        m_printSpeed(80),
        m_travelSpeed(150)
    {
        // TODO
    }

    Json::Value SlicerConfigurationPrivate::toJSON() const
    {
        Json::Value root;

        // Slicer name and min/max versions
        root["slicer"] = slicerName().toStdString();

        // TODO: rewrite the software stack, using strings
        // instead of integers to represent toolheads
        root["extruder"] = 0;

        root["raft"] = m_raft;
        root["support"] = m_supports;

        root["infill"] = m_infill;
        root["layer_height"] = m_layerHeight;
        root["shells"] = m_shells;

        root["extruder_temperature"] = m_extruderTemperature;
        root["platform_temperature"] = m_platformTemperature;

        root["travel_speed"] = m_travelSpeed;
        root["print_speed"] = m_printSpeed;

        return root;
    }

    SlicerConfiguration::Slicer SlicerConfigurationPrivate::slicer() const
    {
        return m_slicer;
    }

    QString SlicerConfigurationPrivate::slicerName() const
    {
        switch (m_slicer) {
        case SlicerConfiguration::Skeinforge:
            return "Skeinforge";
        case SlicerConfiguration::MiracleGrue:
            return "MiracleGrue";
        default:
            return QString();
        }
    }

    SlicerConfiguration::Extruder SlicerConfigurationPrivate::extruder() const
    {
        return m_extruder;
    }

    QString SlicerConfigurationPrivate::extruderName() const
    {
        switch (m_extruder) {
        case SlicerConfiguration::Left:
            return "Left";
        case SlicerConfiguration::Right:
            return "Right";
        default:
            return QString();
        }
    }

    bool SlicerConfigurationPrivate::raft() const
    {
        return m_raft;
    }

    bool SlicerConfigurationPrivate::supports() const
    {
        return m_supports;
    }

    double SlicerConfigurationPrivate::infill() const
    {
        return m_infill;
    }

    double SlicerConfigurationPrivate::layerHeight() const
    {
        return m_layerHeight;
    }

    unsigned SlicerConfigurationPrivate::shells() const
    {
        return m_shells;
    }

    unsigned SlicerConfigurationPrivate::extruderTemperature() const
    {
        return m_extruderTemperature;
    }

    unsigned SlicerConfigurationPrivate::platformTemperature() const
    {
        return m_platformTemperature;
    }

    unsigned SlicerConfigurationPrivate::printSpeed() const
    {
        return m_printSpeed;
    }

    unsigned SlicerConfigurationPrivate::travelSpeed() const
    {
        return m_travelSpeed;
    }

    void SlicerConfigurationPrivate::setSlicer(SlicerConfiguration::Slicer slicer)
    {
        m_slicer = slicer;
    }

    void SlicerConfigurationPrivate::setExtruder(SlicerConfiguration::Extruder extruder)
    {
        m_extruder = extruder;
    }

    void SlicerConfigurationPrivate::setRaft(bool raft)
    {
        m_raft = raft;
    }

    void SlicerConfigurationPrivate::setSupports(bool supports)
    {
        m_supports = supports;
    }

    void SlicerConfigurationPrivate::setInfill(double infill)
    {
        m_infill = infill;
    }

    void SlicerConfigurationPrivate::setLayerHeight(double height)
    {
        m_layerHeight = height;
    }

    void SlicerConfigurationPrivate::setShells(unsigned shells)
    {
        m_shells = shells;
    }

    void SlicerConfigurationPrivate::setExtruderTemperature(unsigned temperature)
    {
        m_extruderTemperature = temperature;
    }

    void SlicerConfigurationPrivate::setPlatformTemperature(unsigned temperature)
    {
        m_platformTemperature = temperature;
    }

    void SlicerConfigurationPrivate::setPrintSpeed(unsigned speed)
    {
        m_printSpeed = speed;
    }

    void SlicerConfigurationPrivate::setTravelSpeed(unsigned speed)
    {
        m_travelSpeed = speed;
    }
}
<commit_msg>Fix slicer constants (again).<commit_after>#include "slicerconfigurationprivate.h"

namespace conveyor
{

    SlicerConfiguration *
    SlicerConfigurationPrivate::defaultConfiguration(SlicerConfiguration::Quality quality)
    {
        Json::Value null;
        SlicerConfiguration * const config(new SlicerConfiguration(null));

        switch(quality)
        {
        case SlicerConfiguration::LowQuality:
            config->setSlicer(SlicerConfiguration::MiracleGrue);
            config->setLayerHeight(.3);
            break;
        case SlicerConfiguration::MediumQuality:
            config->setSlicer(SlicerConfiguration::MiracleGrue);
            break;
        case SlicerConfiguration::HighQuality:
            config->setSlicer(SlicerConfiguration::Skeinforge);
            break;
        }
        return config;
    }

    SlicerConfigurationPrivate::SlicerConfigurationPrivate(Json::Value &) :
        m_slicer(SlicerConfiguration::MiracleGrue),
        m_extruder(SlicerConfiguration::Left),
        m_raft(true),
        m_supports(false),
        m_infill(0.90),
        m_layerHeight(0.2),
        m_shells(3),
        m_extruderTemperature(220),
        m_platformTemperature(220),
        m_printSpeed(80),
        m_travelSpeed(150)
    {
        // TODO
    }

    Json::Value SlicerConfigurationPrivate::toJSON() const
    {
        Json::Value root;

        // Slicer name and min/max versions
        root["slicer"] = slicerName().toStdString();

        // TODO: rewrite the software stack, using strings
        // instead of integers to represent toolheads
        root["extruder"] = 0;

        root["raft"] = m_raft;
        root["support"] = m_supports;

        root["infill"] = m_infill;
        root["layer_height"] = m_layerHeight;
        root["shells"] = m_shells;

        root["extruder_temperature"] = m_extruderTemperature;
        root["platform_temperature"] = m_platformTemperature;

        root["travel_speed"] = m_travelSpeed;
        root["print_speed"] = m_printSpeed;

        return root;
    }

    SlicerConfiguration::Slicer SlicerConfigurationPrivate::slicer() const
    {
        return m_slicer;
    }

    QString SlicerConfigurationPrivate::slicerName() const
    {
        switch (m_slicer) {
        case SlicerConfiguration::Skeinforge:
            return "SKEINFORGE";
        case SlicerConfiguration::MiracleGrue:
            return "MIRACLEGRUE";
        default:
            return QString();
        }
    }

    SlicerConfiguration::Extruder SlicerConfigurationPrivate::extruder() const
    {
        return m_extruder;
    }

    QString SlicerConfigurationPrivate::extruderName() const
    {
        switch (m_extruder) {
        case SlicerConfiguration::Left:
            return "Left";
        case SlicerConfiguration::Right:
            return "Right";
        default:
            return QString();
        }
    }

    bool SlicerConfigurationPrivate::raft() const
    {
        return m_raft;
    }

    bool SlicerConfigurationPrivate::supports() const
    {
        return m_supports;
    }

    double SlicerConfigurationPrivate::infill() const
    {
        return m_infill;
    }

    double SlicerConfigurationPrivate::layerHeight() const
    {
        return m_layerHeight;
    }

    unsigned SlicerConfigurationPrivate::shells() const
    {
        return m_shells;
    }

    unsigned SlicerConfigurationPrivate::extruderTemperature() const
    {
        return m_extruderTemperature;
    }

    unsigned SlicerConfigurationPrivate::platformTemperature() const
    {
        return m_platformTemperature;
    }

    unsigned SlicerConfigurationPrivate::printSpeed() const
    {
        return m_printSpeed;
    }

    unsigned SlicerConfigurationPrivate::travelSpeed() const
    {
        return m_travelSpeed;
    }

    void SlicerConfigurationPrivate::setSlicer(SlicerConfiguration::Slicer slicer)
    {
        m_slicer = slicer;
    }

    void SlicerConfigurationPrivate::setExtruder(SlicerConfiguration::Extruder extruder)
    {
        m_extruder = extruder;
    }

    void SlicerConfigurationPrivate::setRaft(bool raft)
    {
        m_raft = raft;
    }

    void SlicerConfigurationPrivate::setSupports(bool supports)
    {
        m_supports = supports;
    }

    void SlicerConfigurationPrivate::setInfill(double infill)
    {
        m_infill = infill;
    }

    void SlicerConfigurationPrivate::setLayerHeight(double height)
    {
        m_layerHeight = height;
    }

    void SlicerConfigurationPrivate::setShells(unsigned shells)
    {
        m_shells = shells;
    }

    void SlicerConfigurationPrivate::setExtruderTemperature(unsigned temperature)
    {
        m_extruderTemperature = temperature;
    }

    void SlicerConfigurationPrivate::setPlatformTemperature(unsigned temperature)
    {
        m_platformTemperature = temperature;
    }

    void SlicerConfigurationPrivate::setPrintSpeed(unsigned speed)
    {
        m_printSpeed = speed;
    }

    void SlicerConfigurationPrivate::setTravelSpeed(unsigned speed)
    {
        m_travelSpeed = speed;
    }
}
<|endoftext|>


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

#ifndef CAMERA_H
#define CAMERA_H

#include <vector>
#include <Ogre.h>
#include "stdafx.h"
#include "AbstractCameraListener.hpp"
#include "HelperLogics.hpp"
#include "Node.hpp"
#include "AbstractMovable.hpp"

namespace yz {

/**
*@author Grégory Van den Borre
*/
class Camera : public AbstractMovable {

public:

    Camera(Ogre::Camera* cam, Ogre::RaySceneQuery* query, Ogre::PlaneBoundedVolumeListSceneQuery* planeQuery);

    Ogre::Vector3 getPoint(const Ogre::Vector3& pos, const Ogre::Real x, const Ogre::Real y);

    Ogre::Ray getRay(const Ogre::Real x, const Ogre::Real y);

    void attachGround(yz::Node* node) {
        node->attachObject(this.planeQuery);
    }

    inline void setAspectRatio(const Ogre::Real ratio) {
        LOG_FUNCTION
        this->camera->setAspectRatio(ratio);

    }

    inline void setNearClipDistance(const Ogre::Real dist) {
        LOG_FUNCTION
        this->camera->setNearClipDistance(dist);
    }

    inline void setFarClipDistance(const Ogre::Real dist) {
        LOG_FUNCTION
        this->camera->setFarClipDistance(dist);
    }

    inline void addListener(yz::AbstractCameraListener* l) {
        LOG_FUNCTION
        this->listenerList.push_back(l);
    }

    inline void enableRenderingDistance() {
        LOG_FUNCTION
        this->camera->setUseRenderingDistance(true);
    }

    /**
     * Remove a listener from the list and call its destructor.
     * @param l Listener to remove.
     */
    inline void removeListener(yz::AbstractCameraListener* l) {
        LOG_FUNCTION
        this->listenerList.erase(std::remove(this->listenerList.begin(), this->listenerList.end(), l));
        delete l;
    }

    std::string getName() const {
        LOG_FUNCTION
        return this->camera->getName();
    }

    inline bool isVisible(const Ogre::Real x, const Ogre::Real y, const Ogre::Real z) {
        LOG_FUNCTION
        return this->camera->isVisible(Ogre::Vector3(x, y, z));
    }

    inline void forceListenersUpdate() {
        LOG_FUNCTION
        this->updateListeners();
    }

    void updateListeners();

    inline Ogre::Camera* getCamera() const{
        LOG_FUNCTION
        return this->camera;
    }

    inline void detachFromParent() {
        LOG_FUNCTION
        this->camera->detachFromParent();
    }

    Ogre::MovableObject* getMovableObject() {
        LOG_FUNCTION
        return this->camera;
    }

    yz::Id* throwRay(const Ogre::Real x, const Ogre::Real y, const bool poly);

    Ogre::Vector3 throwRayPos(const Ogre::Real x, const Ogre::Real y);

    std::vector<yz::Id*> throwPlaneRay(Ogre::Real x1, Ogre::Real x2, Ogre::Real y1, Ogre::Real y2);

    inline static yz::Camera* get(const POINTER pointer) {
        LOG_FUNCTION
        return reinterpret_cast<yz::Camera*>(pointer);
    }

private:

    static yz::Id* ID_WORLD;

    std::vector<yz::AbstractCameraListener*> listenerList;

    Ogre::Camera* camera;

    Ogre::RaySceneQuery* query;

    Ogre::PlaneBoundedVolumeListSceneQuery* planeQuery;

};

}

#endif
<commit_msg>[YE-0] Fix for camera.<commit_after>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2018 Grégory Van den Borre
 *
 * More infos available: https://www.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

#ifndef CAMERA_H
#define CAMERA_H

#include <vector>
#include <Ogre.h>
#include "stdafx.h"
#include "AbstractCameraListener.hpp"
#include "HelperLogics.hpp"
#include "Node.hpp"
#include "AbstractMovable.hpp"

namespace yz {

/**
*@author Grégory Van den Borre
*/
class Camera : public AbstractMovable {

public:

    Camera(Ogre::Camera* cam, Ogre::RaySceneQuery* query, Ogre::PlaneBoundedVolumeListSceneQuery* planeQuery);

    Ogre::Vector3 getPoint(const Ogre::Vector3& pos, const Ogre::Real x, const Ogre::Real y);

    Ogre::Ray getRay(const Ogre::Real x, const Ogre::Real y);

    void attachGround(yz::Node* node) {
        node->attachObject(this->planeQuery);
    }

    inline void setAspectRatio(const Ogre::Real ratio) {
        LOG_FUNCTION
        this->camera->setAspectRatio(ratio);

    }

    inline void setNearClipDistance(const Ogre::Real dist) {
        LOG_FUNCTION
        this->camera->setNearClipDistance(dist);
    }

    inline void setFarClipDistance(const Ogre::Real dist) {
        LOG_FUNCTION
        this->camera->setFarClipDistance(dist);
    }

    inline void addListener(yz::AbstractCameraListener* l) {
        LOG_FUNCTION
        this->listenerList.push_back(l);
    }

    inline void enableRenderingDistance() {
        LOG_FUNCTION
        this->camera->setUseRenderingDistance(true);
    }

    /**
     * Remove a listener from the list and call its destructor.
     * @param l Listener to remove.
     */
    inline void removeListener(yz::AbstractCameraListener* l) {
        LOG_FUNCTION
        this->listenerList.erase(std::remove(this->listenerList.begin(), this->listenerList.end(), l));
        delete l;
    }

    std::string getName() const {
        LOG_FUNCTION
        return this->camera->getName();
    }

    inline bool isVisible(const Ogre::Real x, const Ogre::Real y, const Ogre::Real z) {
        LOG_FUNCTION
        return this->camera->isVisible(Ogre::Vector3(x, y, z));
    }

    inline void forceListenersUpdate() {
        LOG_FUNCTION
        this->updateListeners();
    }

    void updateListeners();

    inline Ogre::Camera* getCamera() const{
        LOG_FUNCTION
        return this->camera;
    }

    inline void detachFromParent() {
        LOG_FUNCTION
        this->camera->detachFromParent();
    }

    Ogre::MovableObject* getMovableObject() {
        LOG_FUNCTION
        return this->camera;
    }

    yz::Id* throwRay(const Ogre::Real x, const Ogre::Real y, const bool poly);

    Ogre::Vector3 throwRayPos(const Ogre::Real x, const Ogre::Real y);

    std::vector<yz::Id*> throwPlaneRay(Ogre::Real x1, Ogre::Real x2, Ogre::Real y1, Ogre::Real y2);

    inline static yz::Camera* get(const POINTER pointer) {
        LOG_FUNCTION
        return reinterpret_cast<yz::Camera*>(pointer);
    }

private:

    static yz::Id* ID_WORLD;

    std::vector<yz::AbstractCameraListener*> listenerList;

    Ogre::Camera* camera;

    Ogre::RaySceneQuery* query;

    Ogre::PlaneBoundedVolumeListSceneQuery* planeQuery;

};

}

#endif
<|endoftext|>


<commit_before>#include "../src/alm.h"
#include "alm_wrapper.h"
#include <cstdlib>
#include <string>
#include <iostream>

extern "C" {

    #define MAX_NUM_ALM 10

    static const std::string atom_name[] = {
        "X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
        "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K",
        "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu",
        "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",
        "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
        "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr",
        "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm",
        "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au",
        "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac",
        "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es",
        "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
        "Ds", "Rg", "Cn", "Uut", "Uuq", "Uup", "Uuh", "Uus", "Uuo"};

    static ALM_NS::ALM *alm[MAX_NUM_ALM];
    static int is_alm_used[MAX_NUM_ALM];
    static int is_alm_init = 0;

    void alm_init(void)
    {
        int id;
        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (alm[id]) {
                delete alm[id];
            }
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
        is_alm_init = 1;
    }

    int alm_new(void)
    {
        int id;

        if (!is_alm_init) {
            alm_init();
        }

        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (!is_alm_used[id]) {
                alm[id] = new ALM_NS::ALM();
                is_alm_used[id] = 1;
                break;
            }
        }

        if (id == MAX_NUM_ALM) {
            return -1;
        } else {
            return id;
        }
    }

    void alm_delete(const int id)
    {
        if (alm[id]) {
            delete alm[id];
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
    }

    // void set_output_filename_prefix(const std::string prefix);
    // void set_is_print_symmetry(const int is_printsymmetry);
    // void set_is_print_hessians(const bool print_hessian);
    // void set_symmetry_param(const int nsym);
    // void set_symmetry_tolerance(const double tolerance);
    // void set_displacement_param(const bool trim_dispsign_for_evenfunc);
    // void set_displacement_basis(const std::string str_disp_basis);
    // void set_periodicity(const int is_periodic[3]);

    void alm_set_cell(const int id,
                      const int nat,
                      const double lavec[3][3],
                      const double xcoord[][3],
                      const int kd[])
    {
        int i, j, nkd;
        int nkd_vals[nat], kd_new[nat];
        bool kd_exist;

        nkd_vals[0] = kd[0];
        kd_new[0] = 1;
        nkd = 1;
        for (i = 1; i < nat; ++i) {
            kd_exist = false;
            for (j = 0; j < nkd; ++j) {
                if (nkd_vals[j] == kd[i]) {
                    kd_exist = true;
                    kd_new[i] = j + 1;
                    break;
                }
            }
            if (!kd_exist) {
                nkd_vals[nkd] = kd[i];
                kd_new[i] = nkd + 1;
                ++nkd;
            }
        }
        std::string kdname[nkd];
        for (int i = 0; i < nkd; i++) {
            kdname[i] = atom_name[abs(nkd_vals[i]) % 118];
        }

        alm[id]->set_cell(nat, lavec, xcoord, kd_new, kdname);
    }

    // void set_magnetic_params(const double* magmom,
    //   		       const bool lspin,
    //   		       const int noncollinear,
    //   		       const int trev_sym_mag,
    //   		       const std::string str_magmom);

    void alm_set_displacement_and_force(const int id,
                                        const double* u_in,
                                        const double* f_in,
                                        const int nat,
                                        const int ndata_used)
    {
        alm[id]->set_displacement_and_force(u_in, f_in, nat, ndata_used);
    }

    void alm_set_fitting_constraint_type(const int id,
                                         const int constraint_flag) // ICONST
    {
        alm[id]->set_fitting_constraint_type(constraint_flag);
    }

    // void set_fitting_constraint_rotation_axis(const std::string rotation_axis) // ROTAXIS
    // void set_multiplier_option(const int multiply_data);
    // void set_fitting_filenames(const std::string dfile,
    //   			 const std::string ffile);
    void alm_set_norder(const int id,
                        const int maxorder)
    {
        alm[id]->set_norder(maxorder);
    }

    void alm_set_nbody_include(const int id,
                               const int *nbody_include)
    {
        alm[id]->set_nbody_include(nbody_include);
    }

    void alm_set_cutoff_radii(const int id,
                              const double * rcs)
    {
        alm[id]->set_cutoff_radii(rcs);
    }

    int alm_get_atom_mapping_by_pure_translations(const int id,
                                                  int *map_p2s)
    {
        return alm[id]->get_atom_mapping_by_pure_translations(map_p2s);
    }

    int alm_get_number_of_displacement_patterns(const int id,
                                                const int fc_order) // harmonic=1,
    {
        return alm[id]->get_number_of_displacement_patterns(fc_order);
    }

    void alm_get_numbers_of_displacements(const int id,
                                          int *numbers,
                                          const int fc_order) // harmonic=1,
    {
        alm[id]->get_numbers_of_displacements(numbers, fc_order);
    }

    int alm_get_displacement_patterns(const int id,
                                      int *atom_indices,
                                      double *disp_patterns,
                                      const int fc_order) // harmonic=1,
    {
        return alm[id]->get_displacement_patterns(atom_indices,
                                              disp_patterns,
                                              fc_order);
    }

    int alm_get_number_of_fc_elements(const int id,
                                      const int fc_order)  // harmonic=1, ...
    {
        return alm[id]->get_number_of_fc_elements(fc_order);
    }

    void alm_get_fc(const int id,
                    double *fc_values,
                    int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                    const int fc_order)
    {
        alm[id]->get_fc(fc_values, elem_indices, fc_order);
    }

    void alm_run_suggest(const int id)
    {
        alm[id]->set_run_mode("suggest");
        alm[id]->run();
    }

    void alm_run_fitting(const int id)
    {
        alm[id]->set_run_mode("fitting");
        alm[id]->run();
    }
}
<commit_msg>Avoid Non-POD std::string type<commit_after>#include "../src/alm.h"
#include "alm_wrapper.h"
#include <cstdlib>
#include <string>
#include <iostream>

extern "C" {

    #define MAX_NUM_ALM 10

    static const std::string atom_name[] = {
        "X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
        "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K",
        "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu",
        "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",
        "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
        "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr",
        "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm",
        "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au",
        "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac",
        "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es",
        "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
        "Ds", "Rg", "Cn", "Uut", "Uuq", "Uup", "Uuh", "Uus", "Uuo"};

    static ALM_NS::ALM *alm[MAX_NUM_ALM];
    static int is_alm_used[MAX_NUM_ALM];
    static int is_alm_init = 0;

    void alm_init(void)
    {
        int id;
        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (alm[id]) {
                delete alm[id];
            }
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
        is_alm_init = 1;
    }

    int alm_new(void)
    {
        int id;

        if (!is_alm_init) {
            alm_init();
        }

        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (!is_alm_used[id]) {
                alm[id] = new ALM_NS::ALM();
                is_alm_used[id] = 1;
                break;
            }
        }

        if (id == MAX_NUM_ALM) {
            return -1;
        } else {
            return id;
        }
    }

    void alm_delete(const int id)
    {
        if (alm[id]) {
            delete alm[id];
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
    }

    // void set_output_filename_prefix(const std::string prefix);
    // void set_is_print_symmetry(const int is_printsymmetry);
    // void set_is_print_hessians(const bool print_hessian);
    // void set_symmetry_param(const int nsym);
    // void set_symmetry_tolerance(const double tolerance);
    // void set_displacement_param(const bool trim_dispsign_for_evenfunc);
    // void set_displacement_basis(const std::string str_disp_basis);
    // void set_periodicity(const int is_periodic[3]);

    void alm_set_cell(const int id,
                      const int nat,
                      const double lavec[3][3],
                      const double xcoord[][3],
                      const int kd[])
    {
        int i, j, nkd;
        int nkd_vals[nat], kd_new[nat];
        bool kd_exist;

        nkd_vals[0] = kd[0];
        kd_new[0] = 1;
        nkd = 1;
        for (i = 1; i < nat; ++i) {
            kd_exist = false;
            for (j = 0; j < nkd; ++j) {
                if (nkd_vals[j] == kd[i]) {
                    kd_exist = true;
                    kd_new[i] = j + 1;
                    break;
                }
            }
            if (!kd_exist) {
                nkd_vals[nkd] = kd[i];
                kd_new[i] = nkd + 1;
                ++nkd;
            }
        }
        std::string *kdname = new std::string[nkd];
        //std::string kdname[nkd];
        for (int i = 0; i < nkd; i++) {
            kdname[i] = atom_name[abs(nkd_vals[i]) % 118];
        }

        alm[id]->set_cell(nat, lavec, xcoord, kd_new, kdname);
        delete [] kdname;
    }

    // void set_magnetic_params(const double* magmom,
    //   		       const bool lspin,
    //   		       const int noncollinear,
    //   		       const int trev_sym_mag,
    //   		       const std::string str_magmom);

    void alm_set_displacement_and_force(const int id,
                                        const double* u_in,
                                        const double* f_in,
                                        const int nat,
                                        const int ndata_used)
    {
        alm[id]->set_displacement_and_force(u_in, f_in, nat, ndata_used);
    }

    void alm_set_fitting_constraint_type(const int id,
                                         const int constraint_flag) // ICONST
    {
        alm[id]->set_fitting_constraint_type(constraint_flag);
    }

    // void set_fitting_constraint_rotation_axis(const std::string rotation_axis) // ROTAXIS
    // void set_multiplier_option(const int multiply_data);
    // void set_fitting_filenames(const std::string dfile,
    //   			 const std::string ffile);
    void alm_set_norder(const int id,
                        const int maxorder)
    {
        alm[id]->set_norder(maxorder);
    }

    void alm_set_nbody_include(const int id,
                               const int *nbody_include)
    {
        alm[id]->set_nbody_include(nbody_include);
    }

    void alm_set_cutoff_radii(const int id,
                              const double * rcs)
    {
        alm[id]->set_cutoff_radii(rcs);
    }

    int alm_get_atom_mapping_by_pure_translations(const int id,
                                                  int *map_p2s)
    {
        return alm[id]->get_atom_mapping_by_pure_translations(map_p2s);
    }

    int alm_get_number_of_displacement_patterns(const int id,
                                                const int fc_order) // harmonic=1,
    {
        return alm[id]->get_number_of_displacement_patterns(fc_order);
    }

    void alm_get_numbers_of_displacements(const int id,
                                          int *numbers,
                                          const int fc_order) // harmonic=1,
    {
        alm[id]->get_numbers_of_displacements(numbers, fc_order);
    }

    int alm_get_displacement_patterns(const int id,
                                      int *atom_indices,
                                      double *disp_patterns,
                                      const int fc_order) // harmonic=1,
    {
        return alm[id]->get_displacement_patterns(atom_indices,
                                              disp_patterns,
                                              fc_order);
    }

    int alm_get_number_of_fc_elements(const int id,
                                      const int fc_order)  // harmonic=1, ...
    {
        return alm[id]->get_number_of_fc_elements(fc_order);
    }

    void alm_get_fc(const int id,
                    double *fc_values,
                    int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                    const int fc_order)
    {
        alm[id]->get_fc(fc_values, elem_indices, fc_order);
    }

    void alm_run_suggest(const int id)
    {
        alm[id]->set_run_mode("suggest");
        alm[id]->run();
    }

    void alm_run_fitting(const int id)
    {
        alm[id]->set_run_mode("fitting");
        alm[id]->run();
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cretstrm.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 00:38:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_automation.hxx"
#ifndef _CRetStream_HXX
#include "cretstrm.hxx"
#endif
#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#include "rcontrol.hxx"
#include "svcommstream.hxx"

SV_IMPL_REF(SbxBase)

CRetStream::CRetStream(SvStream *pIn)
{
    pSammel = pIn;
    delete pCommStream;
    pCommStream = new SvCommStream( pSammel );
}

CRetStream::~CRetStream()
{
    delete pCommStream;
}

void CRetStream::Read ( String &aString )
{
    comm_UniChar* pStr;
    USHORT nLenInChars;
    CmdBaseStream::Read( pStr, nLenInChars );

    aString = String( pStr, nLenInChars );
    delete [] pStr;
}

void CRetStream::Read( SbxValue &aValue )
{
    *pSammel >> nId;
    if (nId != BinSbxValue)
    {
        DBG_ERROR1( "Falscher Typ im Stream: Erwartet SbxValue, gefunden :%hu", nId );
    }
    SbxBaseRef xBase = SbxBase::Load( *pSammel );
    if ( IS_TYPE( SbxValue, xBase ) )
        aValue = *PTR_CAST( SbxValue, &xBase );
}

<commit_msg>INTEGRATION: CWS changefileheader (1.5.86); FILE MERGED 2008/04/01 15:00:04 thb 1.5.86.2: #i85898# Stripping all external header guards 2008/03/28 16:03:40 rt 1.5.86.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: cretstrm.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_automation.hxx"
#ifndef _CRetStream_HXX
#include "cretstrm.hxx"
#endif
#include <tools/debug.hxx>
#include "rcontrol.hxx"
#include "svcommstream.hxx"

SV_IMPL_REF(SbxBase)

CRetStream::CRetStream(SvStream *pIn)
{
    pSammel = pIn;
    delete pCommStream;
    pCommStream = new SvCommStream( pSammel );
}

CRetStream::~CRetStream()
{
    delete pCommStream;
}

void CRetStream::Read ( String &aString )
{
    comm_UniChar* pStr;
    USHORT nLenInChars;
    CmdBaseStream::Read( pStr, nLenInChars );

    aString = String( pStr, nLenInChars );
    delete [] pStr;
}

void CRetStream::Read( SbxValue &aValue )
{
    *pSammel >> nId;
    if (nId != BinSbxValue)
    {
        DBG_ERROR1( "Falscher Typ im Stream: Erwartet SbxValue, gefunden :%hu", nId );
    }
    SbxBaseRef xBase = SbxBase::Load( *pSammel );
    if ( IS_TYPE( SbxValue, xBase ) )
        aValue = *PTR_CAST( SbxValue, &xBase );
}

<|endoftext|>


<commit_before>// Copyright 2015-2017 Philipp Thomann
//
// This file is part of liquidSVM.
//
// liquidSVM is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// liquidSVM 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 Affero General Public License for more details.

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

#undef COMPILE_FOR_COMMAND_LINE__

#define COMPILE_FOR_R__

#ifdef __MINGW32__
#define MS_WIN64
#endif

#include <Python.h>

#define VPRINTF(message_format, ...) \
{ \
    char buffer[1001]; \
    va_list args; \
    va_start (args, message_format); \
    vsnprintf (buffer, 1001, message_format, args); \
    va_end (args); \
    PyGILState_STATE gstate; \
    gstate = PyGILState_Ensure(); \
    PySys_WriteStdout("%s", buffer); \
    PyGILState_Release(gstate); \
}

bool doInterrupt = false;
void CheckUserInterrupt();

#define CLEAR_INTERRUPT doInterrupt = false;

#include "common/liquidSVM.h"

void CheckUserInterrupt(){
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
	int err = PyErr_CheckSignals();
    PyGILState_Release(gstate);
	if(err < 0)
	    doInterrupt = true;
	if(doInterrupt)
		throw string("Interrupted");
}

/*
// only for reference - maybe we never will use this approach...
static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s! %s\n", name, liquid_svm_default_params(-1,1));

    Py_RETURN_NONE;
}
*/

/*
static PyMethodDef liquidSVMmethods[] =
{
     //{"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initliquidSVM(void)
{
	printf("Loading C++ Module of liquidSVM-python\n");
    (void) Py_InitModule("liquidSVM", liquidSVMmethods);
}
*/

// the following helps in eclipse to switch between python 2 and 3
#ifndef PY_MAJOR_VERSION
#define PY_MAJOR_VERSION 3
#endif

struct module_state {
    PyObject *error;
};

#if PY_MAJOR_VERSION >= 3
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
#else
#define GETSTATE(m) (&_state)
static struct module_state _state;
#endif

static PyObject *
error_out(PyObject *m) {
    struct module_state *st = GETSTATE(m);
    PyErr_SetString(st->error, "something bad happened");
    return NULL;
}

static PyMethodDef liquidSVM_methods[] = {
    {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
    {NULL, NULL}
};

#if PY_MAJOR_VERSION >= 3

static int liquidSVM_traverse(PyObject *m, visitproc visit, void *arg) {
    Py_VISIT(GETSTATE(m)->error);
    return 0;
}

static int liquidSVM_clear(PyObject *m) {
    Py_CLEAR(GETSTATE(m)->error);
    return 0;
}

static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "liquidSVM",
        NULL,
        sizeof(struct module_state),
        liquidSVM_methods,
        NULL,
        liquidSVM_traverse,
        liquidSVM_clear,
        NULL
};

#define INITERROR return NULL

PyMODINIT_FUNC
PyInit_liquidSVM(void)

#else
#define INITERROR return

void
initliquidSVM(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
    PyObject *module = PyModule_Create(&moduledef);
#else
    PyObject *module = Py_InitModule("liquidSVM", liquidSVM_methods);
#endif

    if (module == NULL)
        INITERROR;
    struct module_state *st = GETSTATE(module);

    st->error = PyErr_NewException((char*)"liquidSVM.Error", NULL, NULL);
    if (st->error == NULL) {
        Py_DECREF(module);
        INITERROR;
    }

#if PY_MAJOR_VERSION >= 3
    return module;
#endif
}

<commit_msg>deactivated ctrl-c for python on windows<commit_after>// Copyright 2015-2017 Philipp Thomann
//
// This file is part of liquidSVM.
//
// liquidSVM is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// liquidSVM 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 Affero General Public License for more details.

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

#undef COMPILE_FOR_COMMAND_LINE__

#define COMPILE_FOR_R__

#ifdef __MINGW32__
#define MS_WIN64
#endif

#include <Python.h>

#define VPRINTF(message_format, ...) \
{ \
    char buffer[1001]; \
    va_list args; \
    va_start (args, message_format); \
    vsnprintf (buffer, 1001, message_format, args); \
    va_end (args); \
    PyGILState_STATE gstate; \
    gstate = PyGILState_Ensure(); \
    PySys_WriteStdout("%s", buffer); \
    PyGILState_Release(gstate); \
}

bool doInterrupt = false;
void CheckUserInterrupt();

#define CLEAR_INTERRUPT doInterrupt = false;

#include "common/liquidSVM.h"

void CheckUserInterrupt(){
#ifndef _WIN32
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
	int err = PyErr_CheckSignals();
    PyGILState_Release(gstate);
	if(err < 0)
	    doInterrupt = true;
	if(doInterrupt)
		throw string("Interrupted");
#endif
}

/*
// only for reference - maybe we never will use this approach...
static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s! %s\n", name, liquid_svm_default_params(-1,1));

    Py_RETURN_NONE;
}
*/

/*
static PyMethodDef liquidSVMmethods[] =
{
     //{"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initliquidSVM(void)
{
	printf("Loading C++ Module of liquidSVM-python\n");
    (void) Py_InitModule("liquidSVM", liquidSVMmethods);
}
*/

// the following helps in eclipse to switch between python 2 and 3
#ifndef PY_MAJOR_VERSION
#define PY_MAJOR_VERSION 3
#endif

struct module_state {
    PyObject *error;
};

#if PY_MAJOR_VERSION >= 3
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
#else
#define GETSTATE(m) (&_state)
static struct module_state _state;
#endif

static PyObject *
error_out(PyObject *m) {
    struct module_state *st = GETSTATE(m);
    PyErr_SetString(st->error, "something bad happened");
    return NULL;
}

static PyMethodDef liquidSVM_methods[] = {
    {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
    {NULL, NULL}
};

#if PY_MAJOR_VERSION >= 3

static int liquidSVM_traverse(PyObject *m, visitproc visit, void *arg) {
    Py_VISIT(GETSTATE(m)->error);
    return 0;
}

static int liquidSVM_clear(PyObject *m) {
    Py_CLEAR(GETSTATE(m)->error);
    return 0;
}

static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "liquidSVM",
        NULL,
        sizeof(struct module_state),
        liquidSVM_methods,
        NULL,
        liquidSVM_traverse,
        liquidSVM_clear,
        NULL
};

#define INITERROR return NULL

PyMODINIT_FUNC
PyInit_liquidSVM(void)

#else
#define INITERROR return

void
initliquidSVM(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
    PyObject *module = PyModule_Create(&moduledef);
#else
    PyObject *module = Py_InitModule("liquidSVM", liquidSVM_methods);
#endif

    if (module == NULL)
        INITERROR;
    struct module_state *st = GETSTATE(module);

    st->error = PyErr_NewException((char*)"liquidSVM.Error", NULL, NULL);
    if (st->error == NULL) {
        Py_DECREF(module);
        INITERROR;
    }

#if PY_MAJOR_VERSION >= 3
    return module;
#endif
}

<|endoftext|>


<commit_before>/*
    This file is part of Android File Transfer For Linux.
    Copyright (C) 2015-2020  Vladimir Menshakov

    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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "mtpobjectsmodel.h"
#include "qtobjectstream.h"
#include "utils.h"
#include <QDebug>
#include <QBrush>
#include <QColor>
#include <QIcon>
#include <QFile>
#include <QFont>
#include <QFileInfo>
#include <QMimeData>
#include <QUrl>

#include <mtp/ptp/ByteArrayObjectStream.h>
#include <cli/PosixStreams.h> //for mtime

MtpObjectsModel::MtpObjectsModel(QObject *parent):
	QAbstractListModel(parent),
	_storageId(mtp::Session::AllStorages),
	_parentObjectId(mtp::Session::Root),
	_enableThumbnails(false)
{ }

MtpObjectsModel::~MtpObjectsModel()
{ }

void MtpObjectsModel::setStorageId(mtp::StorageId storageId)
{
	_storageId = storageId;
	setParent(mtp::Session::Root);
}

void MtpObjectsModel::setParent(mtp::ObjectId parentObjectId)
{
	beginResetModel();

	_parentObjectId = parentObjectId;
	mtp::msg::ObjectHandles handles;
	try
	{
		handles = _session->GetObjectHandles(_storageId, mtp::ObjectFormat::Any, parentObjectId);
	}
	catch(const std::exception & ex)
	{ qWarning() << "setParent failed:" << fromUtf8(ex.what()); }
	_rows.clear();
	_rows.reserve(handles.ObjectHandles.size());
	for(size_t i = 0; i < handles.ObjectHandles.size(); ++i)
	{
		mtp::ObjectId oid = handles.ObjectHandles[i];
		_rows.append(Row(oid));
	}

	endResetModel();
}

bool MtpObjectsModel::enter(int idx)
{
	if (idx < 0 || idx >= _rows.size())
		return false;

	Row &row = _rows[idx];
	if (row.IsAssociation(_session))
	{
		setParent(row.ObjectId);
		return true;
	}
	else
		return false;
}

QModelIndex MtpObjectsModel::findObject(mtp::ObjectId objectId) const
{
	auto idx = std::find_if(_rows.begin(), _rows.end(), [objectId](const Row & row) { return row.ObjectId == objectId; } );
	return idx != _rows.end()? createIndex(std::distance(_rows.begin(), idx), 0): QModelIndex();
}

QModelIndex MtpObjectsModel::findObject(const QString &filename) const
{
	auto idx = std::find_if(_rows.begin(), _rows.end(), [filename, this](Row & row) { return fromUtf8(row.GetInfo(_session)->Filename) == filename; } );
	return idx != _rows.end()? createIndex(std::distance(_rows.begin(), idx), 0): QModelIndex();
}

void MtpObjectsModel::setSession(mtp::SessionPtr session)
{
	beginResetModel();
	_session = session;
	setParent(mtp::Session::Root);
	endResetModel();
}

int MtpObjectsModel::rowCount(const QModelIndex &) const
{ return _rows.size(); }

mtp::msg::ObjectInfoPtr MtpObjectsModel::Row::GetInfo(mtp::SessionPtr session)
{
	if (!_info)
	{
		_info = std::make_shared<mtp::msg::ObjectInfo>();
		try
		{
			*_info = session->GetObjectInfo(ObjectId);
			//qDebug() << fromUtf8(row.Info->Filename);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to get object info " << fromUtf8(ex.what()); }
	}
	return _info;
}

MtpObjectsModel::ThumbnailPtr MtpObjectsModel::Row::GetThumbnail(mtp::SessionPtr session, QSize maxSize)
{
	if (!_thumbnail)
	{
		auto stream = std::make_shared<mtp::ByteArrayObjectOutputStream>();
		_thumbnail = std::make_shared<QPixmap>();
		try
		{
			qDebug() << "requesting thumbnail for " << ObjectId.Id;
			session->GetThumb(ObjectId, stream);

			auto & data = stream->GetData();
			QPixmap pixmap;
			if (!pixmap.loadFromData(data.data(), data.size()))
				throw std::runtime_error("couldn't load pixmap");

			*_thumbnail = pixmap.scaled(maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);

			qDebug() << "loaded " << data.size() << " bytes of thumbnail data";
		}
		catch(const std::exception &ex)
		{
			qWarning() << "failed to get thumbnail" << fromUtf8(ex.what());
			*_thumbnail = QIcon::fromTheme("image-missing").pixmap(maxSize);
		}
	}
	return _thumbnail;
}

bool MtpObjectsModel::Row::IsAssociation(mtp::SessionPtr session)
{
	mtp::ObjectFormat format = GetInfo(session)->ObjectFormat;
	return format == mtp::ObjectFormat::Association;
}

void MtpObjectsModel::rename(int idx, const QString &fileName)
{
	qDebug() << "renaming row " << idx << " to " << fileName;
	try
	{
		_session->SetObjectProperty(objectIdAt(idx), mtp::ObjectProperty::ObjectFilename, toUtf8(fileName));
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to rename object" << fromUtf8(ex.what()); }

	_rows[idx].ResetInfo();
	emit dataChanged(createIndex(idx, 0), createIndex(idx, 0));
}

void MtpObjectsModel::deleteObjects(const MtpObjectList &objects)
{
	for(mtp::ObjectId objectId: objects)
	{
		try
		{
			qDebug() << "deleting object " << objectId;
			_session->DeleteObject(objectId);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to delete object " << fromUtf8(ex.what()); }
	}
	refresh();
}

mtp::ObjectId MtpObjectsModel::objectIdAt(int idx)
{
	return (idx >= 0 && idx < _rows.size())? _rows[idx].ObjectId: mtp::ObjectId();
}

QVariant MtpObjectsModel::data(const QModelIndex &index, int role) const
{
	int row_idx = index.row();
	if (row_idx < 0 || row_idx > _rows.size())
		return QVariant();

	Row &row = _rows[row_idx];

	switch(role)
	{
	case Qt::ToolTipRole:
	case Qt::DisplayRole:
		return fromUtf8(row.GetInfo(_session)->Filename);

	case Qt::FontRole:
		{
			QFont font;
			if (row.IsAssociation(_session))
				font.setBold(true);
			return font;
		}

	case Qt::DecorationRole:
		if (_enableThumbnails)
			return *row.GetThumbnail(_session, QSize(_maxThumbnailSize.width(), _maxThumbnailSize.height() / 1.5f));
		else
			return QVariant();

	case Qt::SizeHintRole:
		if (_enableThumbnails)
			return _maxThumbnailSize;
		else
			return QVariant();

	default:
		return QVariant();
	}
}

mtp::ObjectId MtpObjectsModel::createDirectory(mtp::ObjectId parentObjectId, const QString &name, mtp::AssociationType type)
{
	QModelIndex existingDir = findObject(name);
	if (existingDir.isValid())
		return _rows.at(existingDir.row()).ObjectId;

	mtp::StorageId storageId = _storageId != mtp::Session::AllStorages? _storageId: mtp::Session::AnyStorage;
	auto noi = _session->CreateDirectory(toUtf8(name), parentObjectId, storageId, type);
	if (parentObjectId == _parentObjectId)
	{
		beginInsertRows(QModelIndex(), _rows.size(), _rows.size());
		_rows.push_back(Row(noi.ObjectId));
		endInsertRows();
	}
	return noi.ObjectId;
}

bool MtpObjectsModel::uploadFile(mtp::ObjectId parentObjectId, const QString &filePath, QString filename)
{
	QFileInfo fileInfo(filePath);
	mtp::ObjectFormat objectFormat = mtp::ObjectFormatFromFilename(toUtf8(filePath));

	if (filename.isEmpty())
		filename = fileInfo.fileName();

	qDebug() << "uploadFile " << fileInfo.fileName() << " as " << filename;

	bool needReset = false;
	QModelIndex existingObject = findObject(filename);
	if (existingObject.isValid())
	{
		if (!emit existingFileOverwrite(filename))
		{
			qDebug() << "skipping, overwrite not confirmed";
			return false;
		}
		try
		{
			_session->DeleteObject(_rows.at(existingObject.row()).ObjectId);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to delete object" << fromUtf8(ex.what()); return false; }

		needReset = parentObjectId == _parentObjectId;
	}

	std::shared_ptr<QtObjectInputStream> object(new QtObjectInputStream(filePath));
	if (!object->Valid())
	{
		qWarning() << "file " << filePath << " could not be opened";
		return false;
	}
	qDebug() << "sending " << fileInfo.size() << " bytes";
	connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));

	mtp::msg::ObjectInfo oi;
	oi.Filename = toUtf8(filename);
	oi.ObjectFormat = objectFormat;
	oi.ObjectCompressedSize = fileInfo.size();
	mtp::msg::NewObjectInfo noi;
	try
	{
		noi = _session->SendObjectInfo(oi, _storageId != mtp::Session::AllStorages? _storageId: mtp::Session::AnyStorage, parentObjectId);
		qDebug() << "new object id: " << noi.ObjectId << ", sending...";
		_session->SendObject(object);
		qDebug() << "ok";
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to send new object info " << fromUtf8(ex.what()); return false; }

	if (parentObjectId == _parentObjectId)
	{
		beginInsertRows(QModelIndex(), _rows.size(), _rows.size());
		_rows.push_back(Row(noi.ObjectId));
		endInsertRows();
	}
	if (needReset)
		refresh();
	return true;
}

bool MtpObjectsModel::sendFile(const QString &filePath)
{
	try
	{
		std::shared_ptr<QtObjectInputStream> object(new QtObjectInputStream(filePath));
		connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));
		_session->SendObject(object);
		return true;
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to send file " << fromUtf8(ex.what()); return false; }
}

bool MtpObjectsModel::downloadFile(const QString &filePath, mtp::ObjectId objectId)
{
	auto object = std::make_shared<QtObjectOutputStream>(filePath);
	if (!object->Valid())
	{
		qWarning() << "cannot open file " << filePath;
		return false;
	}
	connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));
	_session->GetObject(objectId, object);
	object.reset();
	cli::ObjectOutputStream::SetModificationTime(filePath.toStdString(), _session->GetObjectModificationTime(objectId));
	return true;
}

MtpObjectsModel::ObjectInfo MtpObjectsModel::getInfoById(mtp::ObjectId objectId) const
{
	mtp::msg::ObjectInfo oi(_session->GetObjectInfo(objectId));
	qint64 size = oi.ObjectCompressedSize;
	if (size == mtp::MaxObjectSize)
		size = _session->GetObjectIntegerProperty(objectId, mtp::ObjectProperty::ObjectSize);
	return ObjectInfo(fromUtf8(oi.Filename), oi.ObjectFormat, size);
}

QStringList MtpObjectsModel::extractMimeData(const QMimeData *data)
{
	QStringList files;
	QList<QUrl> urls = data->urls();
	for (auto url : urls)
	{
		//qDebug() << "url " << url;
		if (url.isLocalFile())
			files.push_back(url.toLocalFile());
		else
			qWarning() << "skipping non-local url" << url;
	}
	return files;
}

bool MtpObjectsModel::dropMimeData(const QMimeData *data,
	 Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	qDebug() << "data: " << data << action << row << column;
	if (action != Qt::CopyAction || !data)
		return false;

	QStringList files = extractMimeData(data);
	qDebug() << "files dropped: " << files;
	emit onFilesDropped(files);
	return true;
}

QStringList MtpObjectsModel::mimeTypes () const
{ return QStringList("text/uri-list"); }

Qt::ItemFlags MtpObjectsModel::flags(const QModelIndex &index) const
{
	Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
	return defaultFlags | Qt::ItemIsDropEnabled;
}

void MtpObjectsModel::enableThumbnail(bool enable, QSize maxSize)
{
	beginResetModel();

	_enableThumbnails = enable;
	_maxThumbnailSize = maxSize;

	endResetModel();
}
<commit_msg>check thumbnail format before requesting it and skip if it's not present<commit_after>/*
    This file is part of Android File Transfer For Linux.
    Copyright (C) 2015-2020  Vladimir Menshakov

    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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "mtpobjectsmodel.h"
#include "qtobjectstream.h"
#include "utils.h"
#include <QDebug>
#include <QBrush>
#include <QColor>
#include <QIcon>
#include <QFile>
#include <QFont>
#include <QFileInfo>
#include <QMimeData>
#include <QUrl>

#include <mtp/ptp/ByteArrayObjectStream.h>
#include <cli/PosixStreams.h> //for mtime

MtpObjectsModel::MtpObjectsModel(QObject *parent):
	QAbstractListModel(parent),
	_storageId(mtp::Session::AllStorages),
	_parentObjectId(mtp::Session::Root),
	_enableThumbnails(false)
{ }

MtpObjectsModel::~MtpObjectsModel()
{ }

void MtpObjectsModel::setStorageId(mtp::StorageId storageId)
{
	_storageId = storageId;
	setParent(mtp::Session::Root);
}

void MtpObjectsModel::setParent(mtp::ObjectId parentObjectId)
{
	beginResetModel();

	_parentObjectId = parentObjectId;
	mtp::msg::ObjectHandles handles;
	try
	{
		handles = _session->GetObjectHandles(_storageId, mtp::ObjectFormat::Any, parentObjectId);
	}
	catch(const std::exception & ex)
	{ qWarning() << "setParent failed:" << fromUtf8(ex.what()); }
	_rows.clear();
	_rows.reserve(handles.ObjectHandles.size());
	for(size_t i = 0; i < handles.ObjectHandles.size(); ++i)
	{
		mtp::ObjectId oid = handles.ObjectHandles[i];
		_rows.append(Row(oid));
	}

	endResetModel();
}

bool MtpObjectsModel::enter(int idx)
{
	if (idx < 0 || idx >= _rows.size())
		return false;

	Row &row = _rows[idx];
	if (row.IsAssociation(_session))
	{
		setParent(row.ObjectId);
		return true;
	}
	else
		return false;
}

QModelIndex MtpObjectsModel::findObject(mtp::ObjectId objectId) const
{
	auto idx = std::find_if(_rows.begin(), _rows.end(), [objectId](const Row & row) { return row.ObjectId == objectId; } );
	return idx != _rows.end()? createIndex(std::distance(_rows.begin(), idx), 0): QModelIndex();
}

QModelIndex MtpObjectsModel::findObject(const QString &filename) const
{
	auto idx = std::find_if(_rows.begin(), _rows.end(), [filename, this](Row & row) { return fromUtf8(row.GetInfo(_session)->Filename) == filename; } );
	return idx != _rows.end()? createIndex(std::distance(_rows.begin(), idx), 0): QModelIndex();
}

void MtpObjectsModel::setSession(mtp::SessionPtr session)
{
	beginResetModel();
	_session = session;
	setParent(mtp::Session::Root);
	endResetModel();
}

int MtpObjectsModel::rowCount(const QModelIndex &) const
{ return _rows.size(); }

mtp::msg::ObjectInfoPtr MtpObjectsModel::Row::GetInfo(mtp::SessionPtr session)
{
	if (!_info)
	{
		_info = std::make_shared<mtp::msg::ObjectInfo>();
		try
		{
			*_info = session->GetObjectInfo(ObjectId);
			//qDebug() << fromUtf8(row.Info->Filename);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to get object info " << fromUtf8(ex.what()); }
	}
	return _info;
}

MtpObjectsModel::ThumbnailPtr MtpObjectsModel::Row::GetThumbnail(mtp::SessionPtr session, QSize maxSize)
{
	if (!_thumbnail)
	{
		auto stream = std::make_shared<mtp::ByteArrayObjectOutputStream>();
		_thumbnail = std::make_shared<QPixmap>();
		try
		{
			auto format = GetInfo(session)->ThumbFormat;
			if (format == 0)
				throw std::runtime_error("invalid thumbnail format");

			qDebug() << "requesting thumbnail for " << ObjectId.Id << ", format: " << format;
			session->GetThumb(ObjectId, stream);

			auto & data = stream->GetData();
			QPixmap pixmap;
			if (!pixmap.loadFromData(data.data(), data.size()))
				throw std::runtime_error("couldn't load pixmap");

			*_thumbnail = pixmap.scaled(maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);

			qDebug() << "loaded " << data.size() << " bytes of thumbnail data";
		}
		catch(const std::exception &ex)
		{
			qWarning() << "failed to get thumbnail" << fromUtf8(ex.what());
			*_thumbnail = QIcon::fromTheme("image-missing").pixmap(maxSize);
		}
	}
	return _thumbnail;
}

bool MtpObjectsModel::Row::IsAssociation(mtp::SessionPtr session)
{
	mtp::ObjectFormat format = GetInfo(session)->ObjectFormat;
	return format == mtp::ObjectFormat::Association;
}

void MtpObjectsModel::rename(int idx, const QString &fileName)
{
	qDebug() << "renaming row " << idx << " to " << fileName;
	try
	{
		_session->SetObjectProperty(objectIdAt(idx), mtp::ObjectProperty::ObjectFilename, toUtf8(fileName));
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to rename object" << fromUtf8(ex.what()); }

	_rows[idx].ResetInfo();
	emit dataChanged(createIndex(idx, 0), createIndex(idx, 0));
}

void MtpObjectsModel::deleteObjects(const MtpObjectList &objects)
{
	for(mtp::ObjectId objectId: objects)
	{
		try
		{
			qDebug() << "deleting object " << objectId;
			_session->DeleteObject(objectId);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to delete object " << fromUtf8(ex.what()); }
	}
	refresh();
}

mtp::ObjectId MtpObjectsModel::objectIdAt(int idx)
{
	return (idx >= 0 && idx < _rows.size())? _rows[idx].ObjectId: mtp::ObjectId();
}

QVariant MtpObjectsModel::data(const QModelIndex &index, int role) const
{
	int row_idx = index.row();
	if (row_idx < 0 || row_idx > _rows.size())
		return QVariant();

	Row &row = _rows[row_idx];

	switch(role)
	{
	case Qt::ToolTipRole:
	case Qt::DisplayRole:
		return fromUtf8(row.GetInfo(_session)->Filename);

	case Qt::FontRole:
		{
			QFont font;
			if (row.IsAssociation(_session))
				font.setBold(true);
			return font;
		}

	case Qt::DecorationRole:
		if (_enableThumbnails)
			return *row.GetThumbnail(_session, QSize(_maxThumbnailSize.width(), _maxThumbnailSize.height() / 1.5f));
		else
			return QVariant();

	case Qt::SizeHintRole:
		if (_enableThumbnails)
			return _maxThumbnailSize;
		else
			return QVariant();

	default:
		return QVariant();
	}
}

mtp::ObjectId MtpObjectsModel::createDirectory(mtp::ObjectId parentObjectId, const QString &name, mtp::AssociationType type)
{
	QModelIndex existingDir = findObject(name);
	if (existingDir.isValid())
		return _rows.at(existingDir.row()).ObjectId;

	mtp::StorageId storageId = _storageId != mtp::Session::AllStorages? _storageId: mtp::Session::AnyStorage;
	auto noi = _session->CreateDirectory(toUtf8(name), parentObjectId, storageId, type);
	if (parentObjectId == _parentObjectId)
	{
		beginInsertRows(QModelIndex(), _rows.size(), _rows.size());
		_rows.push_back(Row(noi.ObjectId));
		endInsertRows();
	}
	return noi.ObjectId;
}

bool MtpObjectsModel::uploadFile(mtp::ObjectId parentObjectId, const QString &filePath, QString filename)
{
	QFileInfo fileInfo(filePath);
	mtp::ObjectFormat objectFormat = mtp::ObjectFormatFromFilename(toUtf8(filePath));

	if (filename.isEmpty())
		filename = fileInfo.fileName();

	qDebug() << "uploadFile " << fileInfo.fileName() << " as " << filename;

	bool needReset = false;
	QModelIndex existingObject = findObject(filename);
	if (existingObject.isValid())
	{
		if (!emit existingFileOverwrite(filename))
		{
			qDebug() << "skipping, overwrite not confirmed";
			return false;
		}
		try
		{
			_session->DeleteObject(_rows.at(existingObject.row()).ObjectId);
		}
		catch(const std::exception &ex)
		{ qWarning() << "failed to delete object" << fromUtf8(ex.what()); return false; }

		needReset = parentObjectId == _parentObjectId;
	}

	std::shared_ptr<QtObjectInputStream> object(new QtObjectInputStream(filePath));
	if (!object->Valid())
	{
		qWarning() << "file " << filePath << " could not be opened";
		return false;
	}
	qDebug() << "sending " << fileInfo.size() << " bytes";
	connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));

	mtp::msg::ObjectInfo oi;
	oi.Filename = toUtf8(filename);
	oi.ObjectFormat = objectFormat;
	oi.ObjectCompressedSize = fileInfo.size();
	mtp::msg::NewObjectInfo noi;
	try
	{
		noi = _session->SendObjectInfo(oi, _storageId != mtp::Session::AllStorages? _storageId: mtp::Session::AnyStorage, parentObjectId);
		qDebug() << "new object id: " << noi.ObjectId << ", sending...";
		_session->SendObject(object);
		qDebug() << "ok";
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to send new object info " << fromUtf8(ex.what()); return false; }

	if (parentObjectId == _parentObjectId)
	{
		beginInsertRows(QModelIndex(), _rows.size(), _rows.size());
		_rows.push_back(Row(noi.ObjectId));
		endInsertRows();
	}
	if (needReset)
		refresh();
	return true;
}

bool MtpObjectsModel::sendFile(const QString &filePath)
{
	try
	{
		std::shared_ptr<QtObjectInputStream> object(new QtObjectInputStream(filePath));
		connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));
		_session->SendObject(object);
		return true;
	}
	catch(const std::exception &ex)
	{ qWarning() << "failed to send file " << fromUtf8(ex.what()); return false; }
}

bool MtpObjectsModel::downloadFile(const QString &filePath, mtp::ObjectId objectId)
{
	auto object = std::make_shared<QtObjectOutputStream>(filePath);
	if (!object->Valid())
	{
		qWarning() << "cannot open file " << filePath;
		return false;
	}
	connect(object.get(), SIGNAL(positionChanged(qint64,qint64)), this, SIGNAL(filePositionChanged(qint64,qint64)));
	_session->GetObject(objectId, object);
	object.reset();
	cli::ObjectOutputStream::SetModificationTime(filePath.toStdString(), _session->GetObjectModificationTime(objectId));
	return true;
}

MtpObjectsModel::ObjectInfo MtpObjectsModel::getInfoById(mtp::ObjectId objectId) const
{
	mtp::msg::ObjectInfo oi(_session->GetObjectInfo(objectId));
	qint64 size = oi.ObjectCompressedSize;
	if (size == mtp::MaxObjectSize)
		size = _session->GetObjectIntegerProperty(objectId, mtp::ObjectProperty::ObjectSize);
	return ObjectInfo(fromUtf8(oi.Filename), oi.ObjectFormat, size);
}

QStringList MtpObjectsModel::extractMimeData(const QMimeData *data)
{
	QStringList files;
	QList<QUrl> urls = data->urls();
	for (auto url : urls)
	{
		//qDebug() << "url " << url;
		if (url.isLocalFile())
			files.push_back(url.toLocalFile());
		else
			qWarning() << "skipping non-local url" << url;
	}
	return files;
}

bool MtpObjectsModel::dropMimeData(const QMimeData *data,
	 Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	qDebug() << "data: " << data << action << row << column;
	if (action != Qt::CopyAction || !data)
		return false;

	QStringList files = extractMimeData(data);
	qDebug() << "files dropped: " << files;
	emit onFilesDropped(files);
	return true;
}

QStringList MtpObjectsModel::mimeTypes () const
{ return QStringList("text/uri-list"); }

Qt::ItemFlags MtpObjectsModel::flags(const QModelIndex &index) const
{
	Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
	return defaultFlags | Qt::ItemIsDropEnabled;
}

void MtpObjectsModel::enableThumbnail(bool enable, QSize maxSize)
{
	beginResetModel();

	_enableThumbnails = enable;
	_maxThumbnailSize = maxSize;

	endResetModel();
}
<|endoftext|>


<commit_before>/****************************************************************/
/*                                                              */
/*  Implementation of Cardiac Tissue elasticity as given in     */
/*  [Whiteley2007]                                              */
/*                                                              */
/****************************************************************/

#include "CardiacWhiteley2007Material.h"
#include "ColumnMajorMatrix.h"
#include "CardiacSolidMechanicsMaterial.h"
#include "SymmOrthotropicElasticityTensor.h"
#include "VolumetricModel.h"

template<>
InputParameters validParams<CardiacWhiteley2007Material>()
{
  InputParameters params = validParams<Material>();
  params.addRequiredCoupledVar("disp_x", "The x displacement");
  params.addRequiredCoupledVar("disp_y", "The y displacement");
  params.addRequiredCoupledVar("disp_z", "The z displacement");

  params.addRequiredParam<std::vector<Real> >("k_MN", "Material parameters k_MN in following order: k_11, k_22, k_33, k_12, k_23, k_13");
  params.addRequiredParam<std::vector<Real> >("a_MN", "Material parameters a_MN in following order: a_11, a_22, a_33, a_12, a_23, a_13");
  params.addRequiredParam<std::vector<Real> >("b_MN", "Material parameters b_MN in following order: b_11, b_22, b_33, b_12, b_23, b_13");

  params.addCoupledVar("Ta", 0, "The (position dependent) active tension in fibre direction that will finally drive contraction, see (8) in [Whiteley 2007]. Default is Ta=0, i.e. no active tension anywhere.");
  params.addParam<FunctionName>("Ta_function", "A function that describes the (position dependent) active tension in fibre direction that will finally drive contraction, see (8) in [Whiteley 2007].");
  params.addCoupledVar("p", 0, "Hydrostatic pressure that acts as a Lagrange multiplier to ensure incompressibility. Works best with PressureLagrangeMultiplier kernel.");
  return params;
}

CardiacWhiteley2007Material::CardiacWhiteley2007Material(const std::string  & name,
                                                 InputParameters parameters)
  :Material(name, parameters),
   _grad_disp_x(coupledGradient("disp_x")),
   _grad_disp_y(coupledGradient("disp_y")),
   _grad_disp_z(coupledGradient("disp_z")),
   _k(SymmTensor(getParam<std::vector<Real> >("k_MN"))),
   _a(SymmTensor(getParam<std::vector<Real> >("a_MN"))),
   _b(SymmTensor(getParam<std::vector<Real> >("b_MN"))),
   _stress(declareProperty<RealTensorValue>("Kirchhoff_stress")),
   _stress_derivative(declareProperty<SymmGenericElasticityTensor>("Kirchhoff_stress_derivative")),
   _J(declareProperty<Real>("det_displacement_gradient")),
   _Rf(getMaterialProperty<RealTensorValue>("R_fibre")),
   _has_Ta(isCoupled("Ta")),
   _Ta(_has_Ta ? coupledValue("Ta") : _zero),
   _has_Ta_function(isParamValid("Ta_function")),
   _Ta_function( _has_Ta_function ? &getFunction("Ta_function") : NULL ),
   _has_p(isCoupled("p")),
   _p(_has_p ? coupledScalarValue("p") : _zero),
   _id(1, 1, 1, 0, 0, 0)
{
  if (_has_Ta && _has_Ta_function)
    mooseError("CardiacWhiteley2007Material: Only Ta or Ta_function may be given, not both of them.");
}

const RealTensorValue CardiacWhiteley2007Material::STtoRTV(const SymmTensor & A) const
{
  RealTensorValue B;
  B(0,0) = A(0,0);
  B(1,1) = A(1,1);
  B(2,2) = A(2,2);
  B(0,1) = B(1,0) = A(0,1);
  B(0,2) = B(2,0) = A(0,2);
  B(1,2) = B(2,1) = A(1,2);
  return B;
}

const SymmGenericElasticityTensor CardiacWhiteley2007Material::STtoSGET(const SymmTensor & A) const
{
  SymmGenericElasticityTensor B;
  B(0,0,0,0) = A(0,0);
  B(1,1,1,1) = A(1,1);
  B(2,2,2,2) = A(2,2);
  B(1,2,1,2) = A(1,2);
  B(0,2,0,2) = A(0,2);
  B(0,1,0,1) = A(0,1);
  return B;
}

/*
 * computes outer.transpose() * inner * outer
 * TODO: this should be possible in a more efficient way as the resulting matrix is symmetric
 */
const SymmTensor CardiacWhiteley2007Material::symmProd(const RealTensorValue & outer, const SymmTensor & inner) const
{
  RealTensorValue r(outer.transpose() * STtoRTV(inner) * outer);
  return SymmTensor(r(0,0), r(1,1), r(2,2), r(0,1), r(1,2), r(0,2) );
}

/*
 * computes outer.transpose() * outer
 * TODO: this should be possible in a more efficient way as the resulting matrix is symmetric
 */
const SymmTensor CardiacWhiteley2007Material::symmProd(const RealTensorValue & outer) const
{
  RealTensorValue r(outer.transpose() * outer);
  return SymmTensor(r(0,0), r(1,1), r(2,2), r(0,1), r(1,2), r(0,2) );
}

/*
 * computes C^-1 using the already known det(C)
 */
const SymmTensor CardiacWhiteley2007Material::symmInv(const SymmTensor & C, const Real det) const
{
  SymmTensor Cinv(/* 00 */ C(0,0)*C(1,1)-C(1,2)*C(1,2),
                  /* 11 */ C(0,0)*C(0,0)-C(0,2)*C(0,2),
                  /* 22 */ C(0,0)*C(1,1)-C(0,1)*C(0,1),
                  /* 01 */ C(0,2)*C(1,2)-C(0,0)*C(0,1),
                  /* 12 */ C(0,1)*C(0,2)-C(0,0)*C(1,2),
                  /* 02 */ C(0,1)*C(1,2)-C(0,2)*C(1,1));
  return Cinv * (1./det);
}

void
CardiacWhiteley2007Material::computeQpProperties()
{
  // TODO: verify that all rotations are done in the correct direction, i.e. where do you have to use _Rf or _Rf.transpose() ?
  const RealTensorValue R(1,0,0,0,1,0,0,0,1);//TODO: add rotation again (_Rf[_qp]);

  // local deformation gradient tensor: F(ij) = dx(i)/dX(j)
  // Attention: This is not the displacement gradient:
  //               du(i)/dX(j) = d[x(i)-X(i)]/dX(j) = F(ij) - delta(ij)
  // Thus, as we are working on displacements, we have to add unity to the diagonal
  // (every more elegant way I could think of was also less efficient than this one..)
  const RealTensorValue F(_grad_disp_x[_qp](0) + 1, _grad_disp_x[_qp](1),     _grad_disp_x[_qp](2),
                          _grad_disp_y[_qp](0),     _grad_disp_y[_qp](1) + 1, _grad_disp_y[_qp](2),
                          _grad_disp_z[_qp](0),     _grad_disp_z[_qp](1),     _grad_disp_z[_qp](2) + 1);
  // ...its determinant is a measure for local volume changes (is needed in kernel that ensures incompressibility via hydrostatic pressure/Lagrange multiplier p)
  _J[_qp] = F.det();
  // From here on, we go over to fibre coordinates, i.e. for C, Cinv, E, T
  // Cauchy-Green deformation tensor in fibre coordinates: C = R^T F^T F R
  const SymmTensor C(symmProd(R, symmProd(F)));
  // .. and its inverse (note that det(C_fibre) = det(C) = det(F^T)*det(F) = det(F)^2, since det(R)==1 )
  const SymmTensor Cinv(symmInv(C, _J[_qp]*_J[_qp]));
  // Lagrange-Green strain tensor
  const SymmTensor E( (C - _id) * 0.5 );

  // 2nd Piola-Kirchhoff stress tensor: T(MN) = 1/2[dW/dE(MN) + dW/dE(NM)] + [- p + Ta delta(M1) delta(N1) ] Cinv(MN)
  // We make use of dW/dE(MN) == dW/dE(NM) and will add active tension and pressure terms later
  SymmTensor T;
  // Derivative of T: D(MNPQ) = dT(MN)/dE(PQ)
  // We make use of the symmetry of T and the fact that for our W, dT(MN)/dE(PQ) \propto delta(MP)delta(PQ) if p and Ta are omitted.
  // Thus, a symmetric second-order tensor is sufficient here. Ta and p will be added later, again.
  SymmTensor D;

  for (int M=0;M<3;M++)
    for (int N=M;N<3;N++)
      if (E(M,N) > 0) {
        const Real a(_a(M,N));
        const Real b(_b(M,N));
        const Real k(_k(M,N));
        const Real e(E(M,N));
        const Real d( a - e );
        if (d <= 0)
          mooseError("CardiacWhiteley2007Material: E_{MN} >= a_{MN} - the strain is too large for this model");
        const Real f( b*e/d );
        const Real g( k/pow(d,b) );

        T(M,N) = g * e * ( 2+f );
        D(M,N) = g * ( 2 + (4+e/d+f)*f );
      } else {
        T(M,N) = 0.;
        D(M,N) = 0.;
      }

  // For convenicence, we rotate back into the outer coordinate system here before adding pressure and active tension
  // This is done because adding them destroys symmetries which would force us to rotate a fourth order tensor in
  // the case of the stress derivative instead of the second order tensor D
  T = symmProd(R.transpose(), T);
  D = symmProd(R.transpose(), D);
  const RealTensorValue Cinv_outer( R * STtoRTV(Cinv) * R.transpose() ); // Cinv_outer is still symmetric, but we need it as RealTensorValue anyway since we only compose asymmetric products with it

  // The following steps render
  //    T asymmetric
  //    D asymmetric wrt. (MN)<->(PQ), i.e. we need the full fourth order tensor here.
  _stress[_qp] = STtoRTV(T);
  _stress_derivative[_qp] = STtoSGET(D);

  // Add hydrostatic pressure as Lagrange multiplier to ensure incompressibility
  if (_has_p) {
    _stress[_qp] -= Cinv_outer*_p[0]; // TODO: is [0] correct for scalar variables?
    // for the derivative of T, things do become slightly complicated as we have to do
    // _stress_derivative[_qp](MNPQ) += 2 * _p[0] * Cinv_outer(M,P) * Cinv_outer(Q,N)
    // note that the pressure term is symmetric in Q<->N and in M<->P, i.e. C(MNPQ)=C(MQPN) and C(MNPQ)=C(PNMQ) due to symmetry of Cinv_outer
  }
  // Add active tension in fibre direction
  if (_has_Ta || _has_Ta_function) {
    Real Ta;
    if (_has_Ta)
      Ta = _Ta[_qp];
    else
      Ta = _Ta_function->value(_t, _q_point[_qp]);
    // representation of active tension in fibre direction in outer coordinate system
    const RealTensorValue Ta_outer( R * RealTensorValue(Ta, 0, 0, 0, 0, 0, 0, 0, 0) * R.transpose() );
    _stress[_qp] += Ta_outer*Cinv_outer;
    // _stress_derivative[_qp](MNPQ) -= 2 * _Ta[_qp] delta(M1) delta(N1) * invC(M,P) * invC(Q,N);
    // Ta_outer is stull a diagonal matrix, i.e. there is a delta(MN) involved
    // furthermore, Cinv_outer is symmetric
    for (int M=0;M<3;M++)
      for (int P=0;P<3;P++)
        for (int Q=0;Q<3;Q++)
          _stress_derivative[_qp](M,M,P,Q) += 2 * Ta_outer(M,M) * Cinv_outer(M,P) * Cinv_outer(Q,M);
  }
}

<commit_msg>added pressure term to Jacobian, will not make a difference since we do not have any coupled variable for the pressure, yet.<commit_after>/****************************************************************/
/*                                                              */
/*  Implementation of Cardiac Tissue elasticity as given in     */
/*  [Whiteley2007]                                              */
/*                                                              */
/****************************************************************/

#include "CardiacWhiteley2007Material.h"
#include "ColumnMajorMatrix.h"
#include "CardiacSolidMechanicsMaterial.h"
#include "SymmOrthotropicElasticityTensor.h"
#include "VolumetricModel.h"

template<>
InputParameters validParams<CardiacWhiteley2007Material>()
{
  InputParameters params = validParams<Material>();
  params.addRequiredCoupledVar("disp_x", "The x displacement");
  params.addRequiredCoupledVar("disp_y", "The y displacement");
  params.addRequiredCoupledVar("disp_z", "The z displacement");

  params.addRequiredParam<std::vector<Real> >("k_MN", "Material parameters k_MN in following order: k_11, k_22, k_33, k_12, k_23, k_13");
  params.addRequiredParam<std::vector<Real> >("a_MN", "Material parameters a_MN in following order: a_11, a_22, a_33, a_12, a_23, a_13");
  params.addRequiredParam<std::vector<Real> >("b_MN", "Material parameters b_MN in following order: b_11, b_22, b_33, b_12, b_23, b_13");

  params.addCoupledVar("Ta", 0, "The (position dependent) active tension in fibre direction that will finally drive contraction, see (8) in [Whiteley 2007]. Default is Ta=0, i.e. no active tension anywhere.");
  params.addParam<FunctionName>("Ta_function", "A function that describes the (position dependent) active tension in fibre direction that will finally drive contraction, see (8) in [Whiteley 2007].");
  params.addCoupledVar("p", 0, "Hydrostatic pressure that acts as a Lagrange multiplier to ensure incompressibility. Works best with PressureLagrangeMultiplier kernel.");
  return params;
}

CardiacWhiteley2007Material::CardiacWhiteley2007Material(const std::string  & name,
                                                 InputParameters parameters)
  :Material(name, parameters),
   _grad_disp_x(coupledGradient("disp_x")),
   _grad_disp_y(coupledGradient("disp_y")),
   _grad_disp_z(coupledGradient("disp_z")),
   _k(SymmTensor(getParam<std::vector<Real> >("k_MN"))),
   _a(SymmTensor(getParam<std::vector<Real> >("a_MN"))),
   _b(SymmTensor(getParam<std::vector<Real> >("b_MN"))),
   _stress(declareProperty<RealTensorValue>("Kirchhoff_stress")),
   _stress_derivative(declareProperty<SymmGenericElasticityTensor>("Kirchhoff_stress_derivative")),
   _J(declareProperty<Real>("det_displacement_gradient")),
   _Rf(getMaterialProperty<RealTensorValue>("R_fibre")),
   _has_Ta(isCoupled("Ta")),
   _Ta(_has_Ta ? coupledValue("Ta") : _zero),
   _has_Ta_function(isParamValid("Ta_function")),
   _Ta_function( _has_Ta_function ? &getFunction("Ta_function") : NULL ),
   _has_p(isCoupled("p")),
   _p(_has_p ? coupledScalarValue("p") : _zero),
   _id(1, 1, 1, 0, 0, 0)
{
  if (_has_Ta && _has_Ta_function)
    mooseError("CardiacWhiteley2007Material: Only Ta or Ta_function may be given, not both of them.");
}

const RealTensorValue CardiacWhiteley2007Material::STtoRTV(const SymmTensor & A) const
{
  RealTensorValue B;
  B(0,0) = A(0,0);
  B(1,1) = A(1,1);
  B(2,2) = A(2,2);
  B(0,1) = B(1,0) = A(0,1);
  B(0,2) = B(2,0) = A(0,2);
  B(1,2) = B(2,1) = A(1,2);
  return B;
}

const SymmGenericElasticityTensor CardiacWhiteley2007Material::STtoSGET(const SymmTensor & A) const
{
  SymmGenericElasticityTensor B;
  B(0,0,0,0) = A(0,0);
  B(1,1,1,1) = A(1,1);
  B(2,2,2,2) = A(2,2);
  B(1,2,1,2) = A(1,2);
  B(0,2,0,2) = A(0,2);
  B(0,1,0,1) = A(0,1);
  return B;
}

/*
 * computes outer.transpose() * inner * outer
 * TODO: this should be possible in a more efficient way as the resulting matrix is symmetric
 */
const SymmTensor CardiacWhiteley2007Material::symmProd(const RealTensorValue & outer, const SymmTensor & inner) const
{
  RealTensorValue r(outer.transpose() * STtoRTV(inner) * outer);
  return SymmTensor(r(0,0), r(1,1), r(2,2), r(0,1), r(1,2), r(0,2) );
}

/*
 * computes outer.transpose() * outer
 * TODO: this should be possible in a more efficient way as the resulting matrix is symmetric
 */
const SymmTensor CardiacWhiteley2007Material::symmProd(const RealTensorValue & outer) const
{
  RealTensorValue r(outer.transpose() * outer);
  return SymmTensor(r(0,0), r(1,1), r(2,2), r(0,1), r(1,2), r(0,2) );
}

/*
 * computes C^-1 using the already known det(C)
 */
const SymmTensor CardiacWhiteley2007Material::symmInv(const SymmTensor & C, const Real det) const
{
  SymmTensor Cinv(/* 00 */ C(0,0)*C(1,1)-C(1,2)*C(1,2),
                  /* 11 */ C(0,0)*C(0,0)-C(0,2)*C(0,2),
                  /* 22 */ C(0,0)*C(1,1)-C(0,1)*C(0,1),
                  /* 01 */ C(0,2)*C(1,2)-C(0,0)*C(0,1),
                  /* 12 */ C(0,1)*C(0,2)-C(0,0)*C(1,2),
                  /* 02 */ C(0,1)*C(1,2)-C(0,2)*C(1,1));
  return Cinv * (1./det);
}

void
CardiacWhiteley2007Material::computeQpProperties()
{
  // TODO: verify that all rotations are done in the correct direction, i.e. where do you have to use _Rf or _Rf.transpose() ?
  const RealTensorValue R(1,0,0,0,1,0,0,0,1);//TODO: add rotation again (_Rf[_qp]);

  // local deformation gradient tensor: F(ij) = dx(i)/dX(j)
  // Attention: This is not the displacement gradient:
  //               du(i)/dX(j) = d[x(i)-X(i)]/dX(j) = F(ij) - delta(ij)
  // Thus, as we are working on displacements, we have to add unity to the diagonal
  // (every more elegant way I could think of was also less efficient than this one..)
  const RealTensorValue F(_grad_disp_x[_qp](0) + 1, _grad_disp_x[_qp](1),     _grad_disp_x[_qp](2),
                          _grad_disp_y[_qp](0),     _grad_disp_y[_qp](1) + 1, _grad_disp_y[_qp](2),
                          _grad_disp_z[_qp](0),     _grad_disp_z[_qp](1),     _grad_disp_z[_qp](2) + 1);
  // ...its determinant is a measure for local volume changes (is needed in kernel that ensures incompressibility via hydrostatic pressure/Lagrange multiplier p)
  _J[_qp] = F.det();
  // From here on, we go over to fibre coordinates, i.e. for C, Cinv, E, T
  // Cauchy-Green deformation tensor in fibre coordinates: C = R^T F^T F R
  const SymmTensor C(symmProd(R, symmProd(F)));
  // .. and its inverse (note that det(C_fibre) = det(C) = det(F^T)*det(F) = det(F)^2, since det(R)==1 )
  const SymmTensor Cinv(symmInv(C, _J[_qp]*_J[_qp]));
  // Lagrange-Green strain tensor
  const SymmTensor E( (C - _id) * 0.5 );

  // 2nd Piola-Kirchhoff stress tensor: T(MN) = 1/2[dW/dE(MN) + dW/dE(NM)] + [- p + Ta delta(M1) delta(N1) ] Cinv(MN)
  // We make use of dW/dE(MN) == dW/dE(NM) and will add active tension and pressure terms later
  SymmTensor T;
  // Derivative of T: D(MNPQ) = dT(MN)/dE(PQ)
  // We make use of the symmetry of T and the fact that for our W, dT(MN)/dE(PQ) \propto delta(MP)delta(PQ) if p and Ta are omitted.
  // Thus, a symmetric second-order tensor is sufficient here. Ta and p will be added later, again.
  SymmTensor D;

  for (int M=0;M<3;M++)
    for (int N=M;N<3;N++)
      if (E(M,N) > 0) {
        const Real a(_a(M,N));
        const Real b(_b(M,N));
        const Real k(_k(M,N));
        const Real e(E(M,N));
        const Real d( a - e );
        if (d <= 0)
          mooseError("CardiacWhiteley2007Material: E_{MN} >= a_{MN} - the strain is too large for this model");
        const Real f( b*e/d );
        const Real g( k/pow(d,b) );

        T(M,N) = g * e * ( 2+f );
        D(M,N) = g * ( 2 + (4+e/d+f)*f );
      } else {
        T(M,N) = 0.;
        D(M,N) = 0.;
      }

  // For convenicence, we rotate back into the outer coordinate system here before adding pressure and active tension
  // This is done because adding them destroys symmetries which would force us to rotate a fourth order tensor in
  // the case of the stress derivative instead of the second order tensor D
  T = symmProd(R.transpose(), T);
  D = symmProd(R.transpose(), D);
  const RealTensorValue Cinv_outer( R * STtoRTV(Cinv) * R.transpose() ); // Cinv_outer is still symmetric, but we need it as RealTensorValue anyway since we only compose asymmetric products with it

  // The following steps render
  //    T asymmetric
  //    D asymmetric wrt. (MN)<->(PQ), i.e. we need the full fourth order tensor here.
  _stress[_qp] = STtoRTV(T);
  _stress_derivative[_qp] = STtoSGET(D);

  // Add hydrostatic pressure as Lagrange multiplier to ensure incompressibility
  if (_has_p) {
    _stress[_qp] -= Cinv_outer*_p[0]; // TODO: is [0] correct for scalar variables?
    // for the derivative of T, things do become slightly complicated as we have to do
    // _stress_derivative[_qp](MNPQ) += 2 * _p[0] * Cinv_outer(M,P) * Cinv_outer(Q,N)
    // note that the pressure term is symmetric in Q<->N and in M<->P, i.e. C(MNPQ)=C(MQPN) and C(MNPQ)=C(PNMQ) due to symmetry of Cinv_outer
    for (int M=0;M<3;M++)
      for (int N=0;N<3;N++)
        for (int P=M;P<3;P++)
          for (int Q=N;Q<3;Q++) {
            const Real Tp(2 * _p[0] * Cinv_outer(M,P) * Cinv_outer(Q,N));
            _stress_derivative[_qp](M,N,P,Q) += Tp;
            _stress_derivative[_qp](N,M,P,Q) += Tp;
            _stress_derivative[_qp](M,N,Q,P) += Tp;
            _stress_derivative[_qp](N,M,Q,P) += Tp;
          }
 }
  // Add active tension in fibre direction
  if (_has_Ta || _has_Ta_function) {
    Real Ta;
    if (_has_Ta)
      Ta = _Ta[_qp];
    else
      Ta = _Ta_function->value(_t, _q_point[_qp]);
    // representation of active tension in fibre direction in outer coordinate system
    const RealTensorValue Ta_outer( R * RealTensorValue(Ta, 0, 0, 0, 0, 0, 0, 0, 0) * R.transpose() );
    _stress[_qp] += Ta_outer*Cinv_outer;
    // _stress_derivative[_qp](MNPQ) -= 2 * _Ta[_qp] delta(M1) delta(N1) * invC(M,P) * invC(Q,N);
    // Ta_outer is stull a diagonal matrix, i.e. there is a delta(MN) involved
    // furthermore, Cinv_outer is symmetric
    for (int M=0;M<3;M++)
      for (int P=0;P<3;P++)
        for (int Q=0;Q<3;Q++)
          _stress_derivative[_qp](M,M,P,Q) += 2 * Ta_outer(M,M) * Cinv_outer(M,P) * Cinv_outer(Q,M);
  }
}

<|endoftext|>