<commit_before>/******************************************************************************
 *   Copyright (c) 2012 <NAME> <<EMAIL>> *
 *                                                                            *
 *   This file is part of the FreeCAD CAx development system.                 *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or            *
 *   modify it under the terms of the GNU Library General Public              *
 *   License as published by the Free Software Foundation; either             *
 *   version 2 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 Library General Public License for more details.                     *
 *                                                                            *
 *   You should have received a copy of the GNU Library General Public        *
 *   License along with this library; see the file COPYING.LIB. If not,       *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,            *
 *   Suite 330, Boston, MA  02111-1307, USA                                   *
 *                                                                            *
 ******************************************************************************/


#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Lin.hxx>
# include <gp_Circ.hxx>
# include <gp_Ax2.hxx>
# include <BRepAdaptor_Curve.hxx>
#endif


#include "FeaturePolarPattern.h"
#include "DatumLine.h"
#include <Base/Axis.h>
#include <Base/Exception.h>
#include <Base/Tools.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/Part/App/Part2DObject.h>
#include <App/OriginFeature.h>

using namespace PartDesign;

namespace PartDesign {


PROPERTY_SOURCE(PartDesign::PolarPattern, PartDesign::Transformed)

const App::PropertyIntegerConstraint::Constraints intOccurrences = { 1, INT_MAX, 1 };
const App::PropertyAngle::Constraints floatAngle = { Base::toDegrees<double>(Precision::Angular()), 360.0, 1.0 };

PolarPattern::PolarPattern()
{
    ADD_PROPERTY_TYPE(Axis, (0), "PolarPattern", (App::PropertyType)(App::Prop_None), "Direction");
    ADD_PROPERTY(Reversed, (0));
    ADD_PROPERTY(Angle, (360.0));
    Angle.setConstraints(&floatAngle);
    ADD_PROPERTY(Occurrences, (3));
    Occurrences.setConstraints(&intOccurrences);
}

short PolarPattern::mustExecute() const
{
    if (Axis.isTouched() ||
        Reversed.isTouched() ||
        Angle.isTouched() ||
        Occurrences.isTouched())
        return 1;
    return Transformed::mustExecute();
}

const std::list<gp_Trsf> PolarPattern::getTransformations(const std::vector<App::DocumentObject*>)
{
    double angle = Angle.getValue();
    if (angle < Precision::Confusion())
        throw Base::ValueError("Pattern angle too small");
    int occurrences = Occurrences.getValue();
    if (occurrences < 1)
        throw Base::ValueError("At least one occurrence required");

    // Note: The original feature is NOT included in the list of transformations! Therefore
    // we start with occurrence number 1, not number 0
    std::list<gp_Trsf> transformations;
    gp_Trsf trans;
    transformations.push_back(trans); // identity transformation

    if (occurrences < 2)
        return transformations;

    bool reversed = Reversed.getValue();
    double offset;
    if (std::fabs(angle - 360.0) < Precision::Confusion())
        offset = Base::toRadians<double>(angle) / occurrences; // Because e.g. two occurrences in 360 degrees need to be 180 degrees apart
    else
        offset = Base::toRadians<double>(angle) / (occurrences - 1);

    App::DocumentObject* refObject = Axis.getValue();
    if (refObject == NULL)
        throw Base::ValueError("No axis reference specified");
    std::vector<std::string> subStrings = Axis.getSubValues();
    if (subStrings.empty())
        throw Base::ValueError("No axis reference specified");

    gp_Pnt axbase;
    gp_Dir axdir;
    if (refObject->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
        Part::Part2DObject* refSketch = static_cast<Part::Part2DObject*>(refObject);
        Base::Axis axis;
        if (subStrings[0] == "H_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::H_Axis);
        else if (subStrings[0] == "V_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::V_Axis);
        else if (subStrings[0] == "N_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::N_Axis);
        else if (subStrings[0].size() > 4 && subStrings[0].substr(0,4) == "Axis") {
            int AxId = std::atoi(subStrings[0].substr(4,4000).c_str());
            if (AxId >= 0 && AxId < refSketch->getAxisCount())
                axis = refSketch->getAxis(AxId);
        }
        axis *= refSketch->Placement.getValue();<commit_msg>PD: [skip ci] fix angle check in PolarPattern::getTransformations()<commit_after>/******************************************************************************
 *   Copyright (c) 2012 <NAME> <<EMAIL>> *
 *                                                                            *
 *   This file is part of the FreeCAD CAx development system.                 *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or            *
 *   modify it under the terms of the GNU Library General Public              *
 *   License as published by the Free Software Foundation; either             *
 *   version 2 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 Library General Public License for more details.                     *
 *                                                                            *
 *   You should have received a copy of the GNU Library General Public        *
 *   License along with this library; see the file COPYING.LIB. If not,       *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,            *
 *   Suite 330, Boston, MA  02111-1307, USA                                   *
 *                                                                            *
 ******************************************************************************/


#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Lin.hxx>
# include <gp_Circ.hxx>
# include <gp_Ax2.hxx>
# include <BRepAdaptor_Curve.hxx>
#endif


#include "FeaturePolarPattern.h"
#include "DatumLine.h"
#include <Base/Axis.h>
#include <Base/Exception.h>
#include <Base/Tools.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/Part/App/Part2DObject.h>
#include <App/OriginFeature.h>

using namespace PartDesign;

namespace PartDesign {


PROPERTY_SOURCE(PartDesign::PolarPattern, PartDesign::Transformed)

const App::PropertyIntegerConstraint::Constraints intOccurrences = { 1, INT_MAX, 1 };
const App::PropertyAngle::Constraints floatAngle = { Base::toDegrees<double>(Precision::Angular()), 360.0, 1.0 };

PolarPattern::PolarPattern()
{
    ADD_PROPERTY_TYPE(Axis, (0), "PolarPattern", (App::PropertyType)(App::Prop_None), "Direction");
    ADD_PROPERTY(Reversed, (0));
    ADD_PROPERTY(Angle, (360.0));
    Angle.setConstraints(&floatAngle);
    ADD_PROPERTY(Occurrences, (3));
    Occurrences.setConstraints(&intOccurrences);
}

short PolarPattern::mustExecute() const
{
    if (Axis.isTouched() ||
        Reversed.isTouched() ||
        Angle.isTouched() ||
        Occurrences.isTouched())
        return 1;
    return Transformed::mustExecute();
}

const std::list<gp_Trsf> PolarPattern::getTransformations(const std::vector<App::DocumentObject*>)
{
    double angle = Angle.getValue();
    double radians = Base::toRadians<double>(angle);
    if (radians < Precision::Angular())
        throw Base::ValueError("Pattern angle too small");
    int occurrences = Occurrences.getValue();
    if (occurrences < 1)
        throw Base::ValueError("At least one occurrence required");

    // Note: The original feature is NOT included in the list of transformations! Therefore
    // we start with occurrence number 1, not number 0
    std::list<gp_Trsf> transformations;
    gp_Trsf trans;
    transformations.push_back(trans); // identity transformation

    if (occurrences < 2)
        return transformations;

    bool reversed = Reversed.getValue();
    double offset;
    if (std::fabs(angle - 360.0) < Precision::Confusion())
        offset = radians / occurrences; // Because e.g. two occurrences in 360 degrees need to be 180 degrees apart
    else
        offset = radians / (occurrences - 1);

    App::DocumentObject* refObject = Axis.getValue();
    if (refObject == NULL)
        throw Base::ValueError("No axis reference specified");
    std::vector<std::string> subStrings = Axis.getSubValues();
    if (subStrings.empty())
        throw Base::ValueError("No axis reference specified");

    gp_Pnt axbase;
    gp_Dir axdir;
    if (refObject->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
        Part::Part2DObject* refSketch = static_cast<Part::Part2DObject*>(refObject);
        Base::Axis axis;
        if (subStrings[0] == "H_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::H_Axis);
        else if (subStrings[0] == "V_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::V_Axis);
        else if (subStrings[0] == "N_Axis")
            axis = refSketch->getAxis(Part::Part2DObject::N_Axis);
        else if (subStrings[0].size() > 4 && subStrings[0].substr(0,4) == "Axis") {
            int AxId = std::atoi(subStrings[0].substr(4,4000).c_str());
            if (AxId >= 0 && AxId < refSketch->getAxisCount())
                axis = refSketch->getAxis(AxId);
        }
        axis *= refSketch->Placement.getValue();
{'fraction_non_alphanumeric': 0.14122464527187886, 'fraction_numerical': 0.013903437767831634, 'mean_word_length': 2.4728835978835977, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2132306', 'n_tokens_mistral': 3001, 'n_tokens_neox': 2807, 'n_words': 753}