<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2014 Luis B. Barrancos, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "orennayarbrdf.h"

// appleseed.renderer headers.
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/bsdf/bsdfwrapper.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/sampling.h"
#include "foundation/math/scalar.h"
#include "foundation/math/vector.h"
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <algorithm>
#include <cmath>

// Forward declarations.
namespace foundation    { class AbortSwitch; }
namespace renderer      { class Assembly; }
namespace renderer      { class Project; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Oren-Nayar BRDF.
    //

    const char* Model = "orennayar_brdf";

    class OrenNayarBRDFImpl
      : public BSDF
    {
      public:
        OrenNayarBRDFImpl(
            const char*         name,
            const ParamArray&   params)
          : BSDF(name, Reflective, Diffuse, params)
        {
            m_inputs.declare("reflectance", InputFormatSpectralReflectance);
            m_inputs.declare("reflectance_multiplier", InputFormatScalar, "1.0");
            m_inputs.declare("roughness" , InputFormatScalar, "0.1");
        }

        virtual void release() OVERRIDE
        {
            delete this;
        }

        virtual const char* get_model() const OVERRIDE
        {
            return Model;
        }

        FORCE_INLINE virtual Mode sample(
            SamplingContext&    sampling_context,
            const void*         data,
            const bool          adjoint,
            const bool          cosine_mult,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Vector3d&           incoming,
            Spectrum&           value,
            double&             probability) const
        {
            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_on = dot(outgoing, n);
            if (cos_on < 0.0)
                return Absorption;

            // Compute the incoming direction in local space.
            sampling_context.split_in_place(2, 1);
            const Vector2d s = sampling_context.next_vector2<2>();
            const Vector3d wi = sample_hemisphere_cosine(s);

            // Transform the incoming direction to parent space.
            incoming = shading_basis.transform_to_parent(wi);

            // No reflection below the shading surface.
            const double cos_in = dot(incoming, n);
            if (cos_in < 0.0)
                return Absorption;

            // Compute the BRDF value.
            const InputValues* values = static_cast<const InputValues*>(data);

            if (values->m_roughness != 0)
                oren_nayar_qualitative(cos_on, cos_in, values->m_roughness, values->m_reflectance, outgoing, incoming, n, value);
            else
                value = values->m_reflectance;

            value *= static_cast<float>(values->m_reflectance_multiplier * RcpPi);

            // Compute the probability density of the sampled direction.
            probability = wi.y * RcpPi;

            // Return the scattering mode.
            return Diffuse;
        }

        FORCE_INLINE virtual double evaluate(
            const void*         data,
            const bool          adjoint,
            const bool          cosine_mult,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const int           modes,
            Spectrum&           value) const
        {
            if (!(modes & Diffuse))
                return 0.0;

            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_in = dot(incoming, n);
            const double cos_on = dot(outgoing, n);
            if (cos_in < 0.0 || cos_on < 0.0)
                return 0.0;

            // Compute the BRDF value.
            const InputValues* values = static_cast<const InputValues*>(data);

            if (values->m_roughness != 0)
                oren_nayar_qualitative(cos_on, cos_in, values->m_roughness, values->m_reflectance, outgoing, incoming, n, value);
            else
                value = values->m_reflectance;

            value *= static_cast<float>(values->m_reflectance_multiplier * RcpPi );

            // Return the probability density of the sampled direction.
            return cos_in * RcpPi;
        }

        FORCE_INLINE virtual double evaluate_pdf(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const int           modes) const
        {
            if (!(modes & Diffuse))
                return 0.0;

            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_in = dot(incoming, n);
            const double cos_on = min(dot(outgoing, n), 1.0);
            if (cos_in < 0.0 || cos_on < 0.0)
                return 0.0;

            return cos_in * RcpPi;
        }

        void oren_nayar_qualitative(
            const double        cos_on,
            const double        cos_in,
            const double        roughness,
            const Spectrum&     reflectance,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const Vector3d&     n,
            Spectrum&           value) const
        {
            const double theta_r = min(HalfPi, acos(cos_on));
            const double theta_i = acos(cos_in);
            const double alpha = max(theta_i, theta_r);
            const double beta = min(theta_i, theta_r);

            const double sigma2 = square(roughness);

            const double C1 = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));

            double C2 = 0.45 * sigma2 / (sigma2 + 0.09);

            const Vector3d V_perp_N = normalize(outgoing - n * dot(outgoing, n));

            const double cos_phi_diff = dot(V_perp_N, normalize(incoming - n * cos_in));

            if (cos_phi_diff >= 0.0)
                C2 *= sin(alpha);
            else
            {
                const double temp = 2.0 * beta * RcpPi;
                C2 *= sin(alpha) - square(temp) * temp;
            }

            const double C3 = 0.125 * (sigma2 / (sigma2 + 0.09) * square(4.0 * alpha * beta * RcpPiSq)) * tan((alpha + beta) * 0.5);

            value = reflectance ;
            value *= static_cast<float>(C1 + (abs(cos_phi_diff) * C2 * tan(beta)) + (1 - abs(cos_phi_diff)) * C3);
            value += square(reflectance) * static_cast<float>(0.17 * cos_in * (sigma2 / (sigma2 + 0.13)) *
                                                             (1 - cos_phi_diff * square(2 * beta * RcpPi)));
        }

      private:
        typedef OrenNayarBRDFInputValues InputValues;
    };

    typedef BSDFWrapper<OrenNayarBRDFImpl> OrenNayarBRDF;
}

//
// OrenNayarBRDFFactory class implementation.
//

const char* OrenNayarBRDFFactory::get_model() const
{
    return Model;
}

const char* OrenNayarBRDFFactory::get_human_readable_model() const
{
    return "Oren-Nayar BRDF";
}

DictionaryArray OrenNayarBRDFFactory::get_input_metadata() const
{
    DictionaryArray metadata;

    metadata.push_back(
        Dictionary()
            .insert("name", "reflectance")
            .insert("label", "Reflectance")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", "0.5"));

    metadata.push_back(
        Dictionary()
            .insert("name", "reflectance_multiplier")
            .insert("label", "Reflectance Multiplier")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Textures"))
            .insert("use", "optional")
            .insert("default", "1.0"));

    metadata.push_back(
        Dictionary()
            .insert("name", "roughness")
            .insert("label", "Roughness")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", "0.1"));

    return metadata;
}

auto_release_ptr<BSDF> OrenNayarBRDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<BSDF>(new OrenNayarBRDF(name, params));
}

}   // namespace renderer
<commit_msg>Added assertions to the 2nd and 3rd coefficients.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2014 Luis B. Barrancos, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "orennayarbrdf.h"

// appleseed.renderer headers.
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/bsdf/bsdfwrapper.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/sampling.h"
#include "foundation/math/scalar.h"
#include "foundation/math/vector.h"
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <algorithm>
#include <cmath>

// Forward declarations.
namespace foundation    { class AbortSwitch; }
namespace renderer      { class Assembly; }
namespace renderer      { class Project; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Oren-Nayar BRDF.
    //

    const char* Model = "orennayar_brdf";

    class OrenNayarBRDFImpl
      : public BSDF
    {
      public:
        OrenNayarBRDFImpl(
            const char*         name,
            const ParamArray&   params)
          : BSDF(name, Reflective, Diffuse, params)
        {
            m_inputs.declare("reflectance", InputFormatSpectralReflectance);
            m_inputs.declare("reflectance_multiplier", InputFormatScalar, "1.0");
            m_inputs.declare("roughness" , InputFormatScalar, "0.1");
        }

        virtual void release() OVERRIDE
        {
            delete this;
        }

        virtual const char* get_model() const OVERRIDE
        {
            return Model;
        }

        FORCE_INLINE virtual Mode sample(
            SamplingContext&    sampling_context,
            const void*         data,
            const bool          adjoint,
            const bool          cosine_mult,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Vector3d&           incoming,
            Spectrum&           value,
            double&             probability) const
        {
            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_on = dot(outgoing, n);
            if (cos_on < 0.0)
                return Absorption;

            // Compute the incoming direction in local space.
            sampling_context.split_in_place(2, 1);
            const Vector2d s = sampling_context.next_vector2<2>();
            const Vector3d wi = sample_hemisphere_cosine(s);

            // Transform the incoming direction to parent space.
            incoming = shading_basis.transform_to_parent(wi);

            // No reflection below the shading surface.
            const double cos_in = dot(incoming, n);
            if (cos_in < 0.0)
                return Absorption;

            // Compute the BRDF value.
            const InputValues* values = static_cast<const InputValues*>(data);

            if (values->m_roughness != 0)
                oren_nayar_qualitative(cos_on, cos_in, values->m_roughness, values->m_reflectance, outgoing, incoming, n, value);
            else
                value = values->m_reflectance;

            value *= static_cast<float>(values->m_reflectance_multiplier * RcpPi);

            // Compute the probability density of the sampled direction.
            probability = wi.y * RcpPi;

            // Return the scattering mode.
            return Diffuse;
        }

        FORCE_INLINE virtual double evaluate(
            const void*         data,
            const bool          adjoint,
            const bool          cosine_mult,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const int           modes,
            Spectrum&           value) const
        {
            if (!(modes & Diffuse))
                return 0.0;

            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_in = dot(incoming, n);
            const double cos_on = dot(outgoing, n);
            if (cos_in < 0.0 || cos_on < 0.0)
                return 0.0;

            // Compute the BRDF value.
            const InputValues* values = static_cast<const InputValues*>(data);

            if (values->m_roughness != 0)
                oren_nayar_qualitative(cos_on, cos_in, values->m_roughness, values->m_reflectance, outgoing, incoming, n, value);
            else
                value = values->m_reflectance;

            value *= static_cast<float>(values->m_reflectance_multiplier * RcpPi );

            // Return the probability density of the sampled direction.
            return cos_in * RcpPi;
        }

        FORCE_INLINE virtual double evaluate_pdf(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const int           modes) const
        {
            if (!(modes & Diffuse))
                return 0.0;

            // No reflection below the shading surface.
            const Vector3d& n = shading_basis.get_normal();
            const double cos_in = dot(incoming, n);
            const double cos_on = dot(outgoing, n);
            if (cos_in < 0.0 || cos_on < 0.0)
                return 0.0;

            return cos_in * RcpPi;
        }

        void oren_nayar_qualitative(
            const double        cos_on,
            const double        cos_in,
            const double        roughness,
            const Spectrum&     reflectance,
            const Vector3d&     outgoing,
            const Vector3d&     incoming,
            const Vector3d&     n,
            Spectrum&           value) const
        {
            const double theta_r = min(HalfPi, acos(cos_on));
            const double theta_i = acos(cos_in);
            const double alpha = max(theta_i, theta_r);
            const double beta = min(theta_i, theta_r);

            const double sigma2 = square(roughness);

            const double C1 = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));

            double C2 = 0.45 * sigma2 / (sigma2 + 0.09);

            const Vector3d V_perp_N = normalize(outgoing - n * dot(outgoing, n));

            const double cos_phi_diff = dot(V_perp_N, normalize(incoming - n * cos_in));

            if (cos_phi_diff >= 0.0)
                C2 *= sin(alpha);
            else
            {
                const double temp = 2.0 * beta * RcpPi;
                C2 *= sin(alpha) - square(temp) * temp;
            }
            assert(C2 >= 0.0);

            const double C3 = 0.125 * (sigma2 / (sigma2 + 0.09) * square(4.0 * alpha * beta * RcpPiSq)) * tan((alpha + beta) * 0.5);
            assert(C3 >= 0.0);

            value = reflectance ;
            value *= static_cast<float>(C1 + (abs(cos_phi_diff) * C2 * tan(beta)) + (1 - abs(cos_phi_diff)) * C3);
            value += square(reflectance) * static_cast<float>(0.17 * cos_in * (sigma2 / (sigma2 + 0.13)) *
                                                             (1 - cos_phi_diff * square(2 * beta * RcpPi)));
        }

      private:
        typedef OrenNayarBRDFInputValues InputValues;
    };

    typedef BSDFWrapper<OrenNayarBRDFImpl> OrenNayarBRDF;
}

//
// OrenNayarBRDFFactory class implementation.
//

const char* OrenNayarBRDFFactory::get_model() const
{
    return Model;
}

const char* OrenNayarBRDFFactory::get_human_readable_model() const
{
    return "Oren-Nayar BRDF";
}

DictionaryArray OrenNayarBRDFFactory::get_input_metadata() const
{
    DictionaryArray metadata;

    metadata.push_back(
        Dictionary()
            .insert("name", "reflectance")
            .insert("label", "Reflectance")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", "0.5"));

    metadata.push_back(
        Dictionary()
            .insert("name", "reflectance_multiplier")
            .insert("label", "Reflectance Multiplier")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Textures"))
            .insert("use", "optional")
            .insert("default", "1.0"));

    metadata.push_back(
        Dictionary()
            .insert("name", "roughness")
            .insert("label", "Roughness")
            .insert("type", "colormap")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", "0.1"));

    return metadata;
}

auto_release_ptr<BSDF> OrenNayarBRDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<BSDF>(new OrenNayarBRDF(name, params));
}

}   // namespace renderer
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   FontDemo.cpp
    created:    17/6/2006
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#include "CEGuiSample.h"
#include "CEGUI.h"
#include "CEGUIPropertyHelper.h"

using namespace CEGUI;

static char *FontList [] =
{
    "DejaVuSans-10",
    "Commonwealth-10",
    "Iconified-12",
    "fkp-16",
    "FairChar-30"
};

static struct
{
    utf8 *Language;
	utf8 *Text;
} LangList [] =
{
	// A list of strings in different languages
	// Feel free to add your own language here (UTF-8 ONLY!)...
    { (utf8 *)"English",
	  (utf8 *)"THIS IS SOME TEXT IN UPPERCASE\n"
              "and this is lowercase...\n"
              "Try Catching The Brown Fox While It's Jumping Over The Lazy Dog" },
    { (utf8 *)"Русский",
	  (utf8 *)"ПРЕВЕД, КРОСАВЧЕГИ!\n"
              "Съешь еще этих чёртовых помидоров, меня от них уже тошнит\n"
              "Как Хорошо, Что Дырочку Для Клизмы\nИмеют Все Живые Организмы\n" },
    { (utf8 *)"Română",
      (utf8 *)"CEI PATRU APOSTOLI\n"
              "au fost trei:\n"
              "Luca şi Matfei\n" },
    { (utf8 *)"Dansk",
      (utf8 *)"FARLIGE STORE BOGSTAVER\n"
              "og flere men små...\n"
              "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon\n" }
};

#define MIN_POINT_SIZE 6.0f

// Sample sub-class for ListboxTextItem that auto-sets the selection brush
// image.  This saves doing it manually every time in the code.
class MyListItem : public ListboxTextItem
{
public:
    MyListItem (const String& text) : ListboxTextItem(text)
    {
        setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
    }
};

// Sample class
class FontDemo : public CEGuiSample
{
public:
    // method to initialse the samples windows and events.
    bool initialiseSample ()
	{
        // we will use of the WindowManager.
        WindowManager& winMgr = WindowManager::getSingleton ();

        // load scheme and set up defaults
        SchemeManager::getSingleton().loadScheme ("TaharezLook.scheme");
        System::getSingleton().setDefaultMouseCursor ("TaharezLook", "MouseArrow");

        // load all the fonts except Commonwealth which has been already loaded
        for (size_t i = 0; i < (sizeof (FontList) / sizeof (FontList [0])); i++)
            FontManager::getSingleton().createFont (String (FontList [i]) + ".font");

        // load an image to use as a background
        ImagesetManager::getSingleton().createImagesetFromImageFile("BackgroundImage", "GPN-2000-001437.tga");

        // here we will use a StaticImage as the root, then we can use it to place a background image
        Window* background = winMgr.createWindow ("TaharezLook/StaticImage");
        // set area rectangle
        background->setArea (URect (cegui_reldim (0), cegui_reldim (0),
                                          cegui_reldim (1), cegui_reldim (1)));
        // disable frame and standard background
        background->setProperty ("FrameEnabled", "false");
        background->setProperty ("BackgroundEnabled", "false");
        // set the background image
        background->setProperty ("Image", "set:BackgroundImage image:full_image");
        // install this as the root GUI sheet
        System::getSingleton ().setGUISheet (background);

        // set tooltip styles (by default there is none)
        System::getSingleton ().setDefaultTooltip ("TaharezLook/Tooltip");

        // load some demo windows and attach to the background 'root'
        background->addChildWindow (winMgr.loadWindowLayout ("FontDemo.layout"));

        // Add the font names to the listbox
        Listbox *lbox = static_cast<Listbox *> (winMgr.getWindow ("FontDemo/FontList"));
        for (size_t i = 0; i < (sizeof (FontList) / sizeof (FontList [0])); i++)
            lbox->addItem (new MyListItem (FontList [i]));
        // set up the font listbox callback
        lbox->subscribeEvent (Listbox::EventSelectionChanged,
                              Event::Subscriber (&FontDemo::handleFontSelection, this));
        // select the first font
        lbox->setItemSelectState (size_t (0), true);

        // Add language list to the listbox
        lbox = static_cast<Listbox *> (winMgr.getWindow ("FontDemo/LangList"));
        for (size_t i = 0; i < (sizeof (LangList) / sizeof (LangList [0])); i++)
            lbox->addItem (new MyListItem (LangList [i].Language));
        // set up the language listbox callback
        lbox->subscribeEvent (Listbox::EventSelectionChanged,
                              Event::Subscriber (&FontDemo::handleLangSelection, this));
        // select the first language
        lbox->setItemSelectState (size_t (0), true);

        winMgr.getWindow("FontDemo/AutoScaled")->subscribeEvent (
            Checkbox::EventCheckStateChanged,
            Event::Subscriber (&FontDemo::handleAutoScaled, this));
        winMgr.getWindow("FontDemo/Antialiased")->subscribeEvent (
            Checkbox::EventCheckStateChanged,
            Event::Subscriber (&FontDemo::handleAntialiased, this));
        winMgr.getWindow("FontDemo/PointSize")->subscribeEvent (
            Scrollbar::EventScrollPositionChanged,
            Event::Subscriber (&FontDemo::handlePointSize, this));

        return true;
	}

    // method to perform any required cleanup operations.
    void cleanupSample ()
    {
        // me? cleanup? what?
    }

    void setFontDesc ()
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();

        String s = f->getProperty ("Name");
        if (f->isPropertyPresent ("PointSize"))
            s += "." + f->getProperty ("PointSize");

        winMgr.getWindow("FontDemo/FontDesc")->setText (s);
    }

    bool handleFontSelection (const EventArgs& e)
    {
        Listbox *lbox = static_cast<Listbox*> (
            static_cast<const WindowEventArgs&> (e).window);

        if (lbox->getFirstSelectedItem ())
		{
            Font *f = FontManager::getSingleton ().getFont (
                lbox->getFirstSelectedItem ()->getText ());

            WindowManager& winMgr = WindowManager::getSingleton ();
            winMgr.getWindow("FontDemo/FontSample")->setFont (f);

            bool b = f->isPropertyPresent ("AutoScaled");
            Checkbox *cb = static_cast<Checkbox *> (winMgr.getWindow("FontDemo/AutoScaled"));
            cb->setEnabled (b);
            if (b)
                cb->setSelected (PropertyHelper::stringToBool (f->getProperty ("AutoScaled")));

            b = f->isPropertyPresent ("Antialiased");
            cb = static_cast<Checkbox *> (winMgr.getWindow("FontDemo/Antialiased"));
            cb->setEnabled (b);
            if (b)
                cb->setSelected (PropertyHelper::stringToBool (f->getProperty ("Antialiased")));

            b = f->isPropertyPresent ("PointSize");
            Scrollbar *sb = static_cast<Scrollbar *> (
                winMgr.getWindow("FontDemo/PointSize"));
            sb->setEnabled (b);
            if (b)
                sb->setScrollPosition (
                    PropertyHelper::stringToFloat (f->getProperty ("PointSize")) - MIN_POINT_SIZE);

            setFontDesc ();
		}

        return true;
    }

    bool handleAutoScaled (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Checkbox *cb = static_cast<Checkbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();
        f->setProperty ("AutoScaled",
                        PropertyHelper::boolToString (cb->isSelected ()));

        return true;
    }

    bool handleAntialiased (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Checkbox *cb = static_cast<Checkbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();
        f->setProperty ("Antialiased",
                        PropertyHelper::boolToString (cb->isSelected ()));

        return true;
    }

    bool handlePointSize (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Scrollbar *sb = static_cast<Scrollbar *> (
            static_cast<const WindowEventArgs&> (e).window);

        Font *f = winMgr.getWindow ("FontDemo/FontSample")->getFont ();

        f->setProperty ("PointSize",
                        PropertyHelper::intToString (
                            int (MIN_POINT_SIZE + sb->getScrollPosition ())));

        setFontDesc ();

        return true;
    }

    bool handleLangSelection (const EventArgs& e)
    {
        Listbox *lbox = static_cast<Listbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        if (lbox->getFirstSelectedItem ())
        {
            size_t idx = lbox->getItemIndex (lbox->getFirstSelectedItem ());
            WindowManager& winMgr = WindowManager::getSingleton ();
            winMgr.getWindow ("FontDemo/FontSample")->setText (LangList [idx].Text);
        }

        return true;
    }
};

int main(int argc, char *argv[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FontDemo app;
    return app.run ();
}
<commit_msg>Changed Russian text in FontDemo sample - the old text apparently potentially offensive.  Thanks to 'Sanya' for the updated text.<commit_after>/***********************************************************************
    filename:   FontDemo.cpp
    created:    17/6/2006
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#include "CEGuiSample.h"
#include "CEGUI.h"
#include "CEGUIPropertyHelper.h"

using namespace CEGUI;

static char *FontList [] =
{
    "DejaVuSans-10",
    "Commonwealth-10",
    "Iconified-12",
    "fkp-16",
    "FairChar-30"
};

static struct
{
    utf8 *Language;
	utf8 *Text;
} LangList [] =
{
	// A list of strings in different languages
	// Feel free to add your own language here (UTF-8 ONLY!)...
    { (utf8 *)"English",
	  (utf8 *)"THIS IS SOME TEXT IN UPPERCASE\n"
              "and this is lowercase...\n"
              "Try Catching The Brown Fox While It's Jumping Over The Lazy Dog" },
    { (utf8 *)"Русский",
	  (utf8 *)"Всё ускоряющаяся эволюция компьютерных технологий предъявила жёсткие требования к производителям как собственно вычислительной техники, так и периферийных устройств.\n"
              "\nЗавершён ежегодный съезд эрудированных школьников, мечтающих глубоко проникнуть в тайны физических явлений и химических реакций.\n"
              "\nавтор панграмм -- Андрей Николаев\n" },
    { (utf8 *)"Română",
      (utf8 *)"CEI PATRU APOSTOLI\n"
              "au fost trei:\n"
              "Luca şi Matfei\n" },
    { (utf8 *)"Dansk",
      (utf8 *)"FARLIGE STORE BOGSTAVER\n"
              "og flere men små...\n"
              "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon\n" }
};

#define MIN_POINT_SIZE 6.0f

// Sample sub-class for ListboxTextItem that auto-sets the selection brush
// image.  This saves doing it manually every time in the code.
class MyListItem : public ListboxTextItem
{
public:
    MyListItem (const String& text) : ListboxTextItem(text)
    {
        setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
    }
};

// Sample class
class FontDemo : public CEGuiSample
{
public:
    // method to initialse the samples windows and events.
    bool initialiseSample ()
	{
        // we will use of the WindowManager.
        WindowManager& winMgr = WindowManager::getSingleton ();

        // load scheme and set up defaults
        SchemeManager::getSingleton().loadScheme ("TaharezLook.scheme");
        System::getSingleton().setDefaultMouseCursor ("TaharezLook", "MouseArrow");

        // load all the fonts except Commonwealth which has been already loaded
        for (size_t i = 0; i < (sizeof (FontList) / sizeof (FontList [0])); i++)
            FontManager::getSingleton().createFont (String (FontList [i]) + ".font");

        // load an image to use as a background
        ImagesetManager::getSingleton().createImagesetFromImageFile("BackgroundImage", "GPN-2000-001437.tga");

        // here we will use a StaticImage as the root, then we can use it to place a background image
        Window* background = winMgr.createWindow ("TaharezLook/StaticImage");
        // set area rectangle
        background->setArea (URect (cegui_reldim (0), cegui_reldim (0),
                                          cegui_reldim (1), cegui_reldim (1)));
        // disable frame and standard background
        background->setProperty ("FrameEnabled", "false");
        background->setProperty ("BackgroundEnabled", "false");
        // set the background image
        background->setProperty ("Image", "set:BackgroundImage image:full_image");
        // install this as the root GUI sheet
        System::getSingleton ().setGUISheet (background);

        // set tooltip styles (by default there is none)
        System::getSingleton ().setDefaultTooltip ("TaharezLook/Tooltip");

        // load some demo windows and attach to the background 'root'
        background->addChildWindow (winMgr.loadWindowLayout ("FontDemo.layout"));

        // Add the font names to the listbox
        Listbox *lbox = static_cast<Listbox *> (winMgr.getWindow ("FontDemo/FontList"));
        for (size_t i = 0; i < (sizeof (FontList) / sizeof (FontList [0])); i++)
            lbox->addItem (new MyListItem (FontList [i]));
        // set up the font listbox callback
        lbox->subscribeEvent (Listbox::EventSelectionChanged,
                              Event::Subscriber (&FontDemo::handleFontSelection, this));
        // select the first font
        lbox->setItemSelectState (size_t (0), true);

        // Add language list to the listbox
        lbox = static_cast<Listbox *> (winMgr.getWindow ("FontDemo/LangList"));
        for (size_t i = 0; i < (sizeof (LangList) / sizeof (LangList [0])); i++)
            lbox->addItem (new MyListItem (LangList [i].Language));
        // set up the language listbox callback
        lbox->subscribeEvent (Listbox::EventSelectionChanged,
                              Event::Subscriber (&FontDemo::handleLangSelection, this));
        // select the first language
        lbox->setItemSelectState (size_t (0), true);

        winMgr.getWindow("FontDemo/AutoScaled")->subscribeEvent (
            Checkbox::EventCheckStateChanged,
            Event::Subscriber (&FontDemo::handleAutoScaled, this));
        winMgr.getWindow("FontDemo/Antialiased")->subscribeEvent (
            Checkbox::EventCheckStateChanged,
            Event::Subscriber (&FontDemo::handleAntialiased, this));
        winMgr.getWindow("FontDemo/PointSize")->subscribeEvent (
            Scrollbar::EventScrollPositionChanged,
            Event::Subscriber (&FontDemo::handlePointSize, this));

        return true;
	}

    // method to perform any required cleanup operations.
    void cleanupSample ()
    {
        // me? cleanup? what?
    }

    void setFontDesc ()
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();

        String s = f->getProperty ("Name");
        if (f->isPropertyPresent ("PointSize"))
            s += "." + f->getProperty ("PointSize");

        winMgr.getWindow("FontDemo/FontDesc")->setText (s);
    }

    bool handleFontSelection (const EventArgs& e)
    {
        Listbox *lbox = static_cast<Listbox*> (
            static_cast<const WindowEventArgs&> (e).window);

        if (lbox->getFirstSelectedItem ())
		{
            Font *f = FontManager::getSingleton ().getFont (
                lbox->getFirstSelectedItem ()->getText ());

            WindowManager& winMgr = WindowManager::getSingleton ();
            winMgr.getWindow("FontDemo/FontSample")->setFont (f);

            bool b = f->isPropertyPresent ("AutoScaled");
            Checkbox *cb = static_cast<Checkbox *> (winMgr.getWindow("FontDemo/AutoScaled"));
            cb->setEnabled (b);
            if (b)
                cb->setSelected (PropertyHelper::stringToBool (f->getProperty ("AutoScaled")));

            b = f->isPropertyPresent ("Antialiased");
            cb = static_cast<Checkbox *> (winMgr.getWindow("FontDemo/Antialiased"));
            cb->setEnabled (b);
            if (b)
                cb->setSelected (PropertyHelper::stringToBool (f->getProperty ("Antialiased")));

            b = f->isPropertyPresent ("PointSize");
            Scrollbar *sb = static_cast<Scrollbar *> (
                winMgr.getWindow("FontDemo/PointSize"));
            sb->setEnabled (b);
            if (b)
                sb->setScrollPosition (
                    PropertyHelper::stringToFloat (f->getProperty ("PointSize")) - MIN_POINT_SIZE);

            setFontDesc ();
		}

        return true;
    }

    bool handleAutoScaled (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Checkbox *cb = static_cast<Checkbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();
        f->setProperty ("AutoScaled",
                        PropertyHelper::boolToString (cb->isSelected ()));

        return true;
    }

    bool handleAntialiased (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Checkbox *cb = static_cast<Checkbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        MultiLineEditbox *mle = static_cast<MultiLineEditbox *>
            (winMgr.getWindow("FontDemo/FontSample"));

        Font *f = mle->getFont ();
        f->setProperty ("Antialiased",
                        PropertyHelper::boolToString (cb->isSelected ()));

        return true;
    }

    bool handlePointSize (const EventArgs& e)
    {
        WindowManager& winMgr = WindowManager::getSingleton ();

        Scrollbar *sb = static_cast<Scrollbar *> (
            static_cast<const WindowEventArgs&> (e).window);

        Font *f = winMgr.getWindow ("FontDemo/FontSample")->getFont ();

        f->setProperty ("PointSize",
                        PropertyHelper::intToString (
                            int (MIN_POINT_SIZE + sb->getScrollPosition ())));

        setFontDesc ();

        return true;
    }

    bool handleLangSelection (const EventArgs& e)
    {
        Listbox *lbox = static_cast<Listbox *> (
            static_cast<const WindowEventArgs&> (e).window);

        if (lbox->getFirstSelectedItem ())
        {
            size_t idx = lbox->getItemIndex (lbox->getFirstSelectedItem ());
            WindowManager& winMgr = WindowManager::getSingleton ();
            winMgr.getWindow ("FontDemo/FontSample")->setText (LangList [idx].Text);
        }

        return true;
    }
};

int main(int argc, char *argv[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FontDemo app;
    return app.run ();
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// 	Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
//
// 	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.
#include <MTConfig.h>
#include <MTAppInterop.h>
#include <MTTools.h>

#include <stdio.h>

#if MT_SSE_INTRINSICS_SUPPORTED
#include <xmmintrin.h>
#else
#include <malloc.h>
#endif

#if MT_PLATFORM_WINDOWS

inline void ThrowException()
{
	__debugbreak();
}

#elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX

#define _DARWIN_C_SOURCE
#include<signal.h>
inline void ThrowException()
{
	raise(SIGTRAP);
	// force access violation error
	char* pBadAddr = (char*)0x0;
	*pBadAddr = 0;
}

#else

#error Platform is not supported!

#endif

namespace MT
{

	void* Memory::Alloc(size_t size, size_t align)
	{
		void* p = nullptr;
#if MT_SSE_INTRINSICS_SUPPORTED
		p = _mm_malloc(size, align);
#else
		p = memalign(size, align);
#endif
		MT_ASSERT(p, "Can't allocate memory");
		return p;
	}

	void Memory::Free(void* p)
	{
#if MT_SSE_INTRINSICS_SUPPORTED
		_mm_free(p);
#else
		free(p);
#endif
	}

	Memory::StackDesc Memory::AllocStack(size_t size)
	{
		StackDesc desc;

#if MT_PLATFORM_WINDOWS

		MW_SYSTEM_INFO systemInfo;
		GetSystemInfo(&systemInfo);

		int pageSize = (int)systemInfo.dwPageSize;
		int pagesCount = (int)size / pageSize;

		//need additional page for stack guard
		if ((size % pageSize) > 0)
		{
			pagesCount++;
		}

		//protected guard page
		pagesCount++;

		desc.stackMemoryBytesCount = pagesCount * pageSize;
		desc.stackMemory = (char*)VirtualAlloc(NULL, desc.stackMemoryBytesCount, MW_MEM_COMMIT, MW_PAGE_READWRITE);
		MT_ASSERT(desc.stackMemory != NULL, "Can't allocate memory");

		desc.stackBottom = desc.stackMemory + pageSize;
		desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount;

		MW_DWORD oldProtect = 0;
		MW_BOOL res = VirtualProtect(desc.stackMemory, pageSize, MW_PAGE_NOACCESS, &oldProtect);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res != 0, "Can't protect memory");

#elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX

		int pageSize = sysconf(_SC_PAGE_SIZE);
		int pagesCount = size / pageSize;

		//need additional page for stack tail
		if ((size % pageSize) > 0)
		{
			pagesCount++;
		}

		//protected guard page
		pagesCount++;

		desc.stackMemoryBytesCount = pagesCount * pageSize;
		desc.stackMemory = (char*)mmap(NULL, desc.stackMemoryBytesCount, PROT_READ | PROT_WRITE,  MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);

		MT_ASSERT((void *)desc.stackMemory != (void *)-1, "Can't allocate memory");

		desc.stackBottom = desc.stackMemory + pageSize;
		desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount;

		int res = mprotect(desc.stackMemory, pageSize, PROT_NONE);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res == 0, "Can't protect memory");
#else
		#error Platform is not supported!
#endif

		return desc;
	}

	void Memory::FreeStack(const Memory::StackDesc & desc)
	{
#if MT_PLATFORM_WINDOWS

		int res = VirtualFree(desc.stackMemory, 0, MW_MEM_RELEASE);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res != 0, "Can't free memory");

#elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX

		int res = munmap(desc.stackMemory, desc.stackMemoryBytesCount);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res == 0, "Can't free memory");
#else
		#error Platform is not supported!
#endif
	}

	void Diagnostic::ReportAssert(const char* condition, const char* description, const char* sourceFile, int sourceLine)
	{
		printf("Assertion failed : %s. File %s, line %d. Condition %s\n", description, sourceFile, sourceLine, condition);
		ThrowException();
	}

}
<commit_msg>Fixed OSX compilation<commit_after>// The MIT License (MIT)
//
// 	Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
//
// 	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.
#include <MTConfig.h>
#include <MTAppInterop.h>
#include <MTTools.h>

#include <stdio.h>

#if MT_SSE_INTRINSICS_SUPPORTED
#include <xmmintrin.h>
#else
#include <malloc.h>
#endif

#if MT_PLATFORM_WINDOWS

inline void ThrowException()
{
	__debugbreak();
}

#elif MT_PLATFORM_POSIX

#include<signal.h>
inline void ThrowException()
{
	raise(SIGTRAP);
	// force access violation error
	char* pBadAddr = (char*)0x0;
	*pBadAddr = 0;
}

#elif MT_PLATFORM_OSX

inline void ThrowException()
{
	__builtin_trap();
}

#else

#error Platform is not supported!

#endif

namespace MT
{

	void* Memory::Alloc(size_t size, size_t align)
	{
		void* p = nullptr;
#if MT_SSE_INTRINSICS_SUPPORTED
		p = _mm_malloc(size, align);
#else
		p = memalign(size, align);
#endif
		MT_ASSERT(p, "Can't allocate memory");
		return p;
	}

	void Memory::Free(void* p)
	{
#if MT_SSE_INTRINSICS_SUPPORTED
		_mm_free(p);
#else
		free(p);
#endif
	}

	Memory::StackDesc Memory::AllocStack(size_t size)
	{
		StackDesc desc;

#if MT_PLATFORM_WINDOWS

		MW_SYSTEM_INFO systemInfo;
		GetSystemInfo(&systemInfo);

		int pageSize = (int)systemInfo.dwPageSize;
		int pagesCount = (int)size / pageSize;

		//need additional page for stack guard
		if ((size % pageSize) > 0)
		{
			pagesCount++;
		}

		//protected guard page
		pagesCount++;

		desc.stackMemoryBytesCount = pagesCount * pageSize;
		desc.stackMemory = (char*)VirtualAlloc(NULL, desc.stackMemoryBytesCount, MW_MEM_COMMIT, MW_PAGE_READWRITE);
		MT_ASSERT(desc.stackMemory != NULL, "Can't allocate memory");

		desc.stackBottom = desc.stackMemory + pageSize;
		desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount;

		MW_DWORD oldProtect = 0;
		MW_BOOL res = VirtualProtect(desc.stackMemory, pageSize, MW_PAGE_NOACCESS, &oldProtect);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res != 0, "Can't protect memory");

#elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX

		int pageSize = sysconf(_SC_PAGE_SIZE);
		int pagesCount = size / pageSize;

		//need additional page for stack tail
		if ((size % pageSize) > 0)
		{
			pagesCount++;
		}

		//protected guard page
		pagesCount++;

		desc.stackMemoryBytesCount = pagesCount * pageSize;
		desc.stackMemory = (char*)mmap(NULL, desc.stackMemoryBytesCount, PROT_READ | PROT_WRITE,  MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);

		MT_ASSERT((void *)desc.stackMemory != (void *)-1, "Can't allocate memory");

		desc.stackBottom = desc.stackMemory + pageSize;
		desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount;

		int res = mprotect(desc.stackMemory, pageSize, PROT_NONE);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res == 0, "Can't protect memory");
#else
		#error Platform is not supported!
#endif

		return desc;
	}

	void Memory::FreeStack(const Memory::StackDesc & desc)
	{
#if MT_PLATFORM_WINDOWS

		int res = VirtualFree(desc.stackMemory, 0, MW_MEM_RELEASE);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res != 0, "Can't free memory");

#elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX

		int res = munmap(desc.stackMemory, desc.stackMemoryBytesCount);
		MT_USED_IN_ASSERT(res);
		MT_ASSERT(res == 0, "Can't free memory");
#else
		#error Platform is not supported!
#endif
	}

	void Diagnostic::ReportAssert(const char* condition, const char* description, const char* sourceFile, int sourceLine)
	{
		printf("Assertion failed : %s. File %s, line %d. Condition %s\n", description, sourceFile, sourceLine, condition);
		ThrowException();
	}

}
<|endoftext|>


<commit_before>/*************************************************************************/
/*                          ScreenList.cpp                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           Xenro Engine                                */
/*             https://github.com/Jmiller7023/Xenro-Engine               */
/*************************************************************************/
/*                 Copyright  11-3-2017 Joseph Miller.                   */
/*                                                                       */
/* 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.                */
/*************************************************************************/

#include "ScreenList.h"
#include "IScreen.h"
#include "Errormessages.h"

namespace Xenro{

ScreenList::ScreenList(Game* game)
	:m_game(game)
{
	//Empty
}

ScreenList::~ScreenList() {
	destroyScreen();
}

IScreen* ScreenList::moveNext() {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = currScreen->getNextScreenIndex();
		return getCurrScreen();
	}
	//There was no next screen so return nullptr.
	return nullptr;
}

IScreen* ScreenList::movePrevious() {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = currScreen->getPrevScrenIndex();
		return getCurrScreen();
	}

	//There was no next screen so return nullptr.
	return nullptr;
}

IScreen* ScreenList::moveToParticular(int nextScreen) {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = nextScreen;
		return getCurrScreen();
	}

	//There was no next screen so return nullptr.
	return nullptr;

}

void ScreenList::setScreen(int nextScreen) {
	m_currScreenIndex = nextScreen;
}

void ScreenList::addScreen(IScreen* newScreen) {

	//Error checking
	if (newScreen == nullptr) {
		fatalError("Forgot to initialize screen!");
	}

	newScreen->m_screenIndex = m_screens.size();
	m_screens.push_back(newScreen);
	newScreen->create();
	newScreen->setGame(m_game);
}

void ScreenList::destroyScreen() {
	for (size_t i = 0; i < m_screens.size(); i++) {
		m_screens[i]->destroy();
		delete m_screens[i];
		m_screens[i] = nullptr;
	}
	m_screens.resize(0);
	m_currScreenIndex = NO_CURRENT_SCREEN_INDEX;
}

void ScreenList::destroyScreen(int screen) {
	if (screen > 0 && (size_t)screen < m_screens.size()) {
		std::swap(m_screens[screen], m_screens.back());
		delete m_screens[(int)m_screens.size() - 1];
		m_screens.pop_back();
	}

	warning("Passed in invalid screen index");
}

IScreen* ScreenList::getCurrScreen() {

	if(m_currScreenIndex != NO_CURRENT_SCREEN_INDEX){
		return m_screens[m_currScreenIndex];
	}

	fatalError("Forgot to initialize screen!");
	return nullptr;
}

}<commit_msg>Made it so that the game was set in each screen before create was called.<commit_after>/*************************************************************************/
/*                          ScreenList.cpp                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           Xenro Engine                                */
/*             https://github.com/Jmiller7023/Xenro-Engine               */
/*************************************************************************/
/*                 Copyright  11-3-2017 Joseph Miller.                   */
/*                                                                       */
/* 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.                */
/*************************************************************************/

#include "ScreenList.h"
#include "IScreen.h"
#include "Errormessages.h"

namespace Xenro{

ScreenList::ScreenList(Game* game)
	:m_game(game)
{
	//Empty
}

ScreenList::~ScreenList() {
	destroyScreen();
}

IScreen* ScreenList::moveNext() {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = currScreen->getNextScreenIndex();
		return getCurrScreen();
	}
	//There was no next screen so return nullptr.
	return nullptr;
}

IScreen* ScreenList::movePrevious() {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = currScreen->getPrevScrenIndex();
		return getCurrScreen();
	}

	//There was no next screen so return nullptr.
	return nullptr;
}

IScreen* ScreenList::moveToParticular(int nextScreen) {

	IScreen* currScreen = getCurrScreen();
	if (currScreen->getScreenIndex() != NO_CURRENT_SCREEN_INDEX) {
		m_currScreenIndex = nextScreen;
		return getCurrScreen();
	}

	//There was no next screen so return nullptr.
	return nullptr;

}

void ScreenList::setScreen(int nextScreen) {
	m_currScreenIndex = nextScreen;
}

void ScreenList::addScreen(IScreen* newScreen) {

	//Error checking
	if (newScreen == nullptr) {
		fatalError("Forgot to initialize screen!");
	}

	newScreen->setGame(m_game);
	newScreen->m_screenIndex = m_screens.size();
	m_screens.push_back(newScreen);
	newScreen->create();
}

void ScreenList::destroyScreen() {
	for (size_t i = 0; i < m_screens.size(); i++) {
		m_screens[i]->destroy();
		delete m_screens[i];
		m_screens[i] = nullptr;
	}
	m_screens.resize(0);
	m_currScreenIndex = NO_CURRENT_SCREEN_INDEX;
}

void ScreenList::destroyScreen(int screen) {
	if (screen > 0 && (size_t)screen < m_screens.size()) {
		std::swap(m_screens[screen], m_screens.back());
		delete m_screens[(int)m_screens.size() - 1];
		m_screens.pop_back();
	}

	warning("Passed in invalid screen index");
}

IScreen* ScreenList::getCurrScreen() {

	if(m_currScreenIndex != NO_CURRENT_SCREEN_INDEX){
		return m_screens[m_currScreenIndex];
	}

	fatalError("Forgot to initialize screen!");
	return nullptr;
}

}<|endoftext|>


<commit_before>/* The MIT License

   Copyright (c) 2014 Adrian Tan <atks@umich.edu>

   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.
*/

#include "profile_mendel_errors.h"

namespace
{

class Igor : Program
{
    public:

    std::string version;

    ///////////
    //options//
    ///////////
    std::string input_vcf_file;
    std::string input_ped_file;
    std::string ref_fasta_file;
    std::vector<GenomeInterval> intervals;
    std::string interval_list;
    int32_t min_depth;
    float_t min_gq;

    ///////
    //i/o//
    ///////
    BCFOrderedReader *odr;

    ///////////////
    //general use//
    ///////////////
    kstring_t variant;

    /////////
    //stats//
    /////////
    uint32_t no_trios;
    uint32_t no_variants;

    uint32_t no_00;
    uint32_t no_00_00;
    uint32_t no_00_01;
    uint32_t no_00_11;

    uint32_t no_11;
    uint32_t no_11_00;
    uint32_t no_11_01;
    uint32_t no_11_11;

    int32_t trio_genotypes[3][3][3];

    /////////
    //tools//
    /////////
    Pedigree *pedigree;
    VariantManip *vm;

    Igor(int argc, char ** argv)
    {
        //////////////////////////
        //options initialization//
        //////////////////////////
        try
        {
            std::string desc = "Profile Mendel Errors.";

            version = "0.5";
            TCLAP::CmdLine cmd(desc, ' ', version);
            VTOutput my; cmd.setOutput(&my);
            TCLAP::ValueArg<std::string> arg_intervals("i", "i", "intervals", false, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_interval_list("I", "I", "file containing list of intervals []", false, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_input_ped_file("p", "p", "pedigree file", true, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_ref_fasta_file("r", "r", "reference sequence fasta file []", true, "", "str", cmd);
            TCLAP::ValueArg<int32_t> arg_min_depth("d", "d", "minimum depth", false, 5, "str", cmd);
            TCLAP::ValueArg<float> arg_min_gq("q", "q", "minimum genotype quality", false, 2, "str", cmd);

            TCLAP::UnlabeledValueArg<std::string> arg_input_vcf_file("<in.vcf>", "input VCF file", true, "","file", cmd);

            cmd.parse(argc, argv);

            input_vcf_file = arg_input_vcf_file.getValue();
            input_ped_file = arg_input_ped_file.getValue();
            min_depth = arg_min_depth.getValue();
            min_gq = arg_min_gq.getValue();
            parse_intervals(intervals, arg_interval_list.getValue(), arg_intervals.getValue());
        }
        catch (TCLAP::ArgException &e)
        {
            std::cerr << "error: " << e.error() << " for arg " << e.argId() << "\n";
            abort();
        }
    };

    void initialize()
    {
        //////////////////////
        //i/o initialization//
        //////////////////////
        odr = new BCFOrderedReader(input_vcf_file, intervals);

        ///////////////////////////
        //ped file initialization//
        ///////////////////////////
        pedigree = new Pedigree(input_ped_file);

        ///////////////
        //general use//
        ///////////////
        variant = {0,0,0};

        ////////////////////////
        //stats initialization//
        ////////////////////////
        no_trios = 0;
        no_variants = 0;

        for (int32_t i=0; i<3; ++i)
        {
            for (int32_t j=0; j<3; ++j)
            {
                for (int32_t k=0; k<3; ++k)
                {
                    trio_genotypes[i][j][k] = 0;
                }
            }
        }

        /////////
        //tools//
        /////////
        vm = new VariantManip(ref_fasta_file);
    }

    void profile_mendel_errors()
    {
        bcf_hdr_t *h = odr->hdr;
        bcf1_t *v = bcf_init1();

        Variant variant;

        std::vector<Trio>& trios = pedigree->trios;
        no_trios = trios.size();

        int32_t missing = 0;
        int32_t mendel_homalt_err = 0;

        while(odr->read(v))
        {
            bcf_unpack(v, BCF_UN_STR);
            int32_t vtype = vm->classify_variant(odr->hdr, v, variant);

            if (bcf_get_n_allele(v)!=2 || abs(variant.alleles[0].dlen)==1)
            {
                continue;
            }

            int32_t *gts = NULL;
            int32_t n = 0;
            int k = bcf_get_genotypes(h, v, &gts, &n);

            int32_t *pls = NULL;
            n = 0;
            k = bcf_get_format_int(h, v, "PL", &pls, &n);

            bool variant_used = false;
            int32_t pl[3];

            for (int32_t i =0; i< trios.size(); ++i)
            {
                int32_t j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].father.c_str());
                int32_t f1 = bcf_gt_allele(gts[j*2]);
                int32_t f2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                if ((f1+f2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (f1+f2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (f1+f2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    f1 = -1;
//                    f2 = -1;
//                }

                j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].mother.c_str());
                int32_t m1 = bcf_gt_allele(gts[j*2]);
                int32_t m2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                if ((m1+m2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (m1+m2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (m1+m2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    m1 = -1;
//                    m2 = -1;
//                }

                j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].child.c_str());
                int32_t c1 = bcf_gt_allele(gts[j*2]);
                int32_t c2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                 if ((c1+c2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (c1+c2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (c1+c2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    c1 = -1;
//                    c2 = -1;
//                }

                if (!(f1<0 || f2<0 || m1<0 || m2<0 || c1<0 || c2<0))
                {
                    printf("%d/%d %d/%d %d/%d\n", f1,f2,m1,m2,c1,c2);
                    ++trio_genotypes[f1+f2][m1+m2][c1+c2];

                    variant_used = true;
                }
            }
            ++no_variants;

            free(gts);
//            free(dps);
//            free(pls);
        }

        odr->close();
    };

    void print_options()
    {
        std::clog << "merge_candidate_variants v" << version << "\n\n";
        std::clog << "options:     input VCF file        " << input_vcf_file << "\n";
        std::clog << "         [p] input PED file        " << input_ped_file << "\n";
        print_ref_op("         [r] ref FASTA file        ", ref_fasta_file);
        print_int_op("         [i] intervals             ", intervals);
        std::clog << "\n";
    }

    float get_error_rate(int32_t ***gt, int32_t f, int32_t m)
    {
        float total = gt[f][m][0] + gt[f][m][1] + gt[f][m][2];
        float error_count = 0;
        if (f==0 && m==0)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][2];
        }
        else if (f==0 && m==2)
        {
            error_count = gt[f][m][0] + gt[f][m][2];
        }
        else if (f==1 && m==0)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        else if (f==0 && m==1)
        {
            error_count = gt[f][m][1] + gt[f][m][2];
        }
        return 1;
    };

    void print_stats()
    {
        fprintf(stderr, "\n");
        fprintf(stderr, "  Mendelian Errors\n");
        std::string g2s[3] = {"R/R","R/A","A/A"};

        fprintf(stderr, "              R/R     R/A    A/A       Total\n");
        for (int32_t i=0; i<3; ++i)
        {
            for (int32_t j=0; j<3; ++j)
            {
                fprintf(stderr, "  %s %s   %5d   %5d  %5d \n", g2s[i].c_str(), g2s[j].c_str(), trio_genotypes[i][j][0], trio_genotypes[i][j][1], trio_genotypes[i][j][2]);
            }
        }
        fprintf(stderr, "\n");
        fprintf(stderr, "  no. of trios     : %d\n", no_trios);
        fprintf(stderr, "  no. of variants  : %d\n", no_variants);
        fprintf(stderr, "\n");
    };

    ~Igor()
    {
    };

    private:
};

}

void profile_mendel_errors(int argc, char ** argv)
{
    Igor igor(argc, argv);
    igor.print_options();
    igor.initialize();
    igor.profile_mendel_errors();
    igor.print_stats();
}

<commit_msg>added a collapsed table for mendelian errors<commit_after>/* The MIT License

   Copyright (c) 2014 Adrian Tan <atks@umich.edu>

   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.
*/

#include "profile_mendel_errors.h"

namespace
{

class Igor : Program
{
    public:

    std::string version;

    ///////////
    //options//
    ///////////
    std::string input_vcf_file;
    std::string input_ped_file;
    std::string ref_fasta_file;
    std::vector<GenomeInterval> intervals;
    std::string interval_list;
    int32_t min_depth;
    float_t min_gq;

    ///////
    //i/o//
    ///////
    BCFOrderedReader *odr;

    ///////////////
    //general use//
    ///////////////
    kstring_t variant;

    /////////
    //stats//
    /////////
    uint32_t no_trios;
    uint32_t no_variants;

    uint32_t no_00;
    uint32_t no_00_00;
    uint32_t no_00_01;
    uint32_t no_00_11;

    uint32_t no_11;
    uint32_t no_11_00;
    uint32_t no_11_01;
    uint32_t no_11_11;

    int32_t trio_genotypes[3][3][3];

    /////////
    //tools//
    /////////
    Pedigree *pedigree;
    VariantManip *vm;

    Igor(int argc, char ** argv)
    {
        //////////////////////////
        //options initialization//
        //////////////////////////
        try
        {
            std::string desc = "Profile Mendel Errors.";

            version = "0.5";
            TCLAP::CmdLine cmd(desc, ' ', version);
            VTOutput my; cmd.setOutput(&my);
            TCLAP::ValueArg<std::string> arg_intervals("i", "i", "intervals", false, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_interval_list("I", "I", "file containing list of intervals []", false, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_input_ped_file("p", "p", "pedigree file", true, "", "str", cmd);
            TCLAP::ValueArg<std::string> arg_ref_fasta_file("r", "r", "reference sequence fasta file []", true, "", "str", cmd);
            TCLAP::ValueArg<int32_t> arg_min_depth("d", "d", "minimum depth", false, 5, "str", cmd);
            TCLAP::ValueArg<float> arg_min_gq("q", "q", "minimum genotype quality", false, 2, "str", cmd);

            TCLAP::UnlabeledValueArg<std::string> arg_input_vcf_file("<in.vcf>", "input VCF file", true, "","file", cmd);

            cmd.parse(argc, argv);

            input_vcf_file = arg_input_vcf_file.getValue();
            input_ped_file = arg_input_ped_file.getValue();
            min_depth = arg_min_depth.getValue();
            min_gq = arg_min_gq.getValue();
            parse_intervals(intervals, arg_interval_list.getValue(), arg_intervals.getValue());
        }
        catch (TCLAP::ArgException &e)
        {
            std::cerr << "error: " << e.error() << " for arg " << e.argId() << "\n";
            abort();
        }
    };

    void initialize()
    {
        //////////////////////
        //i/o initialization//
        //////////////////////
        odr = new BCFOrderedReader(input_vcf_file, intervals);

        ///////////////////////////
        //ped file initialization//
        ///////////////////////////
        pedigree = new Pedigree(input_ped_file);

        ///////////////
        //general use//
        ///////////////
        variant = {0,0,0};

        ////////////////////////
        //stats initialization//
        ////////////////////////
        no_trios = 0;
        no_variants = 0;

        for (int32_t i=0; i<3; ++i)
        {
            for (int32_t j=0; j<3; ++j)
            {
                for (int32_t k=0; k<3; ++k)
                {
                    trio_genotypes[i][j][k] = 0;
                }
            }
        }

        /////////
        //tools//
        /////////
        vm = new VariantManip(ref_fasta_file);
    }

    void profile_mendel_errors()
    {
        bcf_hdr_t *h = odr->hdr;
        bcf1_t *v = bcf_init1();

        Variant variant;

        std::vector<Trio>& trios = pedigree->trios;
        no_trios = trios.size();

        int32_t missing = 0;
        int32_t mendel_homalt_err = 0;

        while(odr->read(v))
        {
            bcf_unpack(v, BCF_UN_STR);
            int32_t vtype = vm->classify_variant(odr->hdr, v, variant);

            if (bcf_get_n_allele(v)!=2 || abs(variant.alleles[0].dlen)==1)
            {
                continue;
            }

            int32_t *gts = NULL;
            int32_t n = 0;
            int k = bcf_get_genotypes(h, v, &gts, &n);

            int32_t *pls = NULL;
            n = 0;
            k = bcf_get_format_int(h, v, "PL", &pls, &n);

            bool variant_used = false;
            int32_t pl[3];

            for (int32_t i =0; i< trios.size(); ++i)
            {
                int32_t j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].father.c_str());
                int32_t f1 = bcf_gt_allele(gts[j*2]);
                int32_t f2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                if ((f1+f2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (f1+f2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (f1+f2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    f1 = -1;
//                    f2 = -1;
//                }

                j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].mother.c_str());
                int32_t m1 = bcf_gt_allele(gts[j*2]);
                int32_t m2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                if ((m1+m2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (m1+m2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (m1+m2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    m1 = -1;
//                    m2 = -1;
//                }

                j = bcf_hdr_id2int(h, BCF_DT_SAMPLE, trios[i].child.c_str());
                int32_t c1 = bcf_gt_allele(gts[j*2]);
                int32_t c2 = bcf_gt_allele(gts[j*2+1]);
//                pl[0] = pls[j*3];
//                pl[1] = pls[j*3+1];
//                pl[2] = pls[j*3+2];
//
//                 if ((c1+c2==0 && (pl[1]<10 || pl[2]<10)) ||
//                    (c1+c2==1 && (pl[0]<10 || pl[2]<10)) ||
//                    (c1+c2==2 && (pl[0]<10 || pl[1]<10)) )
//                {
//                    c1 = -1;
//                    c2 = -1;
//                }

                if (!(f1<0 || f2<0 || m1<0 || m2<0 || c1<0 || c2<0))
                {
                    //printf("%d/%d %d/%d %d/%d\n", f1,f2,m1,m2,c1,c2);
                    ++trio_genotypes[f1+f2][m1+m2][c1+c2];

                    variant_used = true;
                }
            }
            if (variant_used) ++no_variants;

            free(gts);
//            free(dps);
//            free(pls);
        }

        odr->close();
    };

    void print_options()
    {
        std::clog << "merge_candidate_variants v" << version << "\n\n";
        std::clog << "options:     input VCF file        " << input_vcf_file << "\n";
        std::clog << "         [p] input PED file        " << input_ped_file << "\n";
        print_ref_op("         [r] ref FASTA file        ", ref_fasta_file);
        print_int_op("         [i] intervals             ", intervals);
        std::clog << "\n";
    }

    float get_error_rate(int32_t gt[3][3][3], int32_t f, int32_t m, bool collapse)
    {
        float total = gt[f][m][0] + gt[f][m][1] + gt[f][m][2];
        float error_count = 0;
        if (f==m && f!=1)//0/0,2/2
        {
            error_count = gt[f][m][1] + gt[f][m][2-f];
        }
        else if (abs(f-m)==2) //0/2,2/0
        {
            error_count = gt[f][m][0] + gt[f][m][2];
            if (collapse)
            {
                total += gt[m][f][0] + gt[m][f][1] + gt[m][f][2];
                error_count += gt[m][f][0] + gt[m][f][2];
            }
        }
        else if (abs(f-m)==1)//1/2,2/1,1/0,0/1
        {
            error_count = gt[f][m][f==1?2-m:2-f];
            if (collapse)
            {
                total += gt[m][f][0] + gt[m][f][1] + gt[m][f][2];
                error_count += gt[m][f][f==1?2-m:2-f];
            }
        }
        else if (f==1 && m==1)//1/1
        {
            error_count = 0;
        }

        return error_count/total*100;
    };

    float get_homhet_ratio(int32_t gt[3][3][3], int32_t f, int32_t m, bool collapse)
    {
        float hom = 0;
        float het = 0;
        if (f==m && f!=1)//0/0,2/2
        {

        }
        else if (abs(f-m)==2) //0/2,2/0
        {

        }
        else if (abs(f-m)==1)//1/2,2/1,1/0,0/1
        {
            hom = gt[f][m][f==1?m:f];
            het = gt[f][m][1];
            if (collapse)
            {
                hom += gt[m][f][f==1?m:f];
                het += gt[m][f][1];
            }
        }
        else if (f==1 && m==1)//1/1
        {
            hom = gt[f][m][0]+gt[f][m][2];
            het = gt[f][m][1];
        }

        return hom/het;
    };

    void print_stats()
    {
        std::string g2s[3] = {"R/R","R/A","A/A"};

        fprintf(stderr, "\n");
        fprintf(stderr, "     Mendelian Errors\n");
        fprintf(stderr, "\n");
        fprintf(stderr, "     Father Mother       R/R          R/A          A/A   Error(%%) HomHet\n");
        for (int32_t i=0; i<3; ++i)
        {
            for (int32_t j=0; j<3; ++j)
            {
                fprintf(stderr, "     %s    %s   %10d   %10d   %10d   %5.2f      %4.2f\n", g2s[i].c_str(), g2s[j].c_str(), trio_genotypes[i][j][0], trio_genotypes[i][j][1], trio_genotypes[i][j][2], get_error_rate(trio_genotypes, i, j, false), get_homhet_ratio(trio_genotypes, i, j, false));
            }
        }
        fprintf(stderr, "\n");
        fprintf(stderr, "     Parental            R/R          R/A          A/A   Error(%%) HomHet\n");
        for (int32_t i=0; i<3; ++i)
        {
            for (int32_t j=0; j<3; ++j)
            {
                if (i!=j)
                {
                    if (i<j)
                    {
                        int32_t rr = trio_genotypes[i][j][0] + trio_genotypes[j][i][0];
                        int32_t ra = trio_genotypes[i][j][1] + trio_genotypes[j][i][1];
                        int32_t aa = trio_genotypes[i][j][2] + trio_genotypes[j][i][2];
                        fprintf(stderr, "     %s    %s   %10d   %10d   %10d   %5.2f      %4.2f\n", g2s[i].c_str(), g2s[j].c_str(), rr, ra, aa, get_error_rate(trio_genotypes, i, j, true), get_homhet_ratio(trio_genotypes, i, j, true));
                    }
                }
                else
                {
                    fprintf(stderr, "     %s    %s   %10d   %10d   %10d   %5.2f      %4.2f\n", g2s[i].c_str(), g2s[j].c_str(), trio_genotypes[i][j][0], trio_genotypes[i][j][1], trio_genotypes[i][j][2], get_error_rate(trio_genotypes, i, j, true), get_homhet_ratio(trio_genotypes, i, j, true));
                }
            }
        }
        fprintf(stderr, "\n");
        fprintf(stderr, "  no. of trios     : %d\n", no_trios);
        fprintf(stderr, "  no. of variants  : %d\n", no_variants);
        fprintf(stderr, "\n");
    };

    ~Igor()
    {
    };

    private:
};

}

void profile_mendel_errors(int argc, char ** argv)
{
    Igor igor(argc, argv);
    igor.print_options();
    igor.initialize();
    igor.profile_mendel_errors();
    igor.print_stats();
}

<|endoftext|>