Merge remote-tracking branch 'upstream/main' into bim-cleanup-imports

This commit is contained in:
marcuspollio
2025-03-30 12:44:55 +02:00
807 changed files with 24639 additions and 19953 deletions
+2 -2
View File
@@ -106,9 +106,9 @@ jobs:
mkdir -p ${{ env.reportdir }}
echo "reportFile=${{ env.reportfilename }}" >> $GITHUB_OUTPUT
- uses: prefix-dev/[email protected].2
- uses: prefix-dev/[email protected].3
with:
pixi-version: v0.41.3
pixi-version: v0.43.3
cache: false
- name: Restore Compiler Cache
+3 -3
View File
@@ -1,8 +1,8 @@
# - Try to find Eigen3 lib
#
# This module supports requiring a minimum version, e.g. you can do
# find_package(Eigen3 3.1.2)
# to require version 3.1.2 or newer of Eigen3.
# find_package(Eigen3 3.4.0)
# to require version 3.4.0 or newer of Eigen3.
#
# Once done this will define
#
@@ -17,7 +17,7 @@
if(NOT Eigen3_FIND_VERSION)
set(Eigen3_FIND_VERSION_MAJOR 3)
set(Eigen3_FIND_VERSION_MINOR 0)
set(Eigen3_FIND_VERSION_MINOR 4)
set(Eigen3_FIND_VERSION_PATCH 0)
set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
endif(NOT Eigen3_FIND_VERSION)
@@ -178,7 +178,7 @@ macro(InitializeFreeCADBuildOptions)
endif(MSVC)
if(NOT MSVC)
option(BUILD_FEM_NETGEN "Build the FreeCAD FEM module with the NETGEN mesher" OFF)
option(FREECAD_USE_PCL "Build the features that use PCL libs" OFF)
option(FREECAD_USE_PCL "Build the features that use PCL libs" ON)
endif(NOT MSVC)
# if this is set override some options
+2 -11
View File
@@ -11,19 +11,10 @@ macro(SetupEigen)
"=================\n")
endif(NOT EIGEN3_FOUND)
if (EIGEN3_FOUND AND ${EIGEN3_VERSION} VERSION_LESS "3.3.1")
if (EIGEN3_FOUND AND ${EIGEN3_VERSION} VERSION_LESS "3.4.0")
message(WARNING "Disable module flatmesh because it requires "
"minimum Eigen3 version 3.3.1 but version ${EIGEN3_VERSION} was found")
"minimum Eigen3 version 3.4.0 but version ${EIGEN3_VERSION} was found")
set (BUILD_FLAT_MESH OFF)
endif()
# Older versions raise the warning -Wdeprecated-copy with clang10/gcc10
if (EIGEN3_FOUND AND ${EIGEN3_VERSION} VERSION_LESS "3.3.8")
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-deprecated-copy" _flag_found)
if (_flag_found)
set (EIGEN3_NO_DEPRECATED_COPY "-Wno-deprecated-copy")
endif ()
endif()
endmacro(SetupEigen)
+21 -9
View File
@@ -143,35 +143,47 @@ macro(generate_from_xml BASE_NAME)
)
endmacro(generate_from_xml)
macro(generate_from_py BASE_NAME)
macro(generate_from_py_impl BASE_NAME SUFFIX)
set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/bindings/generate.py")
file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.pyi" SOURCE_NATIVE_PATH)
set(SOURCE_CPP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.cpp" )
set(SOURCE_CPP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}Py${SUFFIX}.cpp")
set(SOURCE_H_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}Py${SUFFIX}.h")
# BASE_NAME may include also a path name
GET_FILENAME_COMPONENT(OUTPUT_PATH "${SOURCE_CPP_PATH}" PATH)
file(TO_NATIVE_PATH "${OUTPUT_PATH}" OUTPUT_NATIVE_PATH)
if(NOT EXISTS "${SOURCE_CPP_PATH}")
# assures the source files are generated at least once
# Ensure the source files are generated at least once.
message(STATUS "${SOURCE_CPP_PATH}")
execute_process(COMMAND "${Python3_EXECUTABLE}" "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMAND_ERROR_IS_FATAL ANY
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}_.h" "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}_.cpp"
OUTPUT "${SOURCE_H_PATH}" "${SOURCE_CPP_PATH}"
COMMAND ${Python3_EXECUTABLE} "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" ${BASE_NAME}.pyi
MAIN_DEPENDENCY "${BASE_NAME}.pyi"
DEPENDS
"${CMAKE_SOURCE_DIR}/src/Tools/bindings/templates/templateClassPyExport.py"
"${TOOL_PATH}"
"${CMAKE_SOURCE_DIR}/src/Tools/bindings/templates/templateClassPyExport.py"
"${TOOL_PATH}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Building ${BASE_NAME}.h/.cpp out of ${BASE_NAME}.pyi"
COMMENT "Building ${BASE_NAME}Py${SUFFIX}.h/.cpp out of ${BASE_NAME}.pyi"
)
endmacro(generate_from_py_impl)
macro(generate_from_py BASE_NAME)
generate_from_py_impl(${BASE_NAME} "")
endmacro(generate_from_py)
macro(generate_from_py_ BASE_NAME)
generate_from_py_impl(${BASE_NAME} "_")
endmacro(generate_from_py_)
macro(generate_embed_from_py BASE_NAME OUTPUT_FILE)
set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/PythonToCPP.py")
file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH)
+1
View File
@@ -33,6 +33,7 @@ packages=(
libocct-visualization-dev
libopencv-dev
libproj-dev
libpcl-dev
libpyside2-dev
libqt5opengl5-dev
libqt5svg5-dev
@@ -4218,7 +4218,7 @@ bool StdMeshers_Quadrangle_2D::check()
return isOK;
}
/*//================================================================================
//================================================================================
/*!
* \brief Finds vertices at the most sharp face corners
* \param [in] theFace - the FACE
+3 -2
View File
@@ -2045,6 +2045,7 @@ void Application::initTypes()
App::PropertyElectricalResistance ::init();
App::PropertyElectricCharge ::init();
App::PropertySurfaceChargeDensity ::init();
App::PropertyVolumeChargeDensity ::init();
App::PropertyElectricCurrent ::init();
App::PropertyElectricPotential ::init();
App::PropertyElectromagneticPotential ::init();
@@ -2635,8 +2636,8 @@ void Application::initConfig(int argc, char ** argv)
Py_DECREF(pyModule);
}
const char* pythonpath = Base::Interpreter().init(argc,argv);
if (pythonpath)
std::string pythonpath = Base::Interpreter().init(argc,argv);
if (!pythonpath.empty())
mConfig["PythonSearchPath"] = pythonpath;
else
Base::Console().Warning("Encoding of Python paths failed\n");
+5 -7
View File
@@ -33,10 +33,6 @@
#include "Datums.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
using namespace App;
PROPERTY_SOURCE(App::DatumElement, App::GeoFeature)
@@ -243,14 +239,16 @@ App::DocumentObjectExecReturn* LocalCoordinateSystem::execute()
const std::vector<LocalCoordinateSystem::SetupData>& LocalCoordinateSystem::getSetupData()
{
using std::numbers::pi;
static const std::vector<SetupData> setupData = {
// clang-format off
{App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation()},
{App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)},
{App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation(Base::Vector3d(1,-1, 1), M_PI * 2 / 3)},
{App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1, 1, 1), pi * 2 / 3)},
{App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation(Base::Vector3d(1,-1, 1), pi * 2 / 3)},
{App::Plane::getClassTypeId(), PlaneRoles[0], tr("XY-plane"), Base::Rotation()},
{App::Plane::getClassTypeId(), PlaneRoles[1], tr("XZ-plane"), Base::Rotation(1.0, 0.0, 0.0, 1.0)},
{App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)},
{App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1, 1, 1), pi * 2 / 3)},
{App::Point::getClassTypeId(), PointRoles[0], tr("Origin"), Base::Rotation()}
// clang-format on
};
-35
View File
@@ -20,41 +20,6 @@
* *
***************************************************************************/
/*!
\defgroup Document Document
\ingroup APP
\brief The Base class of the FreeCAD Document
This (besides the App::Application class) is the most important class in FreeCAD.
It contains all the data of the opened, saved, or newly created FreeCAD Document.
The App::Document manages the Undo and Redo mechanism and the linking of documents.
\namespace App \class App::Document
This is besides the Application class the most important class in FreeCAD
It contains all the data of the opened, saved or newly created FreeCAD Document.
The Document manage the Undo and Redo mechanism and the linking of documents.
Note: the documents are not free objects. They are completely handled by the
App::Application. Only the Application can Open or destroy a document.
\section Exception Exception handling
As the document is the main data structure of FreeCAD we have to take a close
look at how Exceptions affect the integrity of the App::Document.
\section UndoRedo Undo Redo an Transactions
Undo Redo handling is one of the major mechanism of a document in terms of
user friendliness and speed (no one will wait for Undo too long).
\section Dependency Graph and dependency handling
The FreeCAD document handles the dependencies of its DocumentObjects with
an adjacence list. This gives the opportunity to calculate the shortest
recompute path. Also, it enables more complicated dependencies beyond trees.
@see App::Application
@see App::DocumentObject
*/
#include "PreCompiled.h"
#ifndef _PreComp_
+5 -1
View File
@@ -57,7 +57,11 @@ class Transaction;
class StringHasher;
using StringHasherRef = Base::Reference<StringHasher>;
/// The document class
/**
* @brief The document class
* @ingroup DocumentGroup
* @details For a more high-level discussion see the topic @ref DocumentGroup "Document".
*/
class AppExport Document: public App::PropertyContainer
{
PROPERTY_HEADER_WITH_OVERRIDE(App::Document);
-4
View File
@@ -55,10 +55,6 @@ FC_LOG_LEVEL_INIT("App", true, true)
using namespace App;
/** \defgroup DocObject Document Object
\ingroup APP
\brief Base class of all objects handled in the Document
*/
PROPERTY_SOURCE(App::DocumentObject, App::TransactionalObject)
+4 -1
View File
@@ -101,7 +101,10 @@ public:
};
/** Base class of all Classes handled in the Document
/**
* @brief %Base class of all objects handled in the @ref App::Document "Document".
* @ingroup DocObject
* @details For a more high-level overview see topic @ref DocObject "Document Object".
*/
class AppExport DocumentObject: public App::TransactionalObject
{
+16 -30
View File
@@ -34,6 +34,8 @@
#include <boost/math/special_functions/round.hpp>
#include <boost/math/special_functions/trunc.hpp>
#include <numbers>
#include <limits>
#include <sstream>
#include <stack>
#include <string>
@@ -52,29 +54,11 @@
#include "ExpressionParser.h"
/** \defgroup Expression Expressions framework
\ingroup APP
\brief The expression system allows users to write expressions and formulas that produce values
*/
using namespace Base;
using namespace App;
FC_LOG_LEVEL_INIT("Expression", true, true)
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_E
#define M_E 2.71828182845904523536
#endif
#ifndef DOUBLE_MAX
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
#if defined(_MSC_VER)
#define strtoll _strtoi64
#pragma warning(disable : 4003)
@@ -336,22 +320,22 @@ static inline int essentiallyInteger(double a, long &l, int &i) {
double intpart;
if (std::modf(a,&intpart) == 0.0) {
if (intpart<0.0) {
if (intpart >= INT_MIN) {
if (intpart >= std::numeric_limits<int>::min()) {
i = static_cast<int>(intpart);
l = i;
return 1;
}
if (intpart >= LONG_MIN) {
if (intpart >= std::numeric_limits<long>::min()) {
l = static_cast<long>(intpart);
return 2;
}
}
else if (intpart <= INT_MAX) {
else if (intpart <= std::numeric_limits<int>::max()) {
i = static_cast<int>(intpart);
l = i;
return 1;
}
else if (intpart <= static_cast<double>(LONG_MAX)) {
else if (intpart <= static_cast<double>(std::numeric_limits<long>::max())) {
l = static_cast<int>(intpart);
return 2;
}
@@ -363,12 +347,12 @@ static inline bool essentiallyInteger(double a, long &l) {
double intpart;
if (std::modf(a,&intpart) == 0.0) {
if (intpart<0.0) {
if (intpart >= LONG_MIN) {
if (intpart >= std::numeric_limits<long>::min()) {
l = static_cast<long>(intpart);
return true;
}
}
else if (intpart <= static_cast<double>(LONG_MAX)) {
else if (intpart <= static_cast<double>(std::numeric_limits<long>::max())) {
l = static_cast<long>(intpart);
return true;
}
@@ -2150,6 +2134,8 @@ Base::Vector3d FunctionExpression::extractVectorArgument(
Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std::vector<Expression*> &args)
{
using std::numbers::pi;
if(!expr || !expr->getOwner())
_EXPR_THROW("Invalid owner.", expr);
@@ -2186,7 +2172,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
Py::Object pyobj = args[0]->getPyValue();
if (PyObject_TypeCheck(pyobj.ptr(), &Base::MatrixPy::Type)) {
auto m = static_cast<Base::MatrixPy*>(pyobj.ptr())->value();
if (fabs(m.determinant()) <= DBL_EPSILON)
if (fabs(m.determinant()) <= std::numeric_limits<double>::epsilon())
_EXPR_THROW("Cannot invert singular matrix.", expr);
m.inverseGauss();
return Py::asObject(new Base::MatrixPy(m));
@@ -2227,7 +2213,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
Rotation rotation = Base::Rotation(
Vector3d(static_cast<double>(f == MROTATEX), static_cast<double>(f == MROTATEY), static_cast<double>(f == MROTATEZ)),
rotationAngle.getValue() * M_PI / 180.0);
rotationAngle.getValue() * pi / 180.0);
Base::Matrix4D rotationMatrix;
rotation.getValue(rotationMatrix);
@@ -2366,7 +2352,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
switch (f) {
case VANGLE:
return Py::asObject(new QuantityPy(new Quantity(vector1.GetAngle(vector2) * 180 / M_PI, Unit::Angle)));
return Py::asObject(new QuantityPy(new Quantity(vector1.GetAngle(vector2) * 180 / pi, Unit::Angle)));
case VCROSS:
return Py::asObject(new Base::VectorPy(vector1.Cross(vector2)));
case VDOT:
@@ -2425,7 +2411,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
_EXPR_THROW("Unit must be either empty or an angle.", expr);
// Convert value to radians
value *= M_PI / 180.0;
value *= pi / 180.0;
unit = Unit();
break;
case ACOS:
@@ -2434,7 +2420,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
if (!v1.isDimensionless())
_EXPR_THROW("Unit must be empty.", expr);
unit = Unit::Angle;
scaler = 180.0 / M_PI;
scaler = 180.0 / pi;
break;
case EXP:
case LOG:
@@ -2466,7 +2452,7 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
if (v1.getUnit() != v2.getUnit())
_EXPR_THROW("Units must be equal.",expr);
unit = Unit::Angle;
scaler = 180.0 / M_PI;
scaler = 180.0 / pi;
break;
case MOD:
if (e2.isNone())
+7 -4
View File
@@ -108,11 +108,14 @@ protected:
int _changed{0};
};
/**
* Base class for expressions.
*
*/
/**
* @brief %Base class for expressions.
* @ingroup ExpressionFramework
*
* @details For a high-level overview of the %Expression framework see topic
* @ref ExpressionFramework "Expression Framework".
*/
class AppExport Expression : public Base::BaseClass {
TYPESYSTEM_HEADER_WITH_OVERRIDE();
+4 -4
View File
@@ -341,15 +341,15 @@ EXPO [eE][-+]?[0-9]+
{DIGIT}+{EXPO} COUNTCHARS; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM;
{DIGIT}+ { COUNTCHARS;
yylval.ivalue = strtoll( yytext, NULL, 10 );
if (yylval.ivalue == LLONG_MIN)
if (yylval.ivalue == std::numeric_limits<long long>::min())
throw Base::UnderflowError("Integer underflow");
else if (yylval.ivalue == LLONG_MAX)
else if (yylval.ivalue == std::numeric_limits<long long>::max())
throw Base::OverflowError("Integer overflow");
if (yylval.ivalue == 1) { yylval.fvalue = 1; return ONE; } else return INTEGER;
}
"pi" COUNTCHARS; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi
"e" COUNTCHARS; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e
"pi" COUNTCHARS; yylval.constant.fvalue = std::numbers::pi; yylval.constant.name = "pi"; return CONSTANT; // constant pi
"e" COUNTCHARS; yylval.constant.fvalue = std::numbers::e; yylval.constant.name = "e"; return CONSTANT; // constant e
"None" COUNTCHARS; yylval.constant.fvalue = 0; yylval.constant.name = "None"; return CONSTANT;
"True" COUNTCHARS; yylval.constant.fvalue = 1; yylval.constant.name = "True"; return CONSTANT;
+2 -1
View File
@@ -2624,7 +2624,8 @@ Link::Link()
{
LINK_PROPS_ADD(LINK_PARAMS_LINK);
LinkExtension::initExtension(this);
static const PropertyIntegerConstraint::Constraints s_constraints = {0, INT_MAX, 1};
static const PropertyIntegerConstraint::Constraints s_constraints = {
0, std::numeric_limits<int>::max(), 1};
ElementCount.setConstraints(&s_constraints);
}
+10 -7
View File
@@ -130,7 +130,7 @@ ObjectIdentifier::ObjectIdentifier(const App::PropertyContainer* _owner,
}
if (!property.empty()) {
addComponent(SimpleComponent(property));
if (index != INT_MAX) {
if (index != std::numeric_limits<int>::max()) {
addComponent(ArrayComponent(index));
}
}
@@ -179,7 +179,7 @@ ObjectIdentifier::ObjectIdentifier(const Property& prop, int index)
setDocumentObjectName(docObj);
addComponent(SimpleComponent(String(prop.getName())));
if (index != INT_MAX) {
if (index != std::numeric_limits<int>::max()) {
addComponent(ArrayComponent(index));
}
}
@@ -703,8 +703,9 @@ Py::Object ObjectIdentifier::Component::get(const Py::Object& pyobj) const
}
else {
assert(isRange());
constexpr int max = std::numeric_limits<int>::max();
Py::Object slice(PySlice_New(Py::Long(begin).ptr(),
end != INT_MAX ? Py::Long(end).ptr() : nullptr,
end != max ? Py::Long(end).ptr() : nullptr,
step != 1 ? Py::Long(step).ptr() : nullptr),
true);
PyObject* r = PyObject_GetItem(pyobj.ptr(), slice.ptr());
@@ -742,8 +743,9 @@ void ObjectIdentifier::Component::set(Py::Object& pyobj, const Py::Object& value
}
else {
assert(isRange());
constexpr int max = std::numeric_limits<int>::max();
Py::Object slice(PySlice_New(Py::Long(begin).ptr(),
end != INT_MAX ? Py::Long(end).ptr() : nullptr,
end != max ? Py::Long(end).ptr() : nullptr,
step != 1 ? Py::Long(step).ptr() : nullptr),
true);
if (PyObject_SetItem(pyobj.ptr(), slice.ptr(), value.ptr()) < 0) {
@@ -770,8 +772,9 @@ void ObjectIdentifier::Component::del(Py::Object& pyobj) const
}
else {
assert(isRange());
constexpr int max = std::numeric_limits<int>::max();
Py::Object slice(PySlice_New(Py::Long(begin).ptr(),
end != INT_MAX ? Py::Long(end).ptr() : nullptr,
end != max ? Py::Long(end).ptr() : nullptr,
step != 1 ? Py::Long(step).ptr() : nullptr),
true);
if (PyObject_DelItem(pyobj.ptr(), slice.ptr()) < 0) {
@@ -897,11 +900,11 @@ void ObjectIdentifier::Component::toString(std::ostream& ss, bool toPython) cons
break;
case Component::RANGE:
ss << '[';
if (begin != INT_MAX) {
if (begin != std::numeric_limits<int>::max()) {
ss << begin;
}
ss << ':';
if (end != INT_MAX) {
if (end != std::numeric_limits<int>::max()) {
ss << end;
}
if (step != 1) {
+14 -8
View File
@@ -26,6 +26,7 @@
#include <bitset>
#include <map>
#include <limits>
#include <set>
#include <string>
#include <vector>
@@ -211,13 +212,13 @@ public:
Component(const String& _name = String(),
typeEnum _type = SIMPLE,
int begin = INT_MAX,
int end = INT_MAX,
int begin = std::numeric_limits<int>::max(),
int end = std::numeric_limits<int>::max(),
int step = 1); // explicit bombs
Component(String&& _name,
typeEnum _type = SIMPLE,
int begin = INT_MAX,
int end = INT_MAX,
int begin = std::numeric_limits<int>::max(),
int end = std::numeric_limits<int>::max(),
int step = 1); // explicit bombs
static Component SimpleComponent(const char* _component);
@@ -227,7 +228,9 @@ public:
static Component ArrayComponent(int _index);
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step = 1);
static Component RangeComponent(int _begin,
int _end = std::numeric_limits<int>::max(),
int _step = 1);
static Component MapComponent(const String& _key);
static Component MapComponent(String&& _key);
@@ -325,7 +328,9 @@ public:
return Component::ArrayComponent(_index);
}
static Component RangeComponent(int _begin, int _end = INT_MAX, int _step = 1)
static Component RangeComponent(int _begin,
int _end = std::numeric_limits<int>::max(),
int _step = 1)
{
return Component::RangeComponent(_begin, _end, _step);
}
@@ -342,11 +347,12 @@ public:
explicit ObjectIdentifier(const App::PropertyContainer* _owner = nullptr,
const std::string& property = std::string(),
int index = INT_MAX);
int index = std::numeric_limits<int>::max());
ObjectIdentifier(const App::PropertyContainer* _owner, bool localProperty);
ObjectIdentifier(const App::Property& prop, int index = INT_MAX); // explicit bombs
ObjectIdentifier(const App::Property& prop,
int index = std::numeric_limits<int>::max()); // explicit bombs
FC_DEFAULT_CTORS(ObjectIdentifier)
{
+1 -1
View File
@@ -50,7 +50,6 @@
#include <csignal>
#include <cstdio>
#include <ctime>
#include <cfloat>
#ifdef FC_OS_WIN32
#include <crtdbg.h>
@@ -74,6 +73,7 @@
#include <exception>
#include <functional>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
+11 -6
View File
@@ -44,14 +44,19 @@ namespace App
class PropertyContainer;
class ObjectIdentifier;
/** Base class of all properties
* This is the father of all properties. Properties are objects which are used
* in the document tree to parametrize e.g. features and their graphical output.
/**
* @brief %Base class of all properties
* @ingroup PropertyFramework
*
* @details This is the father of all properties. Properties are objects which that used
* in the document tree to parameterize e.g. features and their graphical output.
* They are also used to gain access from the scripting facility.
* /par
* @par
* This abstract base class defines all methods shared by all
* possible properties. It is also possible to define user properties
* and use them in the framework...
* possible properties. It is also possible to define user properties
* and use them in the framework.
*
* For a more high-level overview see topic @ref PropertyFramework "Property Framework".
*/
class AppExport Property: public Base::Persistence
{
-47
View File
@@ -640,50 +640,3 @@ void PropertyData::visitProperties(OffsetBase offsetBase,
};
}
/** \defgroup PropFrame Property framework
\ingroup APP
\brief System to access object properties
\section Introduction
The property framework introduces the ability to access attributes (member variables) of a class by name without
knowing the class type. It's like the reflection mechanism of Java or C#.
This ability is introduced by the App::PropertyContainer class and can be used by all derived classes.
This makes it possible in the first place to make an automatic mapping to python (e.g. in App::FeaturePy) and
abstract editing properties in Gui::PropertyEditor.
\section Examples
Here some little examples how to use it:
\code
// search in PropertyList
Property *prop = _pcFeature->getPropertyByName(attr);
if(prop)
{
return prop->getPyObject();
}
\endcode
or:
\code
void PropertyContainer::Restore(Base::Reader &reader)
{
reader.readElement("Properties");
int Cnt = reader.getAttributeAsInteger("Count");
for(int i=0 ;i<Cnt ;i++)
{
reader.readElement("Property");
string PropName = reader.getAttribute("name");
Property* prop = getPropertyByName(PropName.c_str());
if(prop)
prop->Restore(reader);
reader.readEndElement("Property");
}
reader.readEndElement("Properties");
}
\endcode
*/
+3 -2
View File
@@ -1250,7 +1250,7 @@ void PropertyFloatConstraint::setPyObject(PyObject* value)
double stepSize = valConstr[3];
// need a value > 0
if (stepSize < DBL_EPSILON) {
if (stepSize < std::numeric_limits<double>::epsilon()) {
throw Base::ValueError("Step size must be greater than zero");
}
@@ -1282,7 +1282,8 @@ TYPESYSTEM_SOURCE(App::PropertyPrecision, App::PropertyFloatConstraint)
//**************************************************************************
// Construction/Destruction
//
const PropertyFloatConstraint::Constraints PrecisionStandard = {0.0, DBL_MAX, 0.001};
const PropertyFloatConstraint::Constraints PrecisionStandard = {
0.0, std::numeric_limits<double>::max(), 0.001};
PropertyPrecision::PropertyPrecision()
{
+13 -2
View File
@@ -22,7 +22,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <cfloat>
#endif
#include <Base/QuantityPy.h>
@@ -37,7 +36,8 @@ using namespace Base;
using namespace std;
const PropertyQuantityConstraint::Constraints LengthStandard = {0.0, DBL_MAX, 1.0};
const PropertyQuantityConstraint::Constraints LengthStandard = {
0.0, std::numeric_limits<double>::max(), 1.0};
const PropertyQuantityConstraint::Constraints AngleStandard = {-360, 360, 1.0};
//**************************************************************************
@@ -403,6 +403,17 @@ PropertySurfaceChargeDensity::PropertySurfaceChargeDensity()
setUnit(Base::Unit::SurfaceChargeDensity);
}
//**************************************************************************
// PropertyVolumeChargeDensity
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TYPESYSTEM_SOURCE(App::PropertyVolumeChargeDensity, App::PropertyQuantity)
PropertyVolumeChargeDensity::PropertyVolumeChargeDensity()
{
setUnit(Base::Unit::VolumeChargeDensity);
}
//**************************************************************************
// PropertyElectricCurrent
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+13
View File
@@ -374,6 +374,19 @@ public:
~PropertySurfaceChargeDensity() override = default;
};
/** VolumeChargeDensity property
* This is a property for representing volume charge density. It is basically a float
* property. On the Gui it has a quantity like C/m^3.
*/
class AppExport PropertyVolumeChargeDensity: public PropertyQuantity
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
PropertyVolumeChargeDensity();
~PropertyVolumeChargeDensity() override = default;
};
/** ElectricCurrent property
* This is a property for representing electric currents. It is basically a
* float property. On the Gui it has a quantity like A.
+113 -11
View File
@@ -1,15 +1,117 @@
/** \defgroup APP App
* \ingroup CORE
* \brief The part of FreeCAD that works without GUI (console or server mode)
*/
/**
* @defgroup APP App
* @ingroup CORE
* @brief The part of FreeCAD that works without GUI (console or server mode)
* @details It contains the App namespace and defines core concepts such as
* @ref DocumentGroup "Document", @ref DocumentObjectGroup "Document Object",
* the @ref ExpressionFramework "Expression Framework", and the @ref
* PropertyFramework "Property Framework".
*/
/** \namespace App
\ingroup APP
\brief The FreeCAD Application layer
/**
* @defgroup DocumentGroup Document
* @ingroup APP
* @brief The class that represents a FreeCAD document
*
* This (besides the App::Application class) is the most important class in FreeCAD.
* It contains all the data of the opened, saved, or newly created FreeCAD Document.
* The App::Document manages the Undo and Redo mechanism and the linking of documents.
*
* Note: the documents are not free objects. They are completely handled by the
* App::Application. Only the Application can Open or destroy a document.
*
* \section Exception Exception handling
* As the document is the main data structure of FreeCAD we have to take a close
* look at how Exceptions affect the integrity of the App::Document.
*
* \section UndoRedo Undo Redo an Transactions
* Undo Redo handling is one of the major mechanism of a document in terms of
* user friendliness and speed (no one will wait for Undo too long).
*
* \section Dependency Graph and dependency handling
* The FreeCAD document handles the dependencies of its DocumentObjects with
* an adjacency list. This gives the opportunity to calculate the shortest
* recompute path. Also, it enables more complicated dependencies beyond trees.
*
* @see App::Application
* @see App::DocumentObject
*/
This namespace includes Application services of FreeCAD like:
- The Application class
- The Document class
/**
* @defgroup DocumentObjectGroup Document Object
* @ingroup APP
* @brief %Base class of all objects handled in the Document.
*/
/**
* @defgroup ExpressionFramework Expressions framework
* @ingroup APP
* @brief The expression system allows users to write expressions and formulas that produce values
*/
/**
* @defgroup PropertyFramework Property framework
* @ingroup APP
* @brief System to access object properties.
*
* @section propframe_intro Introduction
*
* The property framework introduces the ability to access attributes (member
* variables) of a class by name without knowing the class type. It's like the
* reflection mechanism of Java or C#. This ability is introduced by the
* App::PropertyContainer class and can be used by all derived classes.
*
* This makes it possible in the first place to make an automatic mapping to python (e.g. in App::FeaturePy) and
* abstract editing properties in Gui::PropertyEditor.
*
* @section Examples
*
* Here some little examples how to use it:
*
* @code
* // search in PropertyList
* Property *prop = _pcFeature->getPropertyByName(attr);
* if(prop)
* {
* return prop->getPyObject();
* }
* @endcode
*
* or:
*
* @code
* void PropertyContainer::Restore(Base::Reader &reader)
* {
* reader.readElement("Properties");
* int Cnt = reader.getAttributeAsInteger("Count");
*
* for(int i=0 ;i<Cnt ;i++)
* {
* reader.readElement("Property");
* string PropName = reader.getAttribute("name");
* Property* prop = getPropertyByName(PropName.c_str());
* if(prop)
* prop->Restore(reader);
*
* reader.readEndElement("Property");
* }
* reader.readEndElement("Properties");
* }
* @endcode
*/
*/
/**
* @namespace App
* @ingroup APP
* @brief The namespace for the part of FreeCAD that works without GUI.
* @details This namespace includes %Application services of FreeCAD that such as:
* - The Application class
* - The Document class
* - The DocumentObject classes
* - The Expression classes
* - The Property classes
*
* For a more high-level discussion see the topic @ref APP "App".
*/
+2 -2
View File
@@ -9583,12 +9583,12 @@ YY_RULE_SETUP
case 138:
YY_RULE_SETUP
#line 351 "ExpressionParser.l"
COUNTCHARS; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi
COUNTCHARS; yylval.constant.fvalue = std::numbers::pi; yylval.constant.name = "pi"; return CONSTANT; // constant pi
YY_BREAK
case 139:
YY_RULE_SETUP
#line 352 "ExpressionParser.l"
COUNTCHARS; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e
COUNTCHARS; yylval.constant.fvalue = std::numbers::e; yylval.constant.name = "e"; return CONSTANT; // constant e
YY_BREAK
case 140:
YY_RULE_SETUP
+21
View File
@@ -26,6 +26,7 @@
// Std. configurations
#include <array>
#include <cassert>
#include <chrono>
#include <map>
#include <set>
@@ -759,6 +760,11 @@ public:
template<typename... Args>
inline void DeveloperError(const std::string& notifier, const char* pMsg, Args&&... args);
template<typename... Args>
/// A noexcept DeveloperError for use in destructors. When compiled in debug, terminates via an
/// assert. In release, the exception is silently caught and dropped.
inline void
DestructorError(const std::string& notifier, const char* pMsg, Args&&... args) noexcept;
template<typename... Args>
inline void UserError(const std::string& notifier, const char* pMsg, Args&&... args);
template<typename... Args>
inline void TranslatedUserError(const std::string& notifier, const char* pMsg, Args&&... args);
@@ -1083,6 +1089,21 @@ inline void Base::ConsoleSingleton::DeveloperError(const std::string& notifier,
Base::ContentType::Untranslatable>(notifier, pMsg, std::forward<Args>(args)...);
}
template<typename... Args>
inline void Base::ConsoleSingleton::DestructorError(const std::string& notifier,
const char* pMsg,
Args&&... args) noexcept
{
try {
Send<Base::LogStyle::Error,
Base::IntendedRecipient::Developer,
Base::ContentType::Untranslatable>(notifier, pMsg, std::forward<Args>(args)...);
}
catch (...) {
assert("An exception was thrown while attempting console output in a destructor" && false);
}
}
template<typename... Args>
inline void
Base::ConsoleSingleton::UserError(const std::string& notifier, const char* pMsg, Args&&... args)
-1
View File
@@ -32,7 +32,6 @@
#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
#elif defined(FC_OS_WIN32)
#include <io.h>
#include <Windows.h>
+31 -5
View File
@@ -538,8 +538,36 @@ void InterpreterSingleton::addPythonPath(const char* Path)
list.append(Py::String(Path));
}
std::string InterpreterSingleton::getPythonPath()
{
// Construct something that looks like the output of the now-deprecated Py_GetPath
PyGILStateLocker lock;
PyObject* path = PySys_GetObject("path");
std::string result;
const char* separator = ":"; // Use ":" on Unix-like systems, ";" on Windows
#ifdef FC_OS_WIN32
separator = ";";
#endif
Py_ssize_t length = PyList_Size(path);
for (Py_ssize_t i = 0; i < length; ++i) {
PyObject* item = PyList_GetItem(path, i); // Borrowed reference
if (!item) {
throw Base::RuntimeError("Failed to retrieve item from path");
}
const char* item_str = PyUnicode_AsUTF8(item);
if (!item_str) {
throw Base::RuntimeError("Failed to convert path item to UTF-8 string");
}
if (!result.empty()) {
result += separator;
}
result += item_str;
}
return result;
}
#if PY_VERSION_HEX < 0x030b0000
const char* InterpreterSingleton::init(int argc, char* argv[])
std::string InterpreterSingleton::init(int argc, char* argv[])
{
if (!Py_IsInitialized()) {
Py_SetProgramName(Py_DecodeLocale(argv[0], nullptr));
@@ -617,7 +645,7 @@ void initInterpreter(int argc, char* argv[])
Py_Initialize();
}
} // namespace
const char* InterpreterSingleton::init(int argc, char* argv[])
std::string InterpreterSingleton::init(int argc, char* argv[])
{
try {
if (!Py_IsInitialized()) {
@@ -626,9 +654,7 @@ const char* InterpreterSingleton::init(int argc, char* argv[])
PythonStdOutput::init_type();
this->_global = PyEval_SaveThread();
}
PyGILStateLocker lock;
return Py_EncodeLocale(Py_GetPath(), nullptr);
return getPythonPath();
}
catch (const Base::Exception& e) {
e.ReportException();
+3 -1
View File
@@ -285,6 +285,8 @@ public:
bool loadModule(const char* psModName);
/// Add an additional python path
void addPythonPath(const char* Path);
/// Get the path (replaces the deprecated Py_GetPath method)
std::string getPythonPath();
static void addType(PyTypeObject* Type, PyObject* Module, const char* Name);
/// Add a module and return a PyObject to it
PyObject* addModule(Py::ExtensionModuleBase*);
@@ -313,7 +315,7 @@ public:
*/
//@{
/// init the interpreter and returns the module search path
const char* init(int argc, char* argv[]);
std::string init(int argc, char* argv[]);
int runCommandLine(const char* prompt);
void replaceStdOutput();
static InterpreterSingleton& Instance();
+3 -3
View File
@@ -429,7 +429,7 @@ bool Matrix4D::toAxisAngle(Vector3d& rclBase,
rfAngle = acos(fCos); // in [0,PI]
if (rfAngle > 0.0) {
if (rfAngle < D_PI) {
if (rfAngle < std::numbers::pi) {
rclDir.x = (dMtrx4D[2][1] - dMtrx4D[1][2]);
rclDir.y = (dMtrx4D[0][2] - dMtrx4D[2][0]);
rclDir.z = (dMtrx4D[1][0] - dMtrx4D[0][1]);
@@ -1013,8 +1013,8 @@ std::array<Matrix4D, 4> Matrix4D::decompose() const
residualMatrix = rotationMatrix * residualMatrix;
// To keep signs of the scale factors equal
if (residualMatrix.determinant() < 0) {
rotationMatrix.rotZ(D_PI);
residualMatrix.rotZ(D_PI);
rotationMatrix.rotZ(std::numbers::pi);
residualMatrix.rotZ(std::numbers::pi);
}
rotationMatrix.inverseGauss();
// extract scale
+3 -3
View File
@@ -218,7 +218,7 @@ PyObject* MatrixPy::number_power_handler(PyObject* self, PyObject* other, PyObje
}
if (b < 0) {
if (fabs(a.determinant()) > DBL_EPSILON) {
if (fabs(a.determinant()) > std::numeric_limits<double>::epsilon()) {
a.inverseGauss();
}
else {
@@ -667,7 +667,7 @@ PyObject* MatrixPy::invert()
{
PY_TRY
{
if (fabs(getMatrixPtr()->determinant()) > DBL_EPSILON) {
if (fabs(getMatrixPtr()->determinant()) > std::numeric_limits<double>::epsilon()) {
getMatrixPtr()->inverseGauss();
Py_Return;
}
@@ -682,7 +682,7 @@ PyObject* MatrixPy::inverse()
{
PY_TRY
{
if (fabs(getMatrixPtr()->determinant()) > DBL_EPSILON) {
if (fabs(getMatrixPtr()->determinant()) > std::numeric_limits<double>::epsilon()) {
Base::Matrix4D m = *getMatrixPtr();
m.inverseGauss();
return new MatrixPy(m);
+2 -1
View File
@@ -99,7 +99,8 @@ int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/)
&angle)) {
// NOTE: The first parameter defines the translation, the second the rotation axis
// and the last parameter defines the rotation angle in degree.
Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(), angle / 180.0 * D_PI);
Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(),
angle / 180.0 * std::numbers::pi);
*getPlacementPtr() = Base::Placement(static_cast<Base::VectorPy*>(o)->value(), rot);
return 0;
}
+1 -6
View File
@@ -36,13 +36,8 @@
#include <cstdio>
#include <cassert>
#include <ctime>
#include <cfloat>
#include <chrono>
#ifdef FC_OS_WIN32
#define _USE_MATH_DEFINES
#endif // FC_OS_WIN32
#include <cmath>
#include <climits>
#include <codecvt>
#ifdef FC_OS_WIN32
@@ -61,7 +56,6 @@
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#endif
// STL
@@ -69,6 +63,7 @@
#include <string_view>
#include <list>
#include <map>
#include <numbers>
#include <unordered_map>
#include <vector>
#include <set>
+4 -4
View File
@@ -22,9 +22,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#define _USE_MATH_DEFINES
#include <cmath>
#include <array>
#include <numbers>
#endif
#include <fmt/format.h>
@@ -443,8 +443,8 @@ const Quantity Quantity::AngSecond(1.0 / 3600.0, Unit(0, 0, 0, 0, 0, 0, 0, 1));
const Quantity
Quantity::Degree(1.0,
Unit(0, 0, 0, 0, 0, 0, 0, 1)); // degree (internal standard angle)
const Quantity Quantity::Radian(180 / M_PI, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // radian
const Quantity Quantity::Gon(360.0 / 400.0, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // gon
const Quantity Quantity::Radian(180 / std::numbers::pi, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // radian
const Quantity Quantity::Gon(360.0 / 400.0, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // gon
// === Parser & Scanner stuff ===============================================
@@ -568,7 +568,7 @@ Quantity Quantity::parse(const std::string& string)
QuantityParser::yy_scan_string(string.c_str());
QuantityParser::StringBufferCleaner cleaner(my_string_buffer);
// set the global return variables
QuantResult = Quantity(DOUBLE_MIN);
QuantResult = Quantity(std::numeric_limits<double>::min());
// run the parser
QuantityParser::yyparse();
-9
View File
@@ -27,15 +27,6 @@
#include "Unit.h"
#include <string>
// NOLINTBEGIN
#ifndef DOUBLE_MAX
#define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
#define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
// NOLINTEND
namespace Base
{
class UnitsSchema;
+2 -2
View File
@@ -1613,12 +1613,12 @@ YY_RULE_SETUP
case 135:
YY_RULE_SETUP
#line 228 "QuantityParser.l"
{yylval = Quantity(M_PI) ; return NUM;} // constant pi
{yylval = Quantity(std::numbers::pi) ; return NUM;} // constant pi
YY_BREAK
case 136:
YY_RULE_SETUP
#line 229 "QuantityParser.l"
{yylval = Quantity(M_E) ; return NUM;} // constant e
{yylval = Quantity(std::numbers::e) ; return NUM;} // constant e
YY_BREAK
case 137:
YY_RULE_SETUP
+7 -7
View File
@@ -68,12 +68,12 @@
#define YYSTYPE Quantity
#define yyparse Quantity_yyparse
#define yyerror Quantity_yyerror
#ifndef DOUBLE_MAX
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
#line 79 "QuantityParser.c" /* yacc.c:339 */
@@ -1301,7 +1301,7 @@ yyreduce:
{
case 2:
#line 34 "QuantityParser.y" /* yacc.c:1646 */
{ QuantResult = Quantity(DOUBLE_MIN); /* empty input */ }
{ QuantResult = Quantity(std::numeric_limits<double>::min()); /* empty input */ }
#line 1305 "QuantityParser.c" /* yacc.c:1646 */
break;
+2 -2
View File
@@ -225,8 +225,8 @@ CGRP '\,'[0-9][0-9][0-9]
","?{DIGIT}+{EXPO}? { yylval = Quantity(num_change(yytext,',','.'));return NUM; }
"pi" {yylval = Quantity(M_PI) ; return NUM;} // constant pi
"e" {yylval = Quantity(M_E) ; return NUM;} // constant e
"pi" {yylval = Quantity(std::numbers::pi) ; return NUM;} // constant pi
"e" {yylval = Quantity(std::numbers::e) ; return NUM;} // constant e
"acos" return ACOS;
"asin" return ASIN;
+7 -7
View File
@@ -25,12 +25,12 @@
#define YYSTYPE Quantity
#define yyparse Quantity_yyparse
#define yyerror Quantity_yyerror
#ifndef DOUBLE_MAX
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
%}
@@ -49,7 +49,7 @@
%%
input: { QuantResult = Quantity(DOUBLE_MIN); /* empty input */ }
input: { QuantResult = Quantity(std::numeric_limits<double>::min()); /* empty input */ }
| num { QuantResult = $1 ; }
| unit { QuantResult = $1 ; }
| quantity { QuantResult = $1 ; }
+4 -4
View File
@@ -88,7 +88,7 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
}
PyErr_Clear(); // set by PyArg_ParseTuple()
double f = DOUBLE_MAX;
double f = std::numeric_limits<double>::max();
if (PyArg_ParseTuple(args, "dO!", &f, &(Base::UnitPy::Type), &object)) {
*self = Quantity(f, *(static_cast<Base::UnitPy*>(object)->getUnitPtr()));
return 0;
@@ -110,7 +110,7 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
int i8 = 0;
PyErr_Clear(); // set by PyArg_ParseTuple()
if (PyArg_ParseTuple(args, "|diiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
if (f < DOUBLE_MAX) {
if (f < std::numeric_limits<double>::max()) {
*self = Quantity(f,
Unit {static_cast<int8_t>(i1),
static_cast<int8_t>(i2),
@@ -207,7 +207,7 @@ PyObject* QuantityPy::getValueAs(PyObject* args)
}
if (!quant.isValid()) {
double f = DOUBLE_MAX;
double f = std::numeric_limits<double>::max();
int i1 = 0;
int i2 = 0;
int i3 = 0;
@@ -218,7 +218,7 @@ PyObject* QuantityPy::getValueAs(PyObject* args)
int i8 = 0;
PyErr_Clear();
if (PyArg_ParseTuple(args, "d|iiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
if (f < DOUBLE_MAX) {
if (f < std::numeric_limits<double>::max()) {
quant = Quantity(f,
Unit {static_cast<int8_t>(i1),
static_cast<int8_t>(i2),
+27 -21
View File
@@ -245,11 +245,12 @@ void Rotation::setValue(const Matrix4D& m)
void Rotation::setValue(const Vector3d& axis, double fAngle)
{
using std::numbers::pi;
// Taken from <http://de.wikipedia.org/wiki/Quaternionen>
//
// normalization of the angle to be in [0, 2pi[
_angle = fAngle;
double theAngle = fAngle - floor(fAngle / (2.0 * D_PI)) * (2.0 * D_PI);
double theAngle = fAngle - floor(fAngle / (2.0 * pi)) * (2.0 * pi);
this->quat[3] = cos(theAngle / 2.0);
Vector3d norm = axis;
@@ -691,9 +692,9 @@ void Rotation::setYawPitchRoll(double y, double p, double r)
{
// The Euler angles (yaw,pitch,roll) are in XY'Z''-notation
// convert to radians
y = (y / 180.0) * D_PI;
p = (p / 180.0) * D_PI;
r = (r / 180.0) * D_PI;
y = (y / 180.0) * std::numbers::pi;
p = (p / 180.0) * std::numbers::pi;
r = (r / 180.0) * std::numbers::pi;
double c1 = cos(y / 2.0);
double s1 = sin(y / 2.0);
@@ -710,6 +711,8 @@ void Rotation::setYawPitchRoll(double y, double p, double r)
void Rotation::getYawPitchRoll(double& y, double& p, double& r) const
{
using std::numbers::pi;
double q00 = quat[0] * quat[0];
double q11 = quat[1] * quat[1];
double q22 = quat[2] * quat[2];
@@ -722,30 +725,31 @@ void Rotation::getYawPitchRoll(double& y, double& p, double& r) const
double q23 = quat[2] * quat[3];
double qd2 = 2.0 * (q13 - q02);
// Tolerance copied from OCC "gp_Quaternion.cxx"
constexpr double tolerance = 16 * std::numeric_limits<double>::epsilon();
// handle gimbal lock
if (fabs(qd2 - 1.0) <= 16 * DBL_EPSILON) { // Tolerance copied from OCC "gp_Quaternion.cxx"
if (fabs(qd2 - 1.0) <= tolerance) {
// north pole
y = 0.0;
p = D_PI / 2.0;
p = pi / 2.0;
r = 2.0 * atan2(quat[0], quat[3]);
}
else if (fabs(qd2 + 1.0)
<= 16 * DBL_EPSILON) { // Tolerance copied from OCC "gp_Quaternion.cxx"
else if (fabs(qd2 + 1.0) <= tolerance) {
// south pole
y = 0.0;
p = -D_PI / 2.0;
p = -pi / 2.0;
r = 2.0 * atan2(quat[0], quat[3]);
}
else {
y = atan2(2.0 * (q01 + q23), (q00 + q33) - (q11 + q22));
p = qd2 > 1.0 ? D_PI / 2.0 : (qd2 < -1.0 ? -D_PI / 2.0 : asin(qd2));
p = qd2 > 1.0 ? pi / 2.0 : (qd2 < -1.0 ? -pi / 2.0 : asin(qd2));
r = atan2(2.0 * (q12 + q03), (q22 + q33) - (q00 + q11));
}
// convert to degree
y = (y / D_PI) * 180;
p = (p / D_PI) * 180;
r = (r / D_PI) * 180;
y = (y / pi) * 180;
p = (p / pi) * 180;
r = (r / pi) * 180;
}
bool Rotation::isSame(const Rotation& q) const
@@ -978,15 +982,17 @@ void Rotation::setEulerAngles(EulerSequence theOrder,
double theBeta,
double theGamma)
{
using std::numbers::pi;
if (theOrder == Invalid || theOrder >= EulerSequenceLast) {
throw Base::ValueError("invalid euler sequence");
}
EulerSequence_Parameters o = translateEulerSequence(theOrder);
theAlpha *= D_PI / 180.0;
theBeta *= D_PI / 180.0;
theGamma *= D_PI / 180.0;
theAlpha *= pi / 180.0;
theBeta *= pi / 180.0;
theGamma *= pi / 180.0;
double a = theAlpha;
double b = theBeta;
@@ -1048,7 +1054,7 @@ void Rotation::getEulerAngles(EulerSequence theOrder,
EulerSequence_Parameters o = translateEulerSequence(theOrder);
if (o.isTwoAxes) {
double sy = sqrt(M(o.i, o.j) * M(o.i, o.j) + M(o.i, o.k) * M(o.i, o.k));
if (sy > 16 * DBL_EPSILON) {
if (sy > 16 * std::numeric_limits<double>::epsilon()) {
theAlpha = atan2(M(o.i, o.j), M(o.i, o.k));
theGamma = atan2(M(o.j, o.i), -M(o.k, o.i));
}
@@ -1060,7 +1066,7 @@ void Rotation::getEulerAngles(EulerSequence theOrder,
}
else {
double cy = sqrt(M(o.i, o.i) * M(o.i, o.i) + M(o.j, o.i) * M(o.j, o.i));
if (cy > 16 * DBL_EPSILON) {
if (cy > 16 * std::numeric_limits<double>::epsilon()) {
theAlpha = atan2(M(o.k, o.j), M(o.k, o.k));
theGamma = atan2(M(o.j, o.i), M(o.i, o.i));
}
@@ -1081,7 +1087,7 @@ void Rotation::getEulerAngles(EulerSequence theOrder,
theGamma = aFirst;
}
theAlpha *= 180.0 / D_PI;
theBeta *= 180.0 / D_PI;
theGamma *= 180.0 / D_PI;
theAlpha *= 180.0 / std::numbers::pi;
theBeta *= 180.0 / std::numbers::pi;
theGamma *= 180.0 / std::numbers::pi;
}
+3 -6
View File
@@ -28,6 +28,7 @@
#include <FCGlobal.h>
#endif
#include <cmath>
#include <numbers>
#include <ostream>
#include <string>
#include <vector>
@@ -127,20 +128,16 @@ inline T sgn(T t)
return (t > 0) ? T(1) : T(-1);
}
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
template<class T>
inline T toRadians(T d)
{
return static_cast<T>((d * M_PI) / 180.0);
return static_cast<T>((d * std::numbers::pi) / 180.0);
}
template<class T>
inline T toDegrees(T r)
{
return static_cast<T>((r / M_PI) * 180.0);
return static_cast<T>((r / std::numbers::pi) * 180.0);
}
inline float fromPercent(const long value)
+6 -6
View File
@@ -43,7 +43,7 @@ double Vector2d::GetAngle(const Vector2d& vec) const
if ((fDivid < -1e-10) || (fDivid > 1e-10)) {
fNum = (*this * vec) / fDivid;
if (fNum < -1) {
return D_PI;
return std::numbers::pi;
}
if (fNum > 1) {
return 0.0;
@@ -52,7 +52,7 @@ double Vector2d::GetAngle(const Vector2d& vec) const
return acos(fNum);
}
return -FLOAT_MAX; // division by zero
return -std::numeric_limits<double>::max(); // division by zero
}
void Vector2d::ProjectToLine(const Vector2d& point, const Vector2d& line)
@@ -173,13 +173,13 @@ bool Line2d::Intersect(const Line2d& rclLine, Vector2d& rclV) const
m1 = (clV2.y - clV1.y) / (clV2.x - clV1.x);
}
else {
m1 = DOUBLE_MAX;
m1 = std::numeric_limits<double>::max();
}
if (fabs(rclLine.clV2.x - rclLine.clV1.x) > 1e-10) {
m2 = (rclLine.clV2.y - rclLine.clV1.y) / (rclLine.clV2.x - rclLine.clV1.x);
}
else {
m2 = DOUBLE_MAX;
m2 = std::numeric_limits<double>::max();
}
if (m1 == m2) { /****** RETURN ERR (parallel lines) *************/
return false;
@@ -189,11 +189,11 @@ bool Line2d::Intersect(const Line2d& rclLine, Vector2d& rclV) const
b2 = rclLine.clV1.y - m2 * rclLine.clV1.x;
// calc intersection
if (m1 == DOUBLE_MAX) {
if (m1 == std::numeric_limits<double>::max()) {
rclV.x = clV1.x;
rclV.y = m2 * rclV.x + b2;
}
else if (m2 == DOUBLE_MAX) {
else if (m2 == std::numeric_limits<double>::max()) {
rclV.x = rclLine.clV1.x;
rclV.y = m1 * rclV.x + b1;
}
+6 -14
View File
@@ -32,15 +32,6 @@
#include <FCGlobal.h>
#endif
// NOLINTBEGIN
#ifndef DOUBLE_MAX
#define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
#define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
// NOLINTEND
namespace Base
{
@@ -462,8 +453,8 @@ inline bool Line2d::Contains(const Vector2d& rclV) const
inline BoundBox2d::BoundBox2d()
{
MinX = MinY = DOUBLE_MAX;
MaxX = MaxY = -DOUBLE_MAX;
MinX = MinY = std::numeric_limits<double>::max();
MaxX = MaxY = -std::numeric_limits<double>::max();
}
inline BoundBox2d::BoundBox2d(double fX1, double fY1, double fX2, double fY2)
@@ -480,7 +471,8 @@ inline bool BoundBox2d::IsValid() const
inline bool BoundBox2d::IsInfinite() const
{
return MaxX >= DOUBLE_MAX && MaxY >= DOUBLE_MAX && MinX <= -DOUBLE_MAX && MinY <= -DOUBLE_MAX;
constexpr double max = std::numeric_limits<double>::max();
return MaxX >= max && MaxY >= max && MinX <= -max && MinY <= -max;
}
inline bool BoundBox2d::IsEqual(const BoundBox2d& bbox, double tolerance) const
@@ -525,8 +517,8 @@ inline Vector2d BoundBox2d::GetCenter() const
inline void BoundBox2d::SetVoid()
{
MinX = MinY = DOUBLE_MAX;
MaxX = MaxY = -DOUBLE_MAX;
MinX = MinY = std::numeric_limits<double>::max();
MaxX = MaxY = -std::numeric_limits<double>::max();
}
inline void BoundBox2d::Add(const Vector2d& v)
+3 -1
View File
@@ -587,7 +587,7 @@ std::string Unit::getString() const
std::string Unit::getTypeString() const
{
static std::array<std::pair<Unit, std::string>, 56> unitSpecs {{
static std::array<std::pair<Unit, std::string>, 57> unitSpecs {{
{ Unit::Acceleration, "Acceleration" },
{ Unit::AmountOfSubstance, "AmountOfSubstance" },
{ Unit::Angle, "Angle" },
@@ -604,6 +604,7 @@ std::string Unit::getTypeString() const
{ Unit::ElectricalResistance, "ElectricalResistance" },
{ Unit::ElectricCharge, "ElectricCharge" },
{ Unit::SurfaceChargeDensity, "SurfaceChargeDensity" },
{ Unit::VolumeChargeDensity, "VolumeChargeDensity" },
{ Unit::ElectricCurrent, "ElectricCurrent" },
{ Unit::ElectricPotential, "ElectricPotential" },
{ Unit::ElectromagneticPotential, "ElectromagneticPotential" },
@@ -683,6 +684,7 @@ const Unit Unit::ElectricalInductance (2, 1, -2, -2);
const Unit Unit::ElectricalResistance (2, 1, -3, -2);
const Unit Unit::ElectricCharge (0, 0, 1, 1);
const Unit Unit::SurfaceChargeDensity (-2, 0, 1, 1);
const Unit Unit::VolumeChargeDensity (-3, 0, 1, 1);
const Unit Unit::ElectricPotential (2, 1, -3, -1);
const Unit Unit::ElectromagneticPotential (1, 1, -2, -1);
const Unit Unit::Force (1, 1, -2);
+1
View File
@@ -111,6 +111,7 @@ public:
static const Unit ElectricPotential;
static const Unit ElectricCharge;
static const Unit SurfaceChargeDensity;
static const Unit VolumeChargeDensity;
static const Unit MagneticFieldStrength;
static const Unit MagneticFlux;
static const Unit MagneticFluxDensity;
+31 -3
View File
@@ -370,14 +370,42 @@ UnitsSchemaInternal::schemaTranslate(const Quantity& quant, double& factor, std:
factor = 1.0;
}
else if (unit == Unit::SurfaceChargeDensity) {
unitString = "C/m^2";
factor = 1e-6;
if (UnitValue <= 1e-4) {
unitString = "C/m^2";
factor = 1e-6;
}
else if (UnitValue <= 1e-2) {
unitString = "C/cm^2";
factor = 1e-2;
}
else {
unitString = "C/mm^2";
factor = 1;
}
}
else if (unit == Unit::VolumeChargeDensity) {
if (UnitValue <= 1e-4) {
unitString = "C/m^3";
factor = 1e-9;
}
else if (UnitValue <= 1e-2) {
unitString = "C/cm^3";
factor = 1e-3;
}
else {
unitString = "C/mm^3";
factor = 1;
}
}
else if (unit == Unit::CurrentDensity) {
if (UnitValue <= 1e3) {
if (UnitValue <= 1e-4) {
unitString = "A/m^2";
factor = 1e-6;
}
else if (UnitValue <= 1e-2) {
unitString = "A/cm^2";
factor = 1e-2;
}
else {
unitString = "A/mm^2";
factor = 1;
+4
View File
@@ -320,6 +320,10 @@ UnitsSchemaMKS::schemaTranslate(const Quantity& quant, double& factor, std::stri
unitString = "C/m^2";
factor = 1e-6;
}
else if (unit == Unit::VolumeChargeDensity) {
unitString = "C/m^3";
factor = 1e-9;
}
else if (unit == Unit::CurrentDensity) {
if (UnitValue <= 1e3) {
unitString = "A/m^2";
+16 -40
View File
@@ -24,34 +24,9 @@
#ifndef BASE_VECTOR3D_H
#define BASE_VECTOR3D_H
#include <limits>
#include <cmath>
#include <cfloat>
#ifndef F_PI
#define F_PI 3.1415926f
#endif
#ifndef D_PI
#define D_PI 3.141592653589793
#endif
#ifndef FLOAT_MAX
#define FLOAT_MAX 3.402823466E+38F
#endif
#ifndef FLOAT_MIN
#define FLOAT_MIN 1.175494351E-38F
#endif
#ifndef DOUBLE_MAX
#define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
#endif
#ifndef DOUBLE_MIN
#define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
#endif
#include <numbers>
namespace Base
{
@@ -60,21 +35,22 @@ struct float_traits
{
};
// TODO: Remove these specializations and use the default implementation for all types.
template<>
struct float_traits<float>
{
using float_type = float;
[[nodiscard]] static constexpr float_type pi()
[[nodiscard]] static consteval float_type pi()
{
return F_PI;
return std::numbers::pi_v<float_type>;
}
[[nodiscard]] static constexpr float_type epsilon()
[[nodiscard]] static consteval float_type epsilon()
{
return FLT_EPSILON;
return std::numeric_limits<float_type>::epsilon();
}
[[nodiscard]] static constexpr float_type maximum()
[[nodiscard]] static consteval float_type maximum()
{
return FLT_MAX;
return std::numeric_limits<float_type>::max();
}
};
@@ -82,17 +58,17 @@ template<>
struct float_traits<double>
{
using float_type = double;
[[nodiscard]] static constexpr float_type pi()
[[nodiscard]] static consteval float_type pi()
{
return D_PI;
return std::numbers::pi_v<float_type>;
}
[[nodiscard]] static constexpr float_type epsilon()
[[nodiscard]] static consteval float_type epsilon()
{
return DBL_EPSILON;
return std::numeric_limits<float_type>::epsilon();
}
[[nodiscard]] static constexpr float_type maximum()
[[nodiscard]] static consteval float_type maximum()
{
return DBL_MAX;
return std::numeric_limits<float_type>::max();
}
};
@@ -275,7 +251,7 @@ template<class float_type>
float_type x = v1.x - v2.x;
float_type y = v1.y - v2.y;
float_type z = v1.z - v2.z;
return static_cast<float_type>(sqrt((x * x) + (y * y) + (z * z)));
return static_cast<float_type>(std::sqrt((x * x) + (y * y) + (z * z)));
}
/// Returns the squared distance between two points
-2
View File
@@ -31,10 +31,8 @@
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#endif
#include "PyExport.h"
#include "Exception.h"
namespace Swig_python
+12 -12
View File
@@ -31,22 +31,22 @@ if(DOXYGEN_FOUND)
# directory order seems important for correct macro expansion
# (files containing macros definitions must be parsed before the files using them)
SET(DOXYGEN_SOURCE_DIR ${COIN3D_INCLUDE_DIRS}/Inventor/fields/SoSubField.h
${CMAKE_SOURCE_DIR}/src/CXX
${CMAKE_SOURCE_DIR}/src/3rdParty/zipios++
SET(DOXYGEN_SOURCE_DIR ${COIN3D_INCLUDE_DIRS}/Inventor/fields/SoSubField.h
${CMAKE_SOURCE_DIR}/src/3rdParty/PyCXX/CXX
${CMAKE_SOURCE_DIR}/src/3rdParty/zipios++
${CMAKE_SOURCE_DIR}/src/3rdParty
${CMAKE_SOURCE_DIR}/src/Build
${CMAKE_SOURCE_DIR}/src/Base
${CMAKE_BINARY_DIR}/src/Base
${CMAKE_SOURCE_DIR}/src/App
${CMAKE_BINARY_DIR}/src/App
${CMAKE_SOURCE_DIR}/src/Gui
${CMAKE_BINARY_DIR}/src/Gui
${CMAKE_SOURCE_DIR}/src/Build
${CMAKE_SOURCE_DIR}/src/Base
${CMAKE_BINARY_DIR}/src/Base
${CMAKE_SOURCE_DIR}/src/App
${CMAKE_BINARY_DIR}/src/App
${CMAKE_SOURCE_DIR}/src/Gui
${CMAKE_BINARY_DIR}/src/Gui
${CMAKE_SOURCE_DIR}/src/Mod
${CMAKE_BINARY_DIR}/src/Mod
#${CMAKE_SOURCE_DIR}/src/Main #nothing to document there ATM...
${CMAKE_SOURCE_DIR}/src/Main #nothing to document there ATM...
${CMAKE_SOURCE_DIR}/src/Doc
${CMAKE_BINARY_DIR}/src/Doc
${CMAKE_BINARY_DIR}/src/Doc
)
STRING(REGEX REPLACE ";" " " DOXYGEN_INPUT_LIST "${DOXYGEN_SOURCE_DIR}")
+1 -1
View File
@@ -2,7 +2,7 @@
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="modules" visible="yes" title=""/>
<tab type="topics" visible="yes" title=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespaces" visible="yes" title=""/>
<tab type="namespacemembers" visible="yes" title=""/>
+87 -39
View File
@@ -22,64 +22,112 @@
/**
\mainpage FreeCAD source documentation
@mainpage FreeCAD Source Documentation
This is the source documentation of <a href=https://www.freecad.org>FreeCAD</a>.
It is automatically generated from the source code, and describes the different
components of the FreeCAD source code, for both the parts written in C++ and Python.
For general help and documentation about the FreeCAD application and how to use it, head
first to the <a href=https://www.freecad.org/wiki>Wiki Documentation</a>.
Refer to the
<a href=https://www.freecad.org/wiki/The_FreeCAD_source_code>general
introduction to the FreeCAD source code</a> page for a broad view of how the source
code is organized, and browse the modules, classes and namespaces from the menu above.
The <a href=https://www.freecad.org/wiki/Developer_hub>Developers section</a>
of the wiki also contains additional information for developers, and the
<a href=https://www.freecad.org/wiki/Power_users_hub>Powerusers / python scripting
section</a> contains coding documentation that is specifically aimed at python scripting, but
that will also be useful to C++ coders, as most of the APIs are identical or very similar.
For space reasons, this on-line version doesn't include the source code headers nor the full
inheritance graphics. But you can build a full version yourself with everything included,
as explained in <a href=https://freecad.org/wiki/Source_documentation>building
the source code documentation</a>. You can also browse through the <a href=https://github.com/FreeCAD/FreeCAD>source
code on github</a>.
@section toc Table of Contents
- @ref intro_main "Introduction"
- @ref organization "Organization of the API Documentation"
- @ref other_doc "Other Documentation"
\if DEV_DOCUMENTATION
@section intro_main Introduction
\mainpage FreeCAD source documentation
This is the source documentation of [FreeCAD](https://www.freecad.org). It
is automatically generated from the source code and describes the different
components of the FreeCAD source code, for both the parts written in C++
and Python. The next section discusses the organization of this API
documentation and the last section describes other forms of documentation
that FreeCAD has.
@section organization Organization of the API Documentation
This documentation is divided into several topics of which the most important are:
- @ref CORE "Core"
- @ref BASE "Base"
- @ref APP "App"
- @ref GUI "Gui"
- @ref WORKBENCHES "Workbenches"
- @ref EMBEDDED "Embedded 3rd party packages"
Firstly, topic @ref CORE "Core" contains the core namespaces and classes
that all of FreeCAD relies on. This consists of namespace %Base (see topic
@ref BASE "Base") that contains fundamental base classes, the namespace
%App (see topic @ref APP "App") that contains classes for FreeCAD in
command-line mode, and namespace %Gui (see topic @ref GUI "Gui") that
contains the classes for FreeCAD's GUI.
FreeCAD is highly modular and most of its functionality is within modules
that are called @ref WORKBENCHES "Workbenches". Workbenches can be written
in C++ or Python or in a combination of the two. FreeCAD also has external
workbenches that can be loaded from the Addon Manager. These external
workbenches need to be written in Python.
Finally, there is the topic @ref EMBEDDED "Embedded 3rd party packages"
that contains 3rd-party software of which the source is embedded in
FreeCAD. This means that during compilation, these packages will be
compiled and linked to FreeCAD as opposed to non-embedded 3rd-party
packages that are only linked to FreeCAD. An example of an important
non-embedded 3rd party software package is [Open CASCADE
Technology](https://dev.opencascade.org/doc/overview/html/). Its API
documentation can be found
[here](https://dev.opencascade.org/doc/refman/html/index.html).
@section other_doc Other Documentation
For general help and documentation about the FreeCAD application and how to
use it, head first to the [Wiki Documentation](https://www.freecad.org/wiki).
Refer to the [Wiki page "The FreeCAD source
code"](https://www.freecad.org/wiki/The_FreeCAD_source_code) for a broad
view of how the source code is organized, and browse the modules, classes
and namespaces from the menu above.
The [Developer hub](https://www.freecad.org/wiki/Developer_hub) of the wiki
contains additional information for developers and the [Power users /
Python scripting section](https://www.freecad.org/wiki/Power_users_hub)
contains coding documentation that is specifically aimed at Python
scripting, but that will also be useful to C++ coders, as most of the APIs
are identical or very similar.
For space reasons, this on-line version doesn't include the source code
headers nor the full inheritance graphics. But you can build a full version
yourself with everything included, as explained in Wiki page [Source
documentation](https://wiki.freecad.org/Source_documentation#Complete_documentation). You
can also browse through the [source code on
GitHub](https://github.com/FreeCAD/FreeCAD).
@if DEV_DOCUMENTATION
@mainpage FreeCAD source documentation
@image html freecadsplash.png
\image html freecadsplash.png
<b>Welcome to FreeCAD source documentation!</b>
We hope you'll find it a convenient tool to explore, understand and
experiment with the internals of the program.
Being generated from the actual state of the code, this documentation
is by no means a well structured corpus or a textbook, but more an
utility to browse through the sources.
If you seek information on FreeCAD at large, please consult our
<a href="https://www.freecad.org/wiki/Main_Page">Wiki</a>
FreeCAD being a fast moving target, don't hesitate to rebuild an up to
date doc from source as often as needed (\ref makingdocs "more info"). CPU cycles are cheap
nowadays!
nowadays!
The homepage of FreeCAD is <a href="https://www.freecad.org">here</a>.
\endif
@endif
<small>
@GIT_REVISION_INFO@
</small>
*/
/** \namespace std
\brief The Standard namespace for the C++ library
*/
/**
* @namespace std
* @brief The Standard namespace for the C++ library
*/
+7 -7
View File
@@ -1,15 +1,15 @@
/** \defgroup CORE Core
These are the core components of FreeCAD.
/** @defgroup CORE Core
The core components of FreeCAD.
It groups the Base classes, and the main components of FreeCAD core,
spread over their App and Gui sides. Core components are programmed in
C++ but provide a broad Python API too. Most of FreeCAD functionality,
FreeCAD's core consists of Base classes, and the main components of FreeCAD
core, spread over their App and Gui sides. Core components are programmed
in C++ but provide a broad Python API too. Most of FreeCAD functionality,
however, is defined in Workbenches.
*/
/** \defgroup WORKBENCHES Workbenches
/** @defgroup WORKBENCHES Workbenches
*/
/** \defgroup EMBEDDED Embedded 3rd party libraries
/** @defgroup EMBEDDED Embedded 3rd party libraries
Important tools and libraries incorporated to FreeCAD.
*/
+1 -1
View File
@@ -34,7 +34,7 @@
</a>
</li>
<li><a href="$relpath^index.html" title="Index">Index</a></li>
<li><a href="$relpath^modules.html" title="Modules list">Modules</a></li>
<li><a href="$relpath^topics.html" title="Topic list">Topics</a></li>
<li><a href="$relpath^annotated.html" title="Annotated list">Classes</a></li>
</ul>
+75
View File
@@ -0,0 +1,75 @@
from Base.Metadata import export, constmethod
from Base.BaseClass import BaseClass
from typing import Any, Final, Tuple, Dict
@export(
Constructor=True,
Delete=True,
)
class AxisOrigin(BaseClass):
"""
Gui.AxisOrigin class.
Class for creating a Coin3D representation of a coordinate system.
Author: Zheng, Lei (realthunder.dev@gmail.com)
Licence: LGPL
"""
@constmethod
def getElementPicked(self, pickedPoint: Any) -> str:
"""
getElementPicked(pickedPoint) -> str
Returns the picked element name.
pickedPoint : coin.SoPickedPoint
"""
...
@constmethod
def getDetailPath(self, subname: str, path: Any) -> Any:
"""
getDetailPath(subname, path) -> coin.SoDetail or None
Returns Coin detail of a subelement.
Note: Not fully implemented. Currently only returns None.
subname : str
String reference to the subelement.
path: coin.SoPath
Output Coin path leading to the returned element detail.
"""
...
AxisLength: float = 0.0
"""Get/set the axis length."""
LineWidth: float = 0.0
"""Get/set the axis line width for rendering."""
PointSize: float = 0.0
"""Get/set the origin point size for rendering."""
Scale: float = 0.0
"""Get/set auto scaling factor, 0 to disable."""
Plane: Tuple[Any, ...] = ()
"""Get/set axis plane size and distance to axis line."""
Labels: Dict[str, str] = {}
"""
Get/set axis component names as a dictionary.
Available keys are:
'O': origin
'X': x axis
'Y': y axis
'Z': z axis
'XY': xy plane
'XZ': xz plane
'YZ': yz plane
"""
Node: Final[Any] = ...
"""Get the Coin3D node."""
-93
View File
@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="AxisOriginPy"
Twin="AxisOrigin"
TwinPointer="AxisOrigin"
Include="Gui/AxisOrigin.h"
Namespace="Gui"
FatherInclude="Base/BaseClassPy.h"
FatherNamespace="Base"
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="Zheng, Lei" EMail="[email protected]" />
<UserDocu>Gui.AxisOrigin class.
Class for creating a Coin3D representation of a coordinate system.</UserDocu>
</Documentation>
<Methode Name="getElementPicked" Const="true">
<Documentation>
<UserDocu>getElementPicked(pickedPoint) -> str
Returns the picked element name.
pickedPoint : coin.SoPickedPoint</UserDocu>
</Documentation>
</Methode>
<Methode Name="getDetailPath" Const="true">
<Documentation>
<UserDocu>getDetailPath(subname, path) -> coin.SoDetail or None
Returns Coin detail of a subelement.
Note: Not fully implemented. Currently only returns None.
subname : str
String reference to the subelement.
path: coin.SoPath
Output Coin path leading to the returned element detail.</UserDocu>
</Documentation>
</Methode>
<Attribute Name="AxisLength">
<Documentation>
<UserDocu>Get/set the axis length.</UserDocu>
</Documentation>
<Parameter Name="AxisLength" Type="Float" />
</Attribute>
<Attribute Name="LineWidth">
<Documentation>
<UserDocu>Get/set the axis line width for rendering.</UserDocu>
</Documentation>
<Parameter Name="LineWidth" Type="Float" />
</Attribute>
<Attribute Name="PointSize">
<Documentation>
<UserDocu>Get/set the origin point size for rendering.</UserDocu>
</Documentation>
<Parameter Name="PointSize" Type="Float" />
</Attribute>
<Attribute Name="Scale">
<Documentation>
<UserDocu>Get/set auto scaling factor, 0 to disable.</UserDocu>
</Documentation>
<Parameter Name="Scale" Type="Float" />
</Attribute>
<Attribute Name="Plane">
<Documentation>
<UserDocu>Get/set axis plane size and distance to axis line.</UserDocu>
</Documentation>
<Parameter Name="Plane" Type="Tuple" />
</Attribute>
<Attribute Name="Labels">
<Documentation>
<UserDocu>Get/set axis component names as a dictionary.
Available keys are:
'O': origin
'X': x axis
'Y': y axis
'Z': z axis
'XY': xy plane
'XZ': xz plane
'YZ': yz plane</UserDocu>
</Documentation>
<Parameter Name="Labels" Type="Dict" />
</Attribute>
<Attribute Name="Node" ReadOnly='true'>
<Documentation>
<UserDocu>Get the Coin3D node.</UserDocu>
</Documentation>
<Parameter Name="Node" Type="Object" />
</Attribute>
</PythonExport>
</GenerateModel>
+29 -29
View File
@@ -270,38 +270,38 @@ if(FREECAD_USE_PYSIDE)
add_definitions(-DHAVE_PYSIDE${PYSIDE_MAJOR_VERSION})
endif(FREECAD_USE_PYSIDE)
generate_from_xml(DocumentPy)
generate_from_xml(PythonWorkbenchPy)
generate_from_xml(ViewProviderPy)
generate_from_xml(ViewProviderDocumentObjectPy)
generate_from_xml(ViewProviderGeometryObjectPy)
generate_from_xml(ViewProviderExtensionPy)
generate_from_xml(WorkbenchPy)
generate_from_xml(Selection/SelectionObjectPy)
generate_from_xml(LinkViewPy)
generate_from_xml(ViewProviderLinkPy)
generate_from_xml(AxisOriginPy)
generate_from_xml(CommandPy)
generate_from_xml(Navigation/NavigationStylePy)
generate_from_py(Document)
generate_from_py(PythonWorkbench)
generate_from_py(ViewProvider)
generate_from_py(ViewProviderDocumentObject)
generate_from_py(ViewProviderGeometryObject)
generate_from_py(ViewProviderExtension)
generate_from_py(Workbench)
generate_from_py(Selection/SelectionObject)
generate_from_py(LinkView)
generate_from_py(ViewProviderLink)
generate_from_py(AxisOrigin)
generate_from_py(Command)
generate_from_py(Navigation/NavigationStyle)
generate_embed_from_py(FreeCADGuiInit GuiInitScript.h)
# The XML files
SET(FreeCADGui_XML_SRCS
ViewProviderDocumentObjectPy.xml
ViewProviderGeometryObjectPy.xml
ViewProviderPy.xml
ViewProviderExtensionPy.xml
PythonWorkbenchPy.xml
WorkbenchPy.xml
Selection/SelectionObjectPy.xml
DocumentPy.xml
LinkViewPy.xml
ViewProviderLinkPy.xml
AxisOriginPy.xml
CommandPy.xml
# The Pyi files
SET(FreeCADGui_Pyi_SRCS
ViewProviderDocumentObject.pyi
ViewProviderGeometryObject.pyi
ViewProvider.pyi
ViewProviderExtension.pyi
PythonWorkbench.pyi
Workbench.pyi
Selection/SelectionObject.pyi
Document.pyi
LinkView.pyi
ViewProviderLink.pyi
AxisOrigin.pyi
Command.pyi
)
SOURCE_GROUP("XML" FILES ${FreeCADApp_XML_SRCS})
SOURCE_GROUP("Pyi" FILES ${FreeCADGui_Pyi_SRCS})
# The 3D Connexion SDK files
if(FREECAD_USE_3DCONNEXION_LEGACY AND MSVC)
@@ -947,7 +947,7 @@ SET(Navigation_CPP_SRCS
SET(Navigation_SRCS
${Navigation_CPP_SRCS}
Navigation/NavigationStyle.h
Navigation/NavigationStylePy.xml
Navigation/NavigationStyle.pyi
Navigation/GestureNavigationStyle.h
Navigation/NavigationAnimator.h
Navigation/NavigationAnimation.h
+2 -2
View File
@@ -748,7 +748,7 @@ QString CallTipsList::stripWhiteSpace(const QString& str) const
{
QString stripped = str;
QStringList lines = str.split(QLatin1String("\n"));
int minspace=INT_MAX;
int minspace=std::numeric_limits<int>::max();
int line=0;
for (QStringList::iterator it = lines.begin(); it != lines.end(); ++it, ++line) {
if (it->size() > 0 && line > 0) {
@@ -766,7 +766,7 @@ QString CallTipsList::stripWhiteSpace(const QString& str) const
}
// remove all leading tabs from each line
if (minspace > 0 && minspace < INT_MAX) {
if (minspace > 0 && minspace < std::numeric_limits<int>::max()) {
int line=0;
QStringList strippedlines;
for (QStringList::iterator it = lines.begin(); it != lines.end(); ++it, ++line) {
+8 -7
View File
@@ -109,20 +109,21 @@ Clipping::Clipping(Gui::View3DInventor* view, QWidget* parent)
d->ui.setupUi(this);
setupConnections();
d->ui.clipView->setRange(-INT_MAX, INT_MAX);
constexpr int max = std::numeric_limits<int>::max();
d->ui.clipView->setRange(-max, max);
d->ui.clipView->setSingleStep(0.1f);
d->ui.clipX->setRange(-INT_MAX, INT_MAX);
d->ui.clipX->setRange(-max, max);
d->ui.clipX->setSingleStep(0.1f);
d->ui.clipY->setRange(-INT_MAX, INT_MAX);
d->ui.clipY->setRange(-max, max);
d->ui.clipY->setSingleStep(0.1f);
d->ui.clipZ->setRange(-INT_MAX, INT_MAX);
d->ui.clipZ->setRange(-max, max);
d->ui.clipZ->setSingleStep(0.1f);
d->ui.dirX->setRange(-INT_MAX, INT_MAX);
d->ui.dirX->setRange(-max, max);
d->ui.dirX->setSingleStep(0.1f);
d->ui.dirY->setRange(-INT_MAX, INT_MAX);
d->ui.dirY->setRange(-max, max);
d->ui.dirY->setSingleStep(0.1f);
d->ui.dirZ->setRange(-INT_MAX, INT_MAX);
d->ui.dirZ->setRange(-max, max);
d->ui.dirZ->setSingleStep(0.1f);
d->ui.dirZ->setValue(1.0f);
+183
View File
@@ -0,0 +1,183 @@
from Base.Metadata import constmethod
from Base.PyObjectBase import PyObjectBase
from typing import Any, Dict, List, Optional
class Command(PyObjectBase):
"""
FreeCAD Python wrapper of Command functions
Author: Werner Mayer (wmayer[at]users.sourceforge.net)
Licence: LGPL
"""
@staticmethod
def get(name: str) -> Optional["Command"]:
"""
get(name) -> Gui.Command or None
Get a given command by name or None if it doesn't exist.
name : str
Command name.
"""
...
@staticmethod
def update() -> None:
"""
update() -> None
Update active status of all commands.
"""
...
@staticmethod
def listAll() -> List[str]:
"""
listAll() -> list of str
Returns the name of all commands.
"""
...
@staticmethod
def listByShortcut(string: str, useRegExp: bool = False) -> List[str]:
"""
listByShortcut(string, useRegExp=False) -> list of str
Returns a list of all commands, filtered by shortcut.
Shortcuts are converted to uppercase and spaces removed
prior to comparison.
string : str
Shortcut to be searched.
useRegExp : bool
Filter using regular expression.
"""
...
def run(self, item: int = 0) -> None:
"""
run(item=0) -> None
Runs the given command.
item : int
Item to be run.
"""
...
@constmethod
def isActive(self) -> bool:
"""
isActive() -> bool
Returns True if the command is active, False otherwise.
"""
...
def getShortcut(self) -> str:
"""
getShortcut() -> str
Returns string representing shortcut key accelerator for command.
"""
...
def setShortcut(self, string: str) -> bool:
"""
setShortcut(string) -> bool
Sets shortcut for given command, returns True for success.
string : str
Shortcut to be set.
"""
...
def resetShortcut(self) -> bool:
"""
resetShortcut() -> bool
Resets shortcut for given command back to the default, returns True for success.
"""
...
def getInfo(self) -> Dict[Any, Any]:
"""
getInfo() -> dict
Return information about this command.
"""
...
def getAction(self) -> List[Any]:
"""
getAction() -> list of QAction
Return the associated QAction object.
"""
...
@staticmethod
def createCustomCommand(
*,
macroFile: str,
menuText: str,
toolTip: str,
whatsThis: str,
statusTip: str,
pixmap: str,
shortcut: str
) -> str:
"""
createCustomCommand(macroFile, menuText, toolTip, whatsThis, statusTip, pixmap, shortcut) -> str
Create a custom command for a macro. Returns name of the created command.
macroFile : str
Macro file.
menuText : str
Menu text. Optional.
toolTip : str
Tool tip text. Optional.
whatsThis : str
`What's this?` text. Optional.
statusTip : str
Status tip text. Optional.
pixmap : str
Pixmap name. Optional.
shortcut : str
Shortcut key sequence. Optional.
"""
...
@staticmethod
def removeCustomCommand(name: str) -> bool:
"""
removeCustomCommand(name) -> bool
Remove the custom command if it exists.
Given the name of a custom command, this removes that command.
It is not an error to remove a non-existent command, the function
simply does nothing in that case.
Returns True if something was removed, or False if not.
name : str
Command name.
"""
...
@staticmethod
def findCustomCommand(name: str) -> Optional[str]:
"""
findCustomCommand(name) -> str or None
Given the name of a macro, return the name of the custom command for that macro
or None if there is no command matching that macro script name.
name : str
Macro name.
"""
...
-157
View File
@@ -1,157 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PyObjectBase"
Name="CommandPy"
Twin="Command"
TwinPointer="Command"
Include="Gui/Command.h"
FatherInclude="Base/PyObjectBase.h"
Namespace="Gui"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer[at]users.sourceforge.net" />
<UserDocu>FreeCAD Python wrapper of Command functions</UserDocu>
</Documentation>
<Methode Name="get" Static='true'>
<Documentation>
<UserDocu>get(name) -> Gui.Command or None
Get a given command by name or None if it doesn't exist.
name : str
Command name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="update" Static='true'>
<Documentation>
<UserDocu>update() -> None
Update active status of all commands.</UserDocu>
</Documentation>
</Methode>
<Methode Name="listAll" Static='true'>
<Documentation>
<UserDocu>listAll() -> list of str
Returns the name of all commands.</UserDocu>
</Documentation>
</Methode>
<Methode Name="listByShortcut" Static='true'>
<Documentation>
<UserDocu>listByShortcut(string, useRegExp=False) -> list of str
Returns a list of all commands, filtered by shortcut.
Shortcuts are converted to uppercase and spaces removed
prior to comparison.
string : str
Shortcut to be searched.
useRegExp : bool
Filter using regular expression.</UserDocu>
</Documentation>
</Methode>
<Methode Name="run">
<Documentation>
<UserDocu>run(item=0) -> None
Runs the given command.
item : int
Item to be run.</UserDocu>
</Documentation>
</Methode>
<Methode Name="isActive" Const="true">
<Documentation>
<UserDocu>isActive() -> bool
Returns True if the command is active, False otherwise.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getShortcut">
<Documentation>
<UserDocu>getShortcut() -> str
Returns string representing shortcut key accelerator for command.</UserDocu>
</Documentation>
</Methode>
<Methode Name="setShortcut">
<Documentation>
<UserDocu>setShortcut(string) -> bool
Sets shortcut for given command, returns True for success.
string : str
Shortcut to be set.</UserDocu>
</Documentation>
</Methode>
<Methode Name="resetShortcut">
<Documentation>
<UserDocu>resetShortcut() -> bool
Resets shortcut for given command back to the default, returns True for success.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getInfo">
<Documentation>
<UserDocu>getInfo() -> dict
Return information about this command.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getAction">
<Documentation>
<UserDocu>getAction() -> list of QAction
Return the associated QAction object.</UserDocu>
</Documentation>
</Methode>
<Methode Name="createCustomCommand" Static='true' Keyword='true'>
<Documentation>
<UserDocu>createCustomCommand(macroFile, menuText, toolTip, whatsThis, statusTip, pixmap, shortcut) -> str
Create a custom command for a macro. Returns name of the created command.
macroFile : str
Macro file.
menuText : str
Menu text. Optional.
toolTip : str
Tool tip text. Optional.
whatsThis : str
`What's this?` text. Optional.
statusTip : str
Status tip text. Optional.
pixmap : str
Pixmap name. Optional.
shortcut : str
Shortcut key sequence. Optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeCustomCommand" Static='true'>
<Documentation>
<UserDocu>removeCustomCommand(name) -> bool
Remove the custom command if it exists.
Given the name of a custom command, this removes that command.
It is not an error to remove a non-existent command, the function
simply does nothing in that case.
Returns True if something was removed, or False if not.
name : str
Command name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="findCustomCommand" Static='true'>
<Documentation>
<UserDocu>findCustomCommand(name) -> str or None
Given the name of a macro, return the name of the custom command for that macro
or None if there is no command matching that macro script name.
name : str
Macro name.</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>
+1 -1
View File
@@ -166,7 +166,7 @@ SbVec3f DemoMode::getDirection(Gui::View3DInventor* view) const
SbRotation inv = rot.inverse();
SbVec3f vec(this->viewAxis);
inv.multVec(vec, vec);
if (vec.length() < FLT_EPSILON) {
if (vec.length() < std::numeric_limits<float>::epsilon()) {
vec = this->viewAxis;
}
vec.normalize();
+2 -2
View File
@@ -905,7 +905,7 @@ void ParameterValue::onCreateUIntItem()
DlgInputDialogImp::UIntBox);
dlg.setWindowTitle(QObject::tr("New unsigned item"));
UIntSpinBox* edit = dlg.getUIntBox();
edit->setRange(0, UINT_MAX);
edit->setRange(0, std::numeric_limits<unsigned>::max());
if (dlg.exec() == QDialog::Accepted) {
QString value = edit->text();
unsigned long val = value.toULong(&ok);
@@ -1249,7 +1249,7 @@ void ParameterUInt::changeValue()
DlgInputDialogImp::UIntBox);
dlg.setWindowTitle(QObject::tr("Change value"));
UIntSpinBox* edit = dlg.getUIntBox();
edit->setRange(0, UINT_MAX);
edit->setRange(0, std::numeric_limits<unsigned>::max());
edit->setValue(text(2).toULong());
if (dlg.exec() == QDialog::Accepted) {
QString value = edit->text();
+2 -1
View File
@@ -672,13 +672,14 @@ void Document::setEditingTransform(const Base::Matrix4D &mat) {
void Document::resetEdit() {
bool vpIsNotNull = d->_editViewProvider != nullptr;
bool vpHasChanged = d->_editViewProvider != d->_editViewProviderPrevious;
int modeToRestore = d->_editModePrevious;
Gui::ViewProvider* vpToRestore = d->_editViewProviderPrevious;
bool shouldRestorePrevious = d->_editWantsRestorePrevious;
Application::Instance->setEditDocument(nullptr);
if (vpIsNotNull && shouldRestorePrevious) {
if (vpIsNotNull && vpHasChanged && shouldRestorePrevious) {
setEdit(vpToRestore, modeToRestore);
}
}
+255
View File
@@ -0,0 +1,255 @@
from Base.Metadata import constmethod
from Base.Persistence import Persistence
from Base.Matrix import Matrix
from typing import Any, Final, List, Optional
class Document(Persistence):
"""
This is a Document class
Author: Werner Mayer (wmayer@users.sourceforge.net)
Licence: LGPL
"""
def show(self, objName: str) -> None:
"""
show(objName) -> None
Show an object.
objName : str
Name of the `Gui.ViewProvider` to show.
"""
...
def hide(self, objName: str) -> None:
"""
hide(objName) -> None
Hide an object.
objName : str
Name of the `Gui.ViewProvider` to hide.
"""
...
def setPos(self, objName: str, matrix: Matrix) -> None:
"""
setPos(objName, matrix) -> None
Set the position of an object.
objName : str
Name of the `Gui.ViewProvider`.
matrix : Base.Matrix
Transformation to apply on the object.
"""
...
def setEdit(self, obj: Any, mod: int = 0, subName: Optional[str] = None) -> bool:
"""
setEdit(obj, mod=0, subName) -> bool
Set an object in edit mode.
obj : str, App.DocumentObject, Gui.ViewPrivider
Object to set in edit mode.
mod : int
Edit mode.
subName : str
Subelement name. Optional.
"""
...
def getInEdit(self) -> Optional[Any]:
"""
getInEdit() -> Gui.ViewProviderDocumentObject or None
Returns the current object in edit mode or None if there is no such object.
"""
...
def resetEdit(self) -> None:
"""
resetEdit() -> None
End the current editing.
"""
...
def addAnnotation(self, annoName: str, fileName: str, modName: str) -> None:
"""
addAnnotation(annoName, fileName, modName) -> None
Add an Inventor object from a file.
annoName : str
Annotation name.
fileName : str
File name.
modName : str
Display mode name. Optional.
"""
...
def update(self) -> None:
"""
update() -> None
Update the view representations of all objects.
"""
...
def getObject(self, objName: str) -> Optional[Any]:
"""
getObject(objName) -> object or None
Return the object with the given name. If no one exists, return None.
ObjName : str
Object name.
"""
...
def activeObject(self) -> Optional[Any]:
"""
activeObject() -> object or None
The active object of the document. Deprecated, use ActiveObject.
"""
...
def activeView(self) -> Optional[Any]:
"""
activeView() -> object or None
The active view of the document. Deprecated, use ActiveView.
"""
...
def createView(self, type: str) -> Optional[Any]:
"""
createView(type) -> object or None
Return a newly created view of a given type.
type : str
Type name.
"""
...
@constmethod
def mdiViewsOfType(self, type: str) -> List[Any]:
"""
mdiViewsOfType(type) -> list of MDIView
Return a list of mdi views of a given type.
type : str
Type name.
"""
...
def save(self) -> bool:
"""
save() -> bool
Attempts to save the document
"""
...
def saveAs(self) -> bool:
"""
saveAs() -> bool
Attempts to save the document under a new name
"""
...
def sendMsgToViews(self, msg: str) -> None:
"""
sendMsgToViews(msg) -> None
Send a message to all views of the document.
msg : str
"""
...
def mergeProject(self, fileName: str) -> None:
"""
mergeProject(fileName) -> None
Merges this document with another project file.
fileName : str
File name.
"""
...
def toggleTreeItem(
self, obj: Any, mod: int = 0, subName: Optional[str] = None
) -> None:
"""
toggleTreeItem(obj, mod=0, subName) -> None
Change TreeItem of a document object.
obj : App.DocumentObject
mod : int
Item mode.
0: Toggle, 1: Collapse, 2: Expand, 3: Expand path.
subName : str
Subelement name. Optional.
"""
...
def scrollToTreeItem(self, obj: Any) -> None:
"""
scrollToTreeItem(obj) -> None
Scroll the tree view to the item of a view object.
obj : Gui.ViewProviderDocumentObject
"""
...
def toggleInSceneGraph(self, obj: Any) -> None:
"""
toggleInSceneGraph(obj) -> None
Add or remove view object from scene graph of all views depending
on its canAddToSceneGraph().
obj : Gui.ViewProvider
"""
...
ActiveObject: Any = ...
"""The active object of the document."""
ActiveView: Any = ...
"""The active view of the document."""
EditingTransform: Any = ...
"""The editing transformation matrix."""
InEditInfo: Any = ...
"""A tuple(obj,subname,subElement,editMode) of editing object reference, or None if no object is in edit."""
EditMode: Final[int] = 0
"""Current edit mode. Only meaningful when there is a current object in edit."""
Document: Final[Any] = ...
"""The related App document to this Gui document."""
Transacting: Final[bool] = False
"""Indicate whether the document is undoing/redoing."""
Modified: bool = False
"""Returns True if the document is marked as modified, and False otherwise."""
TreeRootObjects: Final[List[Any]] = []
"""The list of tree root objects."""
-263
View File
@@ -1,263 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PersistencePy"
Name="DocumentPy"
Twin="Document"
TwinPointer="Document"
Include="Gui/Document.h"
Namespace="Gui"
FatherInclude="Base/PersistencePy.h"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="[email protected]" />
<UserDocu>This is a Document class</UserDocu>
</Documentation>
<Methode Name="show">
<Documentation>
<UserDocu>show(objName) -> None
Show an object.
objName : str
Name of the `Gui.ViewProvider` to show.</UserDocu>
</Documentation>
</Methode>
<Methode Name="hide">
<Documentation>
<UserDocu>hide(objName) -> None
Hide an object.
objName : str
Name of the `Gui.ViewProvider` to hide.</UserDocu>
</Documentation>
</Methode>
<Methode Name="setPos">
<Documentation>
<UserDocu>setPos(objName, matrix) -> None
Set the position of an object.
objName : str
Name of the `Gui.ViewProvider`.
matrix : Base.Matrix
Transformation to apply on the object.</UserDocu>
</Documentation>
</Methode>
<Methode Name="setEdit">
<Documentation>
<UserDocu>setEdit(obj, mod=0, subName) -> bool
Set an object in edit mode.
obj : str, App.DocumentObject, Gui.ViewPrivider
Object to set in edit mode.
mod : int
Edit mode.
subName : str
Subelement name. Optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getInEdit">
<Documentation>
<UserDocu>getInEdit() -> Gui.ViewProviderDocumentObject or None
Returns the current object in edit mode or None if there is no such object.</UserDocu>
</Documentation>
</Methode>
<Methode Name="resetEdit">
<Documentation>
<UserDocu>resetEdit() -> None
End the current editing.</UserDocu>
</Documentation>
</Methode>
<Methode Name="addAnnotation">
<Documentation>
<UserDocu>addAnnotation(annoName, fileName, modName) -> None
Add an Inventor object from a file.
annoName : str
Annotation name.
fileName : str
File name.
modName : str
Display mode name. Optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="update">
<Documentation>
<UserDocu>update() -> None
Update the view representations of all objects.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getObject">
<Documentation>
<UserDocu>getObject(objName) -> object or None
Return the object with the given name. If no one exists, return None.
ObjName : str
Object name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="activeObject">
<Documentation>
<UserDocu>activeObject() -> object or None
The active object of the document. Deprecated, use ActiveObject.</UserDocu>
</Documentation>
</Methode>
<Methode Name="activeView">
<Documentation>
<UserDocu>activeView() -> object or None
The active view of the document. Deprecated, use ActiveView.</UserDocu>
</Documentation>
</Methode>
<Methode Name="createView">
<Documentation>
<UserDocu>createView(type) -> object or None
Return a newly created view of a given type.
type : str
Type name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="mdiViewsOfType" Const="true">
<Documentation>
<UserDocu>mdiViewsOfType(type) -> list of MDIView
Return a list of mdi views of a given type.
type : str
Type name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="save">
<Documentation>
<UserDocu>save() -> bool
Attempts to save the document</UserDocu>
</Documentation>
</Methode>
<Methode Name="saveAs">
<Documentation>
<UserDocu>saveAs() -> bool
Attempts to save the document under a new name</UserDocu>
</Documentation>
</Methode>
<Methode Name="sendMsgToViews">
<Documentation>
<UserDocu>sendMsgToViews(msg) -> None
Send a message to all views of the document.
msg : str</UserDocu>
</Documentation>
</Methode>
<Methode Name="mergeProject">
<Documentation>
<UserDocu>mergeProject(fileName) -> None
Merges this document with another project file.
fileName : str
File name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="toggleTreeItem">
<Documentation>
<UserDocu>toggleTreeItem(obj, mod=0, subName) -> None
Change TreeItem of a document object.
obj : App.DocumentObject
mod : int
Item mode.
0: Toggle, 1: Collapse, 2: Expand, 3: Expand path.
subName : str
Subelement name. Optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="scrollToTreeItem">
<Documentation>
<UserDocu>scrollToTreeItem(obj) -> None
Scroll the tree view to the item of a view object.
obj : Gui.ViewProviderDocumentObject</UserDocu>
</Documentation>
</Methode>
<Methode Name="toggleInSceneGraph">
<Documentation>
<UserDocu>toggleInSceneGraph(obj) -> None
Add or remove view object from scene graph of all views depending
on its canAddToSceneGraph().
obj : Gui.ViewProvider</UserDocu>
</Documentation>
</Methode>
<Attribute Name="ActiveObject" ReadOnly="false">
<Documentation>
<UserDocu>The active object of the document.</UserDocu>
</Documentation>
<Parameter Name="ActiveObject" Type="Object" />
</Attribute>
<Attribute Name="ActiveView" ReadOnly="false">
<Documentation>
<UserDocu>The active view of the document.</UserDocu>
</Documentation>
<Parameter Name="ActiveView" Type="Object" />
</Attribute>
<Attribute Name="EditingTransform">
<Documentation>
<UserDocu>The editing transformation matrix.</UserDocu>
</Documentation>
<Parameter Name="EditingTransform" Type="Object" />
</Attribute>
<Attribute Name="InEditInfo">
<Documentation>
<UserDocu>A tuple(obj,subname,subElement,editMode) of editing object reference, or None if no object is in edit.</UserDocu>
</Documentation>
<Parameter Name="InEditInfo" Type="Object" />
</Attribute>
<Attribute Name="EditMode" ReadOnly="true">
<Documentation>
<UserDocu>Current edit mode. Only meaningful when there is a current object in edit.</UserDocu>
</Documentation>
<Parameter Name="EditMode" Type="Long" />
</Attribute>
<Attribute Name="Document" ReadOnly="true">
<Documentation>
<UserDocu>The related App document to this Gui document.</UserDocu>
</Documentation>
<Parameter Name="Document" Type="Object" />
</Attribute>
<Attribute Name="Transacting" ReadOnly="true">
<Documentation>
<UserDocu>Indicate whether the document is undoing/redoing.</UserDocu>
</Documentation>
<Parameter Name="Transacting" Type="Boolean" />
</Attribute>
<Attribute Name="Modified">
<Documentation>
<UserDocu>Returns True if the document is marked as modified, and False otherwise.</UserDocu>
</Documentation>
<Parameter Name="Modified" Type="Boolean" />
</Attribute>
<Attribute Name="TreeRootObjects" ReadOnly="true">
<Documentation>
<UserDocu>The list of tree root objects.</UserDocu>
</Documentation>
<Parameter Name="TreeRootObjects" Type="List" />
</Attribute>
</PythonExport>
</GenerateModel>
+2 -2
View File
@@ -152,8 +152,8 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
spinBox = new QuantitySpinBox(mdi);
spinBox->setUnit(Base::Unit::Length);
spinBox->setMinimum(-INT_MAX);
spinBox->setMaximum(INT_MAX);
spinBox->setMinimum(-std::numeric_limits<int>::max());
spinBox->setMaximum(std::numeric_limits<int>::max());
spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
spinBox->setKeyboardTracking(false);
spinBox->setFocusPolicy(Qt::ClickFocus); // prevent passing focus with tab.
+9 -4
View File
@@ -139,14 +139,15 @@ EditorView::EditorView(TextEdit* editor, QWidget* parent)
d->activityTimer = new QTimer(this);
// clang-format off
connectionList <<
connect(d->activityTimer, &QTimer::timeout,
this, &EditorView::checkTimestamp);
this, &EditorView::checkTimestamp) <<
connect(d->textEdit->document(), &QTextDocument::modificationChanged,
this, &EditorView::setWindowModified);
this, &EditorView::setWindowModified) <<
connect(d->textEdit->document(), &QTextDocument::undoAvailable,
this, &EditorView::undoAvailable);
this, &EditorView::undoAvailable) <<
connect(d->textEdit->document(), &QTextDocument::redoAvailable,
this, &EditorView::redoAvailable);
this, &EditorView::redoAvailable) <<
connect(d->textEdit->document(), &QTextDocument::contentsChange,
this, &EditorView::contentsChange);
// clang-format on
@@ -156,6 +157,10 @@ EditorView::EditorView(TextEdit* editor, QWidget* parent)
EditorView::~EditorView()
{
d->activityTimer->stop();
// to avoid the assert introduced a debug version of Qt >6.3. See QTBUG-105473
for (auto conn : connectionList) { // NOLINT(performance-for-range-copy)
disconnect(conn);
}
delete d->activityTimer;
delete d;
getWindowParameter()->Detach(this);
+1
View File
@@ -116,6 +116,7 @@ private:
private:
EditorViewP* d;
QList <QMetaObject::Connection> connectionList;
};
class PythonEditor;
+2 -2
View File
@@ -71,8 +71,8 @@ InputField::InputField(QWidget * parent)
ExpressionWidget(),
validInput(true),
actUnitValue(0),
Maximum(DOUBLE_MAX),
Minimum(-DOUBLE_MAX),
Maximum(std::numeric_limits<double>::max()),
Minimum(-std::numeric_limits<double>::max()),
StepSize(1.0),
HistorySize(5),
SaveSize(5)
+13 -9
View File
@@ -25,10 +25,8 @@
#ifndef _PreComp_
#include <array>
#include <boost/math/constants/constants.hpp>
#ifdef FC_OS_WIN32
#define _USE_MATH_DEFINES
#endif
#include <cmath>
#include <numbers>
#ifdef FC_OS_MACOSX
#include <OpenGL/gl.h>
#else
@@ -39,17 +37,23 @@
#include "SoFCBackgroundGradient.h"
static const std::array <GLfloat[2], 32> big_circle = []{
static const float pi2 = boost::math::constants::two_pi<float>();
constexpr float pi = std::numbers::pi_v<float>;
constexpr float sqrt2 = std::numbers::sqrt2_v<float>;
std::array <GLfloat[2], 32> result; int c = 0;
for (GLfloat i = 0; i < pi2; i += pi2 / 32, c++) {
result[c][0] = M_SQRT2*cosf(i); result[c][1] = M_SQRT2*sinf(i);
for (GLfloat i = 0; i < 2 * pi; i += 2 * pi / 32, c++) {
result[c][0] = sqrt2 * cosf(i);
result[c][1] = sqrt2 * sinf(i);
}
return result; }();
static const std::array <GLfloat[2], 32> small_oval = []{
static const float pi2 = boost::math::constants::two_pi<float>();
constexpr float pi = std::numbers::pi_v<float>;
constexpr float sqrt2 = std::numbers::sqrt2_v<float>;
static const float sqrt1_2 = std::sqrt(1 / 2.F);
std::array <GLfloat[2], 32> result; int c = 0;
for (GLfloat i = 0; i < pi2; i += pi2 / 32, c++) {
result[c][0] = 0.3*M_SQRT2*cosf(i); result[c][1] = M_SQRT1_2*sinf(i);
for (GLfloat i = 0; i < 2 * pi; i += 2 * pi / 32, c++) {
result[c][0] = 0.3 * sqrt2 * cosf(i);
result[c][1] = sqrt1_2 * sinf(i);
}
return result; }();
+4 -2
View File
@@ -45,7 +45,7 @@ using namespace Gui;
* The internationalization of FreeCAD makes heavy use of the internationalization
* support of Qt. For more details refer to your Qt documentation.
*
* \section stepbystep Step by step
* \section stepbystep_language Step by step
* To integrate a new language into FreeCAD or one of its application modules
* you have to perform the following steps:
*
@@ -132,6 +132,7 @@ void Translator::destruct ()
Translator::Translator()
{
// This is needed for Qt's lupdate
// clang-format off
d = new TranslatorP;
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Afrikaans" )] = "af";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Arabic" )] = "ar";
@@ -143,6 +144,7 @@ Translator::Translator()
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Chinese Traditional" )] = "zh-TW";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Croatian" )] = "hr";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Czech" )] = "cs";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Danish" )] = "da";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Dutch" )] = "nl";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("English" )] = "en";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Filipino" )] = "fil";
@@ -176,7 +178,6 @@ Translator::Translator()
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Ukrainian" )] = "uk";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Valencian" )] = "val-ES";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Vietnamese" )] = "vi";
d->mapLanguageTopLevelDomain[QT_TR_NOOP("Danish")] = "da";
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General");
auto entries = hGrp->GetASCII("AdditionalLanguageDomainEntries", "");
@@ -190,6 +191,7 @@ Translator::Translator()
QString tld = match.captured(2);
d->mapLanguageTopLevelDomain[language.toStdString()] = tld.toStdString();
}
// clang-format on
d->activatedLanguage = "English";
+182
View File
@@ -0,0 +1,182 @@
from Base.Metadata import export, constmethod
from Base.BaseClass import BaseClass
from typing import Any, Final, List, Dict, Tuple, overload
@export(
Include="Gui/ViewProviderLink.h",
Constructor=True,
Delete=True,
)
class LinkView(BaseClass):
"""
Helper class to link to a view object
Author: Zheng, Lei (realthunder.dev@gmail.com)
Licence: LGPL
"""
def reset(self) -> None:
"""
Reset the link view and clear the links
"""
...
def setMaterial(self, material: Any) -> None:
"""
setMaterial(Material): set the override material of the entire linked object
setMaterial([Material,...]): set the materials for the elements of the link
array/group.
setMaterial({Int:Material,...}): set the material for the elements of the
link array/group by index.
If material is None, then the material is unset. If the material of an element
is unset, it defaults to the override material of the linked object, if there
is one
"""
...
@overload
def setMaterial(self, material: None) -> None: ...
@overload
def setMaterial(self, material: Any) -> None: ...
@overload
def setMaterial(self, material: List[Any]) -> None: ...
@overload
def setMaterial(self, material: Dict[int, Any]) -> None: ...
def setType(self, type: int, sublink: bool = True) -> None:
"""
setType(type, sublink=True): set the link type.
type=0: override transformation and visibility
type=1: override visibility
type=2: no override
type=-1: sub-object link with override visibility
type=-2: sub-object link with override transformation and visibility
sublink: auto delegate to the sub-object references in the link, if there is
one and only one.
"""
...
@overload
def setType(self, type: int) -> None: ...
@overload
def setType(self, type: int, sublink: bool) -> None: ...
def setTransform(self, matrix: Any) -> None:
"""
setTransform(matrix): set transformation of the linked object
setTransform([matrix,...]): set transformation for the elements of the link
array/group
setTransform({index:matrix,...}): set transformation for elements of the link
array/group by index
"""
...
@overload
def setTransform(self, matrix: Any) -> None: ...
@overload
def setTransform(self, matrix: List[Any]) -> None: ...
@overload
def setTransform(self, matrix: Dict[int, Any]) -> None: ...
def setChildren(
self, children: List[Any], vis: List[Any] = [], type: int = 0
) -> None:
"""
setChildren([obj...],vis=[],type=0)
Group a list of children objects. Note, this mode of operation is incompatible
with link array. Calling this function will deactivate link array. And calling
setSize() will reset all linked children.
vis: initial visibility status of the children
type: children linking type,
0: override transformation and visibility,
1: override visibility,
2: override none.
"""
...
def setLink(self, obj: Any, subname: Any = None) -> None:
"""
setLink(object): Set the link
setLink(object, subname): Set the link with a sub-object reference
setLink(object, [subname,...]): Set the link with a list of sub object references
object: The linked document object or its view object
subname: a string or tuple/list of strings sub-name references to sub object
or sub elements (e.g. Face1, Edge2) belonging to the linked object.
The sub-name must end with a '.' if it is referencing an sub-object,
or else it is considered a sub-element reference.
"""
...
@overload
def setLink(self, obj: Any) -> None: ...
@overload
def setLink(self, obj: Any, subname: str) -> None: ...
@overload
def setLink(self, obj: Any, subname: List[str]) -> None: ...
def getDetailPath(self, element: Any) -> Tuple[Any, Any]:
"""
getDetailPath(element): get the 3d path an detail of an element.
Return a tuple(path,detail) for the coin3D SoPath and SoDetail of the element
"""
...
def getElementPicked(self, pickPoint: Any) -> Any:
"""
getElementPicked(pickPoint): get the element under a 3d pick point.
"""
...
def getBoundBox(self, vobj: Any = None) -> Any:
"""
getBoundBox(vobj=None): get the bounding box.
"""
...
@constmethod
def getChildren(self) -> Any:
"""
Get children view objects
"""
...
LinkedView: Final[Any] = ...
"""The linked view object"""
SubNames: Final[Any] = ...
"""The sub-object reference of the link"""
RootNode: Final[Any] = ...
"""A pivy node holding the cloned representation of the linked view object"""
Owner: Any = ...
"""The owner view object of this link handle"""
Visibilities: Any = ...
"""Get/set the child element visibility"""
Count: int = 0
"""Set the element size to create an array of linked object"""
-165
View File
@@ -1,165 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="LinkViewPy"
Twin="LinkView"
TwinPointer="LinkView"
Include="Gui/ViewProviderLink.h"
Namespace="Gui"
FatherInclude="Base/BaseClassPy.h"
FatherNamespace="Base"
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="Zheng, Lei" EMail="[email protected]" />
<UserDocu>Helper class to link to a view object</UserDocu>
</Documentation>
<Methode Name="reset">
<Documentation>
<UserDocu>Reset the link view and clear the links</UserDocu>
</Documentation>
</Methode>
<Methode Name="setMaterial">
<Documentation>
<UserDocu>
setMaterial(Material): set the override material of the entire linked object
setMaterial([Material,...]): set the materials for the elements of the link
array/group.
setMaterial({Int:Material,...}): set the material for the elements of the
link array/group by index.
If material is None, then the material is unset. If the material of an element
is unset, it defaults to the override material of the linked object, if there
is one
</UserDocu>
</Documentation>
</Methode>
<Methode Name="setType">
<Documentation>
<UserDocu>
setType(type, sublink=True): set the link type.
type=0: override transformation and visibility
type=1: override visibility
type=2: no override
type=-1: sub-object link with override visibility
type=-2: sub-object link with override transformation and visibility
sublink: auto delegate to the sub-object references in the link, if there is
one and only one.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="setTransform">
<Documentation>
<UserDocu>
setTransform(matrix): set transformation of the linked object
setTransform([matrix,...]): set transformation for the elements of the link
array/group
setTransform({index:matrix,...}): set transformation for elements of the link
array/group by index
</UserDocu>
</Documentation>
</Methode>
<Methode Name="setChildren">
<Documentation>
<UserDocu>
setChildren([obj...],vis=[],type=0)
Group a list of children objects. Note, this mode of operation is incompatible
with link array. Calling this function will deactivate link array. And calling
setSize() will reset all linked children.
vis: initial visibility status of the children
type: children linking type,
0: override transformation and visibility,
1: override visibility,
2: override none.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="setLink">
<Documentation>
<UserDocu>
setLink(object): Set the link
setLink(object, subname): Set the link with a sub-object reference
setLink(object, [subname,...]): Set the link with a list of sub object references
object: The linked document object or its view object
subname: a string or tuple/list of strings sub-name references to sub object
or sub elements (e.g. Face1, Edge2) belonging to the linked object.
The sub-name must end with a '.' if it is referencing an sub-object,
or else it is considered a sub-element reference.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="getDetailPath">
<Documentation>
<UserDocu>
getDetailPath(element): get the 3d path an detail of an element.
Return a tuple(path,detail) for the coin3D SoPath and SoDetail of the element
</UserDocu>
</Documentation>
</Methode>
<Methode Name="getElementPicked">
<Documentation>
<UserDocu>getElementPicked(pickPoint): get the element under a 3d pick point. </UserDocu>
</Documentation>
</Methode>
<Methode Name="getBoundBox">
<Documentation>
<UserDocu>getBoundBox(vobj=None): get the bounding box. </UserDocu>
</Documentation>
</Methode>
<Attribute Name="LinkedView" ReadOnly="true">
<Documentation>
<UserDocu>The linked view object</UserDocu>
</Documentation>
<Parameter Name="LinkedView" Type="Object" />
</Attribute>
<Attribute Name="SubNames" ReadOnly="true">
<Documentation>
<UserDocu>The sub-object reference of the link</UserDocu>
</Documentation>
<Parameter Name="SubNames" Type="Object" />
</Attribute>
<Attribute Name="RootNode" ReadOnly="true">
<Documentation>
<UserDocu>A pivy node holding the cloned representation of the linked view object</UserDocu>
</Documentation>
<Parameter Name="RootNode" Type="Object" />
</Attribute>
<Attribute Name="Owner">
<Documentation>
<UserDocu>The owner view object of this link handle</UserDocu>
</Documentation>
<Parameter Name="Owner" Type="Object" />
</Attribute>
<Attribute Name="Visibilities">
<Documentation>
<UserDocu>Get/set the child element visibility</UserDocu>
</Documentation>
<Parameter Name="Visibilities" Type="Object" />
</Attribute>
<Attribute Name="Count">
<Documentation>
<UserDocu>Set the element size to create an array of linked object</UserDocu>
</Documentation>
<Parameter Name="Count" Type="Long" />
</Attribute>
<Methode Name="getChildren" Const="true">
<Documentation>
<UserDocu>Get children view objects</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>
+24 -28
View File
@@ -23,7 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <cfloat>
# include <numbers>
# ifdef FC_OS_WIN32
# include <windows.h>
# endif
@@ -553,7 +553,7 @@ void NaviCubeImplementation::addButtonFace(PickId pickId, const SbVec3f& directi
case PickId::DotBackside: {
int steps = 16;
for (int i = 0; i < steps; i++) {
float angle = 2.0f * M_PI * ((float)i+0.5) / (float)steps;
float angle = 2.0f * std::numbers::pi_v<float> * ((float)i+0.5) / (float)steps;
pointData.emplace_back(10. * cos(angle) + 87.);
pointData.emplace_back(10. * sin(angle) - 87.);
}
@@ -659,8 +659,8 @@ void NaviCubeImplementation::setSize(int size)
void NaviCubeImplementation::prepare()
{
static const float pi = boost::math::constants::pi<float>();
static const float pi1_2 = boost::math::constants::half_pi<float>();
constexpr float pi = std::numbers::pi_v<float>;
constexpr float pi1_2 = pi / 2;
createCubeFaceTextures();
@@ -817,7 +817,7 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode, float opacity)
glOrtho(-2.1, 2.1, -2.1, 2.1, NEARVAL, FARVAL);
}
else {
const float dim = NEARVAL * float(tan(M_PI / 8.0)) * 1.1;
const float dim = NEARVAL * float(tan(std::numbers::pi / 8.0)) * 1.1;
glFrustum(-dim, dim, -dim, dim, NEARVAL, FARVAL);
}
glMatrixMode(GL_MODELVIEW);
@@ -1010,15 +1010,11 @@ SbRotation NaviCubeImplementation::getNearestOrientation(PickId pickId) {
angle *= -1;
}
static const float pi = boost::math::constants::pi<float>();
static const float pi2 = boost::math::constants::two_pi<float>();
static const float pi1_2 = boost::math::constants::half_pi<float>();
static const float pi1_3 = boost::math::constants::third_pi<float>();
static const float pi2_3 = boost::math::constants::two_thirds_pi<float>();
constexpr float pi = std::numbers::pi_v<float>;
// Make angle positive
if (angle < 0) {
angle += pi2;
angle += 2 * pi;
}
// f is a small value used to control orientation priority when the camera is almost exactly between two
@@ -1030,23 +1026,23 @@ SbRotation NaviCubeImplementation::getNearestOrientation(PickId pickId) {
// Find the angle to rotate to the nearest orientation
if (m_Faces[pickId].type == ShapeId::Corner) {
// 6 possible orientations for the corners
if (angle <= (M_PI / 6 + f)) {
if (angle <= (pi / 6 + f)) {
angle = 0;
}
else if (angle <= (M_PI_2 + f)) {
angle = pi1_3;
else if (angle <= (pi / 2 + f)) {
angle = pi / 3;
}
else if (angle < (5 * M_PI / 6 - f)) {
angle = pi2_3;
else if (angle < (5 * pi / 6 - f)) {
angle = 2 * pi / 3;
}
else if (angle <= (M_PI + M_PI / 6 + f)) {
else if (angle <= (pi + pi / 6 + f)) {
angle = pi;
}
else if (angle < (M_PI + M_PI_2 - f)) {
angle = pi + pi1_3;
else if (angle < (pi + pi / 2 - f)) {
angle = pi + pi / 3;
}
else if (angle < (M_PI + 5 * M_PI / 6 - f)) {
angle = pi + pi2_3;
else if (angle < (pi + 5 * pi / 6 - f)) {
angle = pi + 2 * pi / 3;
}
else {
angle = 0;
@@ -1054,17 +1050,17 @@ SbRotation NaviCubeImplementation::getNearestOrientation(PickId pickId) {
}
else {
// 4 possible orientations for the main and edge faces
if (angle <= (M_PI_4 + f)) {
if (angle <= (pi / 4 + f)) {
angle = 0;
}
else if (angle <= (3 * M_PI_4 + f)) {
angle = pi1_2;
else if (angle <= (3 * pi / 4 + f)) {
angle = pi / 2;
}
else if (angle < (M_PI + M_PI_4 - f)) {
else if (angle < (pi + pi / 4 - f)) {
angle = pi;
}
else if (angle < (M_PI + 3 * M_PI_4 - f)) {
angle = pi + pi1_2;
else if (angle < (pi + 3 * pi / 4 - f)) {
angle = pi + pi / 2;
}
else {
angle = 0;
@@ -1089,7 +1085,7 @@ bool NaviCubeImplementation::mouseReleased(short x, short y)
} else {
PickId pickId = pickFace(x, y);
long step = Base::clamp(long(m_NaviStepByTurn), 4L, 36L);
float rotStepAngle = (2 * M_PI) / step;
float rotStepAngle = (2 * std::numbers::pi) / step;
if (m_Faces[pickId].type == ShapeId::Main || m_Faces[pickId].type == ShapeId::Edge || m_Faces[pickId].type == ShapeId::Corner) {
// Handle the cube faces
+6 -4
View File
@@ -25,6 +25,8 @@
#include "NavigationAnimation.h"
#include <Inventor/nodes/SoCamera.h>
#include <numbers>
using namespace Gui;
NavigationAnimation::NavigationAnimation(NavigationStyle* navigation)
@@ -69,8 +71,8 @@ void FixedTimeAnimation::initialize()
SbVec3f rotationAxisPost;
float angle;
SbRotation(navigation->getCamera()->orientation.getValue().inverse() * targetOrientation).getValue(rotationAxisPost, angle);
if (angle > M_PI) {
angle -= float(2 * M_PI);
if (angle > std::numbers::pi) {
angle -= float(2 * std::numbers::pi);
}
// Convert post-multiplication axis to a pre-multiplication axis
@@ -130,9 +132,9 @@ SpinningAnimation::SpinningAnimation(NavigationStyle* navigation, const SbVec3f&
: NavigationAnimation(navigation)
, rotationAxis(axis)
{
setDuration((2 * M_PI / velocity) * 1000.0);
setDuration((2 * std::numbers::pi / velocity) * 1000.0);
setStartValue(0.0);
setEndValue(2 * M_PI);
setEndValue(2 * std::numbers::pi);
setLoopCount(-1);
}
+5 -1
View File
@@ -39,6 +39,9 @@
# include <QMenu>
#endif
#include <cmath>
#include <limits>
#include <Base/Interpreter.h>
#include <App/Application.h>
@@ -719,7 +722,8 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue)
const float distorigo = newpos.length();
// sqrt(FLT_MAX) == ~ 1e+19, which should be both safe for further
// calculations and ok for the end-user and app-programmer.
if (distorigo > float(sqrt(FLT_MAX))) {
float maxDistance = std::sqrt(std::numeric_limits<float>::max());
if (distorigo > maxDistance) {
// do nothing here
}
else {
+15
View File
@@ -0,0 +1,15 @@
from Base.Metadata import export
from Base.BaseClass import BaseClass
@export(
Include="Gui/Navigation/NavigationStyle.h",
)
class NavigationStyle(BaseClass):
"""
This is the base class for navigation styles
Author: Werner Mayer (wmayer@users.sourceforge.net)
Licence: LGPL
"""
...
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="NavigationStylePy"
Twin="NavigationStyle"
TwinPointer="NavigationStyle"
Include="Gui/Navigation/NavigationStyle.h"
Namespace="Gui"
FatherInclude="Base/BaseClassPy.h"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="[email protected]" />
<UserDocu>This is the base class for navigation styles</UserDocu>
</Documentation>
<CustomAttributes />
</PythonExport>
</GenerateModel>
+1 -1
View File
@@ -1819,7 +1819,7 @@ bool OverlayManager::eventFilter(QObject *o, QEvent *ev)
}
if (hit <= 0) {
d->_lastPos.setX(INT_MAX);
d->_lastPos.setX(std::numeric_limits<int>::max());
if (ev->type() == QEvent::Wheel) {
d->wheelDelay = QTime::currentTime().addMSecs(OverlayParams::getDockOverlayWheelDelay());
d->wheelPos = pos;
+1 -2
View File
@@ -50,8 +50,6 @@
#include <fcntl.h>
#include <cctype>
#include <typeinfo>
#include <cfloat>
#include <climits>
#ifdef FC_OS_WIN32
#include <Windows.h>
@@ -69,6 +67,7 @@
#include <bitset>
#include <list>
#include <map>
#include <numbers>
#include <queue>
#include <random>
#include <set>
@@ -182,7 +182,7 @@ void ApplicationCache::setPeriod(ApplicationCache::Period period)
numDays = 365;
break;
case Period::Never:
numDays = INT_MAX;
numDays = std::numeric_limits<int>::max();
break;
}
}
@@ -60,7 +60,7 @@ DlgSettingsDocumentImp::DlgSettingsDocumentImp(QWidget* parent)
ui->prefSaveBackupDateFormat->setToolTip(tip);
ui->FormatTimeDocsLabel->setText(link);
ui->prefCountBackupFiles->setMaximum(INT_MAX);
ui->prefCountBackupFiles->setMaximum(std::numeric_limits<int>::max());
ui->prefCompression->setMinimum(Z_NO_COMPRESSION);
ui->prefCompression->setMaximum(Z_BEST_COMPRESSION);
connect(ui->prefLicenseType, qOverload<int>(&QComboBox::currentIndexChanged),
@@ -164,7 +164,7 @@
<cstring>AmbientLightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -181,7 +181,7 @@
<cstring>BacklightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -267,7 +267,7 @@
<cstring>AmbientLightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -293,7 +293,7 @@
<cstring>HeadlightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -332,7 +332,7 @@
<cstring>BacklightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -367,7 +367,7 @@
<cstring>FillLightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -404,7 +404,7 @@
<cstring>FillLightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
@@ -431,7 +431,7 @@
<cstring>HeadlightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<cstring>View/LightSources</cstring>
</property>
</widget>
</item>
+142
View File
@@ -0,0 +1,142 @@
from Base.Metadata import export
from Workbench import Workbench
from warnings import deprecated
@export(
Twin="PythonBaseWorkbench",
TwinPointer="PythonBaseWorkbench",
Include="Gui/Workbench.h",
)
class PythonWorkbench(Workbench):
"""
This is the class for Python workbenches
Author: Werner Mayer (wmayer@users.sourceforge.net)
Licence: LGPL
"""
def appendMenu(self) -> None:
"""
Append a new menu
"""
...
def removeMenu(self) -> None:
"""
Remove a menu
"""
...
def appendContextMenu(self) -> None:
"""
Append a new context menu item
"""
...
def removeContextMenu(self) -> None:
"""
Remove a context menu item
"""
...
def appendToolbar(self) -> None:
"""
Append a new toolbar
"""
...
def removeToolbar(self) -> None:
"""
Remove a toolbar
"""
...
def appendCommandbar(self) -> None:
"""
Append a new command bar
"""
...
def removeCommandbar(self) -> None:
"""
Remove a command bar
"""
...
@deprecated
def AppendMenu(self) -> None:
"""
deprecated -- use appendMenu
"""
...
@deprecated
def RemoveMenu(self) -> None:
"""
deprecated -- use removeMenu
"""
...
@deprecated
def ListMenus(self) -> None:
"""
deprecated -- use listMenus
"""
...
@deprecated
def AppendContextMenu(self) -> None:
"""
deprecated -- use appendContextMenu
"""
...
@deprecated
def RemoveContextMenu(self) -> None:
"""
deprecated -- use removeContextMenu
"""
...
@deprecated
def AppendToolbar(self) -> None:
"""
deprecated -- use appendToolbar
"""
...
@deprecated
def RemoveToolbar(self) -> None:
"""
deprecated -- use removeToolbar
"""
...
@deprecated
def ListToolbars(self) -> None:
"""
deprecated -- use listToolbars
"""
...
@deprecated
def AppendCommandbar(self) -> None:
"""
deprecated -- use appendCommandBar
"""
...
@deprecated
def RemoveCommandbar(self) -> None:
"""
deprecated -- use removeCommandBar
"""
...
@deprecated
def ListCommandbars(self) -> None:
"""
deprecated -- use listCommandBars
"""
...
-113
View File
@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="WorkbenchPy"
Name="PythonWorkbenchPy"
Twin="PythonBaseWorkbench"
TwinPointer="PythonBaseWorkbench"
Include="Gui/Workbench.h"
Namespace="Gui"
FatherInclude="Gui/WorkbenchPy.h"
FatherNamespace="Gui">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="[email protected]" />
<UserDocu>This is the class for Python workbenches</UserDocu>
</Documentation>
<Methode Name="appendMenu">
<Documentation>
<UserDocu>Append a new menu</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeMenu">
<Documentation>
<UserDocu>Remove a menu</UserDocu>
</Documentation>
</Methode>
<Methode Name="appendContextMenu">
<Documentation>
<UserDocu>Append a new context menu item</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeContextMenu">
<Documentation>
<UserDocu>Remove a context menu item</UserDocu>
</Documentation>
</Methode>
<Methode Name="appendToolbar">
<Documentation>
<UserDocu>Append a new toolbar</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeToolbar">
<Documentation>
<UserDocu>Remove a toolbar</UserDocu>
</Documentation>
</Methode>
<Methode Name="appendCommandbar">
<Documentation>
<UserDocu>Append a new command bar</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeCommandbar">
<Documentation>
<UserDocu>Remove a command bar</UserDocu>
</Documentation>
</Methode>
<Methode Name="AppendMenu">
<Documentation>
<UserDocu>deprecated -- use appendMenu</UserDocu>
</Documentation>
</Methode>
<Methode Name="RemoveMenu">
<Documentation>
<UserDocu>deprecated -- use removeMenu</UserDocu>
</Documentation>
</Methode>
<Methode Name="ListMenus">
<Documentation>
<UserDocu>deprecated -- use listMenus</UserDocu>
</Documentation>
</Methode>
<Methode Name="AppendContextMenu">
<Documentation>
<UserDocu>deprecated -- use appendContextMenu</UserDocu>
</Documentation>
</Methode>
<Methode Name="RemoveContextMenu">
<Documentation>
<UserDocu>deprecated -- use removeContextMenu</UserDocu>
</Documentation>
</Methode>
<Methode Name="AppendToolbar">
<Documentation>
<UserDocu>deprecated -- use appendToolbar</UserDocu>
</Documentation>
</Methode>
<Methode Name="RemoveToolbar">
<Documentation>
<UserDocu>deprecated -- use removeToolbar</UserDocu>
</Documentation>
</Methode>
<Methode Name="ListToolbars">
<Documentation>
<UserDocu>deprecated -- use listToolbars</UserDocu>
</Documentation>
</Methode>
<Methode Name="AppendCommandbar">
<Documentation>
<UserDocu>deprecated -- use appendCommandBar</UserDocu>
</Documentation>
</Methode>
<Methode Name="RemoveCommandbar">
<Documentation>
<UserDocu>deprecated -- use removeCommandBar</UserDocu>
</Documentation>
</Methode>
<Methode Name="ListCommandbars">
<Documentation>
<UserDocu>deprecated -- use listCommandBars</UserDocu>
</Documentation>
</Methode>
<CustomAttributes />
</PythonExport>
</GenerateModel>
+2 -2
View File
@@ -66,8 +66,8 @@ public:
pendingEmit(false),
checkRangeInExpression(false),
unitValue(0),
maximum(DOUBLE_MAX),
minimum(-DOUBLE_MAX),
maximum(std::numeric_limits<double>::max()),
minimum(-std::numeric_limits<double>::max()),
singleStep(1.0),
q_ptr(q)
{
-6
View File
@@ -76,9 +76,7 @@
#include <QWindow>
#include <Inventor/C/basic.h>
#if COIN_MAJOR_VERSION >= 4
#include <Inventor/SbByteBuffer.h>
#endif
#include <Inventor/SbColor.h>
#include <Inventor/SbViewportRegion.h>
@@ -1245,11 +1243,7 @@ QuarterWidget::setNavigationModeFile(const QUrl & url)
QFile file(filenametmp);
if (file.open(QIODevice::ReadOnly)){
QByteArray fileContents = file.readAll();
#if COIN_MAJOR_VERSION >= 4
stateMachine = ScXML::readBuffer(SbByteBuffer(fileContents.size(), fileContents.constData()));
#else
stateMachine = ScXML::readBuffer(fileContents.constData());
#endif
file.close();
}
}
+5 -3
View File
@@ -20,6 +20,8 @@
#include "PreCompiled.h"
#include <numbers>
#include <Base/Console.h>
#include <Inventor/SbLine.h>
#include <Inventor/SbPlane.h>
@@ -303,7 +305,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertOrtho2Perspective(const So
SbRotation camrot = in->orientation.getValue();
float focaldist = float(in->height.getValue() / (2.0*tan(M_PI / 8.0))); // NOLINT
float focaldist = float(in->height.getValue() / (2.0*tan(std::numbers::pi / 8.0))); // NOLINT
SbVec3f offset(0,0,focaldist-in->focalDistance.getValue());
@@ -313,7 +315,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertOrtho2Perspective(const So
out->focalDistance.setValue(focaldist);
// 45° is the default value of this field in SoPerspectiveCamera.
out->heightAngle = (float)(M_PI / 4.0); // NOLINT
out->heightAngle = (float)(std::numbers::pi / 4.0); // NOLINT
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertPerspective2Ortho(const SoPerspectiveCamera* in,
@@ -568,7 +570,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seeksensorCB(void* data, SoSensor
bool end = (par == 1.0F);
par = (float)((1.0 - cos(M_PI * par)) * 0.5); // NOLINT
par = (float)((1.0 - cos(std::numbers::pi * par)) * 0.5); // NOLINT
thisp->getSoRenderManager()->getCamera()->position = thisp->m_camerastartposition +
(thisp->m_cameraendposition - thisp->m_camerastartposition) * par;
+3 -2
View File
@@ -172,8 +172,9 @@ private:
struct Node_Slice
{
explicit Node_Slice(int min=1,int max=INT_MAX):Min(min),Max(max){}
int Min,Max;
explicit Node_Slice(int min = 1, int max = std::numeric_limits<int>::max())
: Min(min), Max(max) {}
int Min, Max;
};
+62
View File
@@ -0,0 +1,62 @@
from Base.Metadata import export
from Base.BaseClass import BaseClass
from typing import Any, Final, Tuple
@export(
Include="Gui/Selection/SelectionObject.h",
Delete=True,
)
class SelectionObject(BaseClass):
"""
This class represents selections made by the user. It holds information about the object, document and sub-element of the selection.
Author: Juergen Riegel (FreeCAD@juergen-riegel.net)
Licence: LGPL
"""
def remove(self) -> None:
"""
Remove this selection item from the selection.
remove() -> None
--
This object becomes invalid.
"""
...
def isObjectTypeOf(self, type: Any) -> bool:
"""
Test for a certain father class.
isObjectTypeOf(type) -> Bool
"""
...
ObjectName: Final[str] = ""
"""Name of the selected object"""
SubElementNames: Final[Tuple[str, ...]] = ()
"""Name of the selected sub-element if any"""
FullName: Final[str] = ""
"""Name of the selected object"""
TypeName: Final[str] = ""
"""Type name of the selected object"""
DocumentName: Final[str] = ""
"""Name of the document of the selected object"""
Document: Final[Any] = ...
"""Document of the selected object"""
Object: Final[Any] = ...
"""Selected object"""
SubObjects: Final[Tuple[Any, ...]] = ()
"""Selected sub-element, if any"""
PickedPoints: Final[Tuple[Any, ...]] = ()
"""Picked points for selection"""
HasSubObjects: Final[bool] = False
"""Selected sub-element, if any"""
-95
View File
@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="SelectionObjectPy"
Twin="SelectionObject"
TwinPointer="SelectionObject"
Include="Gui/Selection/SelectionObject.h"
Namespace="Gui"
Delete="true"
FatherInclude="Base/BaseClassPy.h"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="[email protected]" />
<UserDocu>This class represents selections made by the user. It holds information about the object, document and sub-element of the selection.</UserDocu>
</Documentation>
<Methode Name="remove">
<Documentation>
<UserDocu>Remove this selection item from the selection.
remove() -> None
--
This object becomes invalid.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="isObjectTypeOf">
<Documentation>
<UserDocu>Test for a certain father class.
isObjectTypeOf(type) -> Bool
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="ObjectName" ReadOnly="true">
<Documentation>
<UserDocu>Name of the selected object</UserDocu>
</Documentation>
<Parameter Name="ObjectName" Type="String" />
</Attribute>
<Attribute Name="SubElementNames" ReadOnly="true">
<Documentation>
<UserDocu>Name of the selected sub-element if any</UserDocu>
</Documentation>
<Parameter Name="SubElementNames" Type="Tuple" />
</Attribute>
<Attribute Name="FullName" ReadOnly="true">
<Documentation>
<UserDocu>Name of the selected object</UserDocu>
</Documentation>
<Parameter Name="FullName" Type="String" />
</Attribute>
<Attribute Name="TypeName" ReadOnly="true">
<Documentation>
<UserDocu>Type name of the selected object</UserDocu>
</Documentation>
<Parameter Name="TypeName" Type="String" />
</Attribute>
<Attribute Name="DocumentName" ReadOnly="true">
<Documentation>
<UserDocu>Name of the document of the selected object</UserDocu>
</Documentation>
<Parameter Name="DocumentName" Type="String" />
</Attribute>
<Attribute Name="Document" ReadOnly="true">
<Documentation>
<UserDocu>Document of the selected object</UserDocu>
</Documentation>
<Parameter Name="Document" Type="Object" />
</Attribute>
<Attribute Name="Object" ReadOnly="true">
<Documentation>
<UserDocu>Selected object</UserDocu>
</Documentation>
<Parameter Name="Object" Type="Object" />
</Attribute>
<Attribute Name="SubObjects" ReadOnly="true">
<Documentation>
<UserDocu>Selected sub-element, if any</UserDocu>
</Documentation>
<Parameter Name="SubObjects" Type="Tuple" />
</Attribute>
<Attribute Name="PickedPoints" ReadOnly="true">
<Documentation>
<UserDocu>Picked points for selection</UserDocu>
</Documentation>
<Parameter Name="PickedPoints" Type="Tuple" />
</Attribute>
<Attribute Name="HasSubObjects" ReadOnly="true">
<Documentation>
<UserDocu>Selected sub-element, if any</UserDocu>
</Documentation>
<Parameter Name="HasSubObjects" Type="Boolean" />
</Attribute>
<CustomAttributes />
</PythonExport>
</GenerateModel>
+2 -3
View File
@@ -23,7 +23,6 @@
#ifndef GUI_SOFCSELECTIONCONTEXT_H
#define GUI_SOFCSELECTIONCONTEXT_H
#include <climits>
#include <map>
#include <memory>
#include <set>
@@ -79,11 +78,11 @@ struct GuiExport SoFCSelectionContext : SoFCSelectionContextBase
}
bool isHighlightAll() const{
return highlightIndex==INT_MAX && (selectionIndex.empty() || isSelectAll());
return highlightIndex == std::numeric_limits<int>::max() && (selectionIndex.empty() || isSelectAll());
}
void highlightAll() {
highlightIndex = INT_MAX;
highlightIndex = std::numeric_limits<int>::max();
}
void removeHighlight() {
+1 -1
View File
@@ -409,7 +409,7 @@ void ShortcutManager::onTimer()
timer.stop();
QAction *found = nullptr;
int priority = -INT_MAX;
int priority = -std::numeric_limits<int>::max();
int seq_length = 0;
for (const auto &info : pendingActions) {
if (info.action) {
+51 -39
View File
@@ -34,8 +34,8 @@
# endif
# include <algorithm>
# include <cfloat>
# include <cmath>
# include <numbers>
# include <QFontMetrics>
# include <QPainter>
@@ -78,11 +78,12 @@ void glDrawLine(const SbVec3f& p1, const SbVec3f& p2){
glEnd();
}
void glDrawArc(const SbVec3f& center, float radius, float startAngle=0., float endAngle=2.0*M_PI, int countSegments=0){
void glDrawArc(const SbVec3f& center, float radius, float startAngle=0.,
float endAngle=2.0*std::numbers::pi, int countSegments=0){
float range = endAngle - startAngle;
if (countSegments == 0){
countSegments = std::max(6, abs(int(25.0 * range / M_PI)));
countSegments = std::max(6, abs(int(25.0 * range / std::numbers::pi)));
}
float segment = range / (countSegments-1);
@@ -238,11 +239,12 @@ public:
private:
void getBBox(const std::vector<SbVec3f>& corners, SbBox3f& box, SbVec3f& center) const
{
constexpr float floatMax = std::numeric_limits<float>::max();
if (corners.size() > 1) {
float minX = FLT_MAX;
float minY = FLT_MAX;
float maxX = -FLT_MAX;
float maxY = -FLT_MAX;
float minX = floatMax;
float minY = floatMax;
float maxX = -floatMax;
float maxY = -floatMax;
for (SbVec3f it : corners) {
minX = (it[0] < minX) ? it[0] : minX;
minY = (it[1] < minY) ? it[1] : minY;
@@ -288,14 +290,15 @@ private:
SbVec3f dir;
SbVec3f normal;
constexpr float floatEpsilon = std::numeric_limits<float>::epsilon();
if (label->datumtype.getValue() == SoDatumLabel::DISTANCE) {
dir = (p2-p1);
}
else if (label->datumtype.getValue() == SoDatumLabel::DISTANCEX) {
dir = SbVec3f( (p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
dir = SbVec3f( (p2[0] - p1[0] >= floatEpsilon) ? 1 : -1, 0, 0);
}
else if (label->datumtype.getValue() == SoDatumLabel::DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
dir = SbVec3f(0, (p2[1] - p1[1] >= floatEpsilon) ? 1 : -1, 0);
}
dir.normalize();
@@ -546,11 +549,11 @@ private:
float startangle = atan2f(vc1[1], vc1[0]);
float endangle = atan2f(vc2[1], vc2[0]);
if (endangle < startangle) {
endangle += 2. * M_PI;
endangle += 2. * std::numbers::pi;
}
SbVec3f textCenter;
if (endangle - startangle <= M_PI) {
if (endangle - startangle <= std::numbers::pi) {
textCenter = ctr + vm * (length + imgHeight);
} else {
textCenter = ctr - vm * (length + 2. * imgHeight);
@@ -628,14 +631,16 @@ SbVec3f SoDatumLabel::getLabelTextCenterDistance(const SbVec3f& p1, const SbVec3
SbVec3f dir;
SbVec3f normal;
constexpr float floatEpsilon = std::numeric_limits<float>::epsilon();
if (datumtype.getValue() == SoDatumLabel::DISTANCE) {
dir = (p2 - p1);
}
else if (datumtype.getValue() == SoDatumLabel::DISTANCEX) {
dir = SbVec3f((p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
dir = SbVec3f((p2[0] - p1[0] >= floatEpsilon) ? 1 : -1, 0, 0);
}
else if (datumtype.getValue() == SoDatumLabel::DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
dir = SbVec3f(0, (p2[1] - p1[1] >= floatEpsilon) ? 1 : -1, 0);
}
dir.normalize();
@@ -689,7 +694,7 @@ SbVec3f SoDatumLabel::getLabelTextCenterArcLength(const SbVec3f& ctr, const SbVe
float endangle = atan2f(vc2[1], vc2[0]);
if (endangle < startangle) {
endangle += 2. * M_PI;
endangle += 2. * std::numbers::pi;
}
// Text location
@@ -697,7 +702,7 @@ SbVec3f SoDatumLabel::getLabelTextCenterArcLength(const SbVec3f& ctr, const SbVe
vm.normalize();
SbVec3f textCenter;
if (endangle - startangle <= M_PI) {
if (endangle - startangle <= std::numbers::pi) {
textCenter = ctr + vm * (length + this->imgHeight);
} else {
textCenter = ctr - vm * (length + 2. * this->imgHeight);
@@ -709,12 +714,13 @@ SbVec3f SoDatumLabel::getLabelTextCenterArcLength(const SbVec3f& ctr, const SbVe
void SoDatumLabel::generateDistancePrimitives(SoAction * action, const SbVec3f& p1, const SbVec3f& p2)
{
SbVec3f dir;
constexpr float floatEpsilon = std::numeric_limits<float>::epsilon();
if (this->datumtype.getValue() == DISTANCE) {
dir = (p2-p1);
} else if (this->datumtype.getValue() == DISTANCEX) {
dir = SbVec3f( (p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
dir = SbVec3f( (p2[0] - p1[0] >= floatEpsilon) ? 1 : -1, 0, 0);
} else if (this->datumtype.getValue() == DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
dir = SbVec3f(0, (p2[1] - p1[1] >= floatEpsilon) ? 1 : -1, 0);
}
dir.normalize();
@@ -957,7 +963,8 @@ void SoDatumLabel::generateArcLengthPrimitives(SoAction * action, const SbVec3f&
void SoDatumLabel::generatePrimitives(SoAction * action)
{
// Initialisation check (needs something more sensible) prevents an infinite loop bug
if (this->imgHeight <= FLT_EPSILON || this->imgWidth <= FLT_EPSILON) {
constexpr float floatEpsilon = std::numeric_limits<float>::epsilon();
if (this->imgHeight <= floatEpsilon | this->imgWidth <= floatEpsilon) {
return;
}
@@ -1161,6 +1168,8 @@ void SoDatumLabel::getDimension(float scale, int& srcw, int& srch)
void SoDatumLabel::drawDistance(const SbVec3f* points, float scale, int srch, float& angle, SbVec3f& textOffset)
{
using std::numbers::pi;
float length = this->param1.getValue();
float length2 = this->param2.getValue();
@@ -1168,12 +1177,13 @@ void SoDatumLabel::drawDistance(const SbVec3f* points, float scale, int srch, fl
SbVec3f p2 = points[1];
SbVec3f dir;
constexpr float floatEpsilon = std::numeric_limits<float>::epsilon();
if (this->datumtype.getValue() == DISTANCE) {
dir = (p2-p1);
} else if (this->datumtype.getValue() == DISTANCEX) {
dir = SbVec3f( (p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
dir = SbVec3f( (p2[0] - p1[0] >= floatEpsilon) ? 1 : -1, 0, 0);
} else if (this->datumtype.getValue() == DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
dir = SbVec3f(0, (p2[1] - p1[1] >= floatEpsilon) ? 1 : -1, 0);
}
dir.normalize();
@@ -1192,10 +1202,10 @@ void SoDatumLabel::drawDistance(const SbVec3f* points, float scale, int srch, fl
// Get magnitude of angle between horizontal
angle = atan2f(dir[1],dir[0]);
if (angle > M_PI_2+M_PI/12) {
angle -= (float)M_PI;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += (float)M_PI;
if (angle > pi/2 + pi/12) {
angle -= (float)pi;
} else if (angle <= -pi/2 + pi/12) {
angle += (float)pi;
}
textOffset = midpos + normal * length + dir * length2;
@@ -1291,7 +1301,7 @@ void SoDatumLabel::drawDistance(const SbVec3f* points)
float startangle1 = this->param3.getValue();
float radius1 = this->param5.getValue();
SbVec3f center = points[2];
int countSegments = std::max(6, abs(int(50.0 * range1 / (2 * M_PI))));
int countSegments = std::max(6, abs(int(50.0 * range1 / (2 * std::numbers::pi))));
double segment = range1 / (countSegments - 1);
glBegin(GL_LINE_STRIP);
@@ -1307,7 +1317,7 @@ void SoDatumLabel::drawDistance(const SbVec3f* points)
float startangle2 = this->param6.getValue();
float radius2 = this->param8.getValue();
SbVec3f center = points[3];
int countSegments = std::max(6, abs(int(50.0 * range2 / (2 * M_PI))));
int countSegments = std::max(6, abs(int(50.0 * range2 / (2 * std::numbers::pi))));
double segment = range2 / (countSegments - 1);
glBegin(GL_LINE_STRIP);
@@ -1342,10 +1352,10 @@ void SoDatumLabel::drawRadiusOrDiameter(const SbVec3f* points, float& angle, SbV
// Get magnitude of angle between horizontal
angle = atan2f(dir[1],dir[0]);
if (angle > M_PI_2+M_PI/12) {
angle -= (float)M_PI;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += (float)M_PI;
if (angle > std::numbers::pi/2 + std::numbers::pi/12) {
angle -= (float)std::numbers::pi;
} else if (angle <= -std::numbers::pi/2 + std::numbers::pi/12) {
angle += (float)std::numbers::pi;
}
textOffset = pos;
@@ -1401,7 +1411,7 @@ void SoDatumLabel::drawRadiusOrDiameter(const SbVec3f* points, float& angle, SbV
float startangle = this->param3.getValue();
float range = this->param4.getValue();
if (range != 0.0) {
int countSegments = std::max(6, abs(int(50.0 * range / (2 * M_PI))));
int countSegments = std::max(6, abs(int(50.0 * range / (2 * std::numbers::pi))));
double segment = range / (countSegments - 1);
glBegin(GL_LINE_STRIP);
@@ -1521,6 +1531,8 @@ void SoDatumLabel::drawSymmetric(const SbVec3f* points)
void SoDatumLabel::drawArcLength(const SbVec3f* points, float& angle, SbVec3f& textOffset)
{
using std::numbers::pi;
SbVec3f ctr = points[0];
SbVec3f p1 = points[1];
SbVec3f p2 = points[2];
@@ -1535,7 +1547,7 @@ void SoDatumLabel::drawArcLength(const SbVec3f* points, float& angle, SbVec3f& t
float startangle = atan2f(vc1[1], vc1[0]);
float endangle = atan2f(vc2[1], vc2[0]);
if (endangle < startangle) {
endangle += 2.0F * (float)M_PI;
endangle += 2.0F * (float)pi;
}
float range = endangle - startangle;
@@ -1547,10 +1559,10 @@ void SoDatumLabel::drawArcLength(const SbVec3f* points, float& angle, SbVec3f& t
dir.normalize();
// Get magnitude of angle between horizontal
angle = atan2f(dir[1],dir[0]);
if (angle > M_PI_2+M_PI/12) {
angle -= (float)M_PI;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += (float)M_PI;
if (angle > pi/2 + pi/12) {
angle -= (float)pi;
} else if (angle <= -pi/2 + pi/12) {
angle += (float)pi;
}
// Text location
textOffset = getLabelTextCenterArcLength(ctr, p1, p2);
@@ -1566,7 +1578,7 @@ void SoDatumLabel::drawArcLength(const SbVec3f* points, float& angle, SbVec3f& t
SbVec3f pnt4 = p2 + (length-radius) * vm;
// Draw arc
if (range <= M_PI) {
if (range <= pi) {
glDrawArc(ctr + (length-radius)*vm, radius, startangle, endangle);
}
else {
@@ -1606,7 +1618,7 @@ void SoDatumLabel::drawText(SoState *state, int srcw, int srch, float angle, con
const SbViewVolume & vv = SoViewVolumeElement::get(state);
SbVec3f z = vv.zVector();
bool flip = norm.getValue().dot(z) > FLT_EPSILON;
bool flip = norm.getValue().dot(z) > std::numeric_limits<float>::epsilon();
static bool init = false;
static bool npot = false;
@@ -1678,7 +1690,7 @@ void SoDatumLabel::drawText(SoState *state, int srcw, int srch, float angle, con
// Apply a rotation and translation matrix
glTranslatef(textOffset[0], textOffset[1], textOffset[2]);
glRotatef((GLfloat) angle * 180 / M_PI, 0,0,1);
glRotatef((GLfloat) angle * 180 / std::numbers::pi, 0,0,1);
glBegin(GL_QUADS);
glColor3f(1.F, 1.F, 1.F);
+9 -7
View File
@@ -23,6 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <cassert>
#include <numbers>
#include <Inventor/SbRotation.h>
#include <Inventor/actions/SoGLRenderAction.h>
@@ -743,7 +744,7 @@ RDragger::RDragger()
}
SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0));
SO_KIT_ADD_FIELD(rotationIncrement, (M_PI / 8.0));
SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0));
SO_KIT_ADD_FIELD(rotationIncrementCount, (0));
SO_KIT_INIT_INSTANCE();
@@ -808,7 +809,7 @@ SoGroup* RDragger::buildGeometry()
unsigned int segments = 15;
float angleIncrement = static_cast<float>(M_PI / 2.0) / static_cast<float>(segments);
float angleIncrement = (std::numbers::pi_v<float> / 2.f) / static_cast<float>(segments);
SbRotation rotation(SbVec3f(0.0, 0.0, 1.0), angleIncrement);
SbVec3f point(arcRadius, 0.0, 0.0);
for (unsigned int index = 0; index <= segments; ++index) {
@@ -965,9 +966,10 @@ void RDragger::drag()
appendRotation(getStartMotionMatrix(), localRotation, SbVec3f(0.0, 0.0, 0.0)));
}
Base::Quantity quantity(static_cast<double>(rotationIncrementCount.getValue()) * (180.0 / M_PI)
* rotationIncrement.getValue(),
Base::Unit::Angle);
Base::Quantity quantity(
static_cast<double>(rotationIncrementCount.getValue())
* (180.0 / std::numbers::pi)* rotationIncrement.getValue(),
Base::Unit::Angle);
QString message =
QStringLiteral("%1 %2").arg(QObject::tr("Rotation:"), QString::fromStdString(quantity.getUserString()));
@@ -1179,7 +1181,7 @@ SoFCCSysDragger::SoFCCSysDragger()
SO_KIT_ADD_FIELD(translationIncrementCountZ, (0));
SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0));
SO_KIT_ADD_FIELD(rotationIncrement, (M_PI / 8.0));
SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0));
SO_KIT_ADD_FIELD(rotationIncrementCountX, (0));
SO_KIT_ADD_FIELD(rotationIncrementCountY, (0));
SO_KIT_ADD_FIELD(rotationIncrementCountZ, (0));
@@ -1272,7 +1274,7 @@ SoFCCSysDragger::SoFCCSysDragger()
SoRotation* localRotation;
SbRotation tempRotation;
auto angle = static_cast<float>(M_PI / 2.0);
auto angle = static_cast<float>(std::numbers::pi / 2.0);
// Translator
localRotation = SO_GET_ANY_PART(this, "xTranslatorRotation", SoRotation);
localRotation->rotation.setValue(SbVec3f(0.0, 0.0, -1.0), angle);
-35
View File
@@ -31,7 +31,6 @@
# else
# include <GL/gl.h>
# endif
# include <cfloat>
# include <QFontMetrics>
# include <QPainter>
# include <QPen>
@@ -51,12 +50,7 @@
#include <Inventor/elements/SoViewingMatrixElement.h>
#include <Inventor/elements/SoViewportRegionElement.h>
#include <Inventor/elements/SoViewVolumeElement.h>
#if COIN_MAJOR_VERSION > 3
#include <Inventor/elements/SoMultiTextureEnabledElement.h>
#else
#include <Inventor/elements/SoGLTexture3EnabledElement.h>
#endif
#include "SoTextLabel.h"
#include "SoFCInteractiveElement.h"
@@ -65,31 +59,6 @@
using namespace Gui;
/*!
\code
s="""
#Inventor V2.1 ascii
Annotation {
Translation { translation 4 0 0 }
FontStyle {
size 20
style BOLD
}
BaseColor {
rgb 0.0 0.0 0.0
}
SoTextLabel { string ["Text label", "Second line"] backgroundColor 1.0 0.447059 0.337255}
}
"""
App.ActiveDocument.addObject("App::InventorObject","iv").Buffer=s
\endcode
*/
SO_NODE_SOURCE(SoTextLabel)
@@ -215,11 +184,7 @@ void SoTextLabel::GLRender(SoGLRenderAction *action)
// disable textures for all units
SoGLTextureEnabledElement::set(state, this, false);
#if COIN_MAJOR_VERSION > 3
SoMultiTextureEnabledElement::set(state, this, false);
#else
SoGLTexture3EnabledElement::set(state, this, false);
#endif
glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);

Some files were not shown because too many files have changed in this diff Show More