Sketch: Refactor SketchObject::getPoint
Add the helper class SketchGeometryType and the interface SketchGeometry with the needed sub-classes to remove the cascaded if-else construct
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "GeometryFacadePy.h"
|
||||
#include "PropertyConstraintList.h"
|
||||
#include "Sketch.h"
|
||||
#include "SketchGeometry.h"
|
||||
#include "SketchGeometryExtension.h"
|
||||
#include "SketchGeometryExtensionPy.h"
|
||||
#include "SketchObject.h"
|
||||
@@ -88,6 +89,7 @@ PyMOD_INIT_FUNC(Sketcher)
|
||||
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
|
||||
// This function is responsible for adding inherited slots from a type's base class.
|
||||
|
||||
Sketcher::SketchGeometryType::init();
|
||||
Sketcher::SketchGeometryExtension ::init();
|
||||
Sketcher::ExternalGeometryExtension ::init();
|
||||
Sketcher::SolverGeometryExtension ::init();
|
||||
|
||||
@@ -58,6 +58,8 @@ SOURCE_GROUP("Properties" FILES ${Properties_SRCS})
|
||||
SET(Features_SRCS
|
||||
SketchObjectSF.cpp
|
||||
SketchObjectSF.h
|
||||
SketchGeometry.cpp
|
||||
SketchGeometry.h
|
||||
SketchGeometryExtension.cpp
|
||||
SketchGeometryExtension.h
|
||||
ExternalGeometryExtension.cpp
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "SketchGeometry.h"
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
template<typename GeometryT>
|
||||
class SketchGeometryT: public SketchGeometry
|
||||
{
|
||||
public:
|
||||
using GeomType = GeometryT;
|
||||
bool supports(const Part::Geometry* geo) const override
|
||||
{
|
||||
return geo->is<GeomType>();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchPoint: public SketchGeometryT<Part::GeomPoint>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto geomPoint = dynamic_cast<const GeomType*>(geo);
|
||||
if (PosId == PointPos::start || PosId == PointPos::mid || PosId == PointPos::end) {
|
||||
return geomPoint->getPoint();
|
||||
}
|
||||
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchLineSegment: public SketchGeometryT<Part::GeomLineSegment>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto lineSeg = dynamic_cast<const GeomType*>(geo);
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return lineSeg->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return lineSeg->getEndPoint();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchCircle: public SketchGeometryT<Part::GeomCircle>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto circle = dynamic_cast<const GeomType*>(geo);
|
||||
auto pt = circle->getCenter();
|
||||
if (PosId != PointPos::mid) {
|
||||
pt.x += circle->getRadius();
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
};
|
||||
|
||||
class SketchEllipse: public SketchGeometryT<Part::GeomEllipse>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto ellipse = dynamic_cast<const GeomType*>(geo);
|
||||
auto pt = ellipse->getCenter();
|
||||
if (PosId != PointPos::mid) {
|
||||
pt += ellipse->getMajorAxisDir() * ellipse->getMajorRadius();
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
};
|
||||
|
||||
class SketchArcOfCircle: public SketchGeometryT<Part::GeomArcOfCircle>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto aoc = dynamic_cast<const GeomType*>(geo);
|
||||
const bool emulateCCW = true;
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoc->getStartPoint(emulateCCW);
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoc->getEndPoint(emulateCCW);
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoc->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchArcOfEllipse: public SketchGeometryT<Part::GeomArcOfEllipse>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto aoe = dynamic_cast<const GeomType*>(geo);
|
||||
const bool emulateCCW = true;
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoe->getStartPoint(emulateCCW);
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoe->getEndPoint(emulateCCW);
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoe->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchArcOfHyperbola: public SketchGeometryT<Part::GeomArcOfHyperbola>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto aoh = dynamic_cast<const GeomType*>(geo);
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoh->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoh->getEndPoint();
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoh->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchArcOfParabola: public SketchGeometryT<Part::GeomArcOfParabola>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto aop = dynamic_cast<const GeomType*>(geo);
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aop->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aop->getEndPoint();
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aop->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
class SketchBSplineCurve: public SketchGeometryT<Part::GeomBSplineCurve>
|
||||
{
|
||||
public:
|
||||
Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const override
|
||||
{
|
||||
auto bsp = dynamic_cast<const GeomType*>(geo);
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return bsp->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return bsp->getEndPoint();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Sketcher
|
||||
|
||||
std::list<SketchGeometryPtr> SketchGeometryType::sketchGeoms; // NOLINT
|
||||
|
||||
void SketchGeometryType::init()
|
||||
{
|
||||
static bool init = true;
|
||||
if (init) {
|
||||
init = false;
|
||||
addType(std::make_shared<SketchPoint>());
|
||||
addType(std::make_shared<SketchLineSegment>());
|
||||
addType(std::make_shared<SketchCircle>());
|
||||
addType(std::make_shared<SketchEllipse>());
|
||||
addType(std::make_shared<SketchArcOfCircle>());
|
||||
addType(std::make_shared<SketchArcOfEllipse>());
|
||||
addType(std::make_shared<SketchArcOfHyperbola>());
|
||||
addType(std::make_shared<SketchArcOfParabola>());
|
||||
addType(std::make_shared<SketchBSplineCurve>());
|
||||
}
|
||||
}
|
||||
|
||||
void SketchGeometryType::addType(const SketchGeometryPtr& type)
|
||||
{
|
||||
sketchGeoms.emplace_back(type);
|
||||
}
|
||||
|
||||
Base::Vector3d SketchGeometryType::getPoint(const Part::Geometry* geo, PointPos PosId)
|
||||
{
|
||||
for (const auto& it : sketchGeoms) {
|
||||
if (it->supports(geo)) {
|
||||
return it->getPoint(geo, PosId);
|
||||
}
|
||||
}
|
||||
|
||||
return Base::Vector3d();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SKETCHER_GEOMETRY_H
|
||||
#define SKETCHER_GEOMETRY_H
|
||||
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include "GeoEnum.h"
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
namespace Part
|
||||
{
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
class SketcherExport SketchGeometry
|
||||
{
|
||||
public:
|
||||
SketchGeometry() = default;
|
||||
SketchGeometry(const SketchGeometry&) = default;
|
||||
SketchGeometry(SketchGeometry&&) = default;
|
||||
SketchGeometry& operator=(const SketchGeometry&) = default;
|
||||
SketchGeometry& operator=(SketchGeometry&&) = default;
|
||||
virtual ~SketchGeometry() = default;
|
||||
|
||||
virtual bool supports(const Part::Geometry* geo) const = 0;
|
||||
virtual Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId) const = 0;
|
||||
};
|
||||
|
||||
using SketchGeometryPtr = std::shared_ptr<SketchGeometry>;
|
||||
|
||||
class SketchGeometryType
|
||||
{
|
||||
public:
|
||||
static void init();
|
||||
static void addType(const SketchGeometryPtr& type);
|
||||
static Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId);
|
||||
|
||||
private:
|
||||
static std::list<SketchGeometryPtr> sketchGeoms; // NOLINT
|
||||
};
|
||||
|
||||
} // namespace Sketcher
|
||||
|
||||
#endif // SKETCHER_GEOMETRY_H
|
||||
@@ -111,6 +111,7 @@
|
||||
#include "GeoEnum.h"
|
||||
#include "SketchObject.h"
|
||||
#include "SketchObjectPy.h"
|
||||
#include "SketchGeometry.h"
|
||||
#include "SolverGeometryExtension.h"
|
||||
#include "ExternalGeometryFacade.h"
|
||||
#include <Mod/Part/App/Datums.h>
|
||||
@@ -1644,170 +1645,9 @@ int SketchObject::moveGeometry(int geoId, PointPos pos, const Base::Vector3d& to
|
||||
return moveGeometries(geoEltIds, toPoint, relative, updateGeoBeforeMoving);
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomPoint *geomPoint, PointPos PosId)
|
||||
{
|
||||
if (PosId == PointPos::start || PosId == PointPos::mid || PosId == PointPos::end)
|
||||
return geomPoint->getPoint();
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomLineSegment *lineSeg, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return lineSeg->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return lineSeg->getEndPoint();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomCircle *circle, PointPos PosId)
|
||||
{
|
||||
auto pt = circle->getCenter();
|
||||
if(PosId != PointPos::mid)
|
||||
pt.x += circle->getRadius();
|
||||
return pt;
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomEllipse *ellipse, PointPos PosId)
|
||||
{
|
||||
auto pt = ellipse->getCenter();
|
||||
if(PosId != PointPos::mid)
|
||||
pt += ellipse->getMajorAxisDir()*ellipse->getMajorRadius();
|
||||
return pt;
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomArcOfCircle *aoc, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoc->getStartPoint(/*emulateCCW=*/true);
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoc->getEndPoint(/*emulateCCW=*/true);
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoc->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomArcOfEllipse *aoe, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoe->getStartPoint(/*emulateCCW=*/true);
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoe->getEndPoint(/*emulateCCW=*/true);
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoe->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomArcOfHyperbola *aoh, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aoh->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aoh->getEndPoint();
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aoh->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomArcOfParabola *aop, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return aop->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return aop->getEndPoint();
|
||||
}
|
||||
case PointPos::mid: {
|
||||
return aop->getCenter();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <>
|
||||
Base::Vector3d SketchObject::getPointForGeometry<>(const Part::GeomBSplineCurve *bsp, PointPos PosId)
|
||||
{
|
||||
switch (PosId) {
|
||||
case PointPos::start: {
|
||||
return bsp->getStartPoint();
|
||||
}
|
||||
case PointPos::end: {
|
||||
return bsp->getEndPoint();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
Base::Vector3d SketchObject::getPoint(const Part::Geometry *geo, PointPos PosId)
|
||||
{
|
||||
if (auto point = freecad_cast<Part::GeomPoint*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomPoint>(point, PosId);
|
||||
}
|
||||
else if (auto lineSegment = freecad_cast<Part::GeomLineSegment*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomLineSegment>(lineSegment, PosId);
|
||||
}
|
||||
else if (auto circle = freecad_cast<Part::GeomCircle*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomCircle>(circle, PosId);
|
||||
}
|
||||
else if (auto ellipse = freecad_cast<Part::GeomEllipse*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomEllipse>(ellipse, PosId);
|
||||
}
|
||||
else if (auto arcOfCircle = freecad_cast<Part::GeomArcOfCircle*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomArcOfCircle>(arcOfCircle, PosId);
|
||||
}
|
||||
else if (auto arcOfEllipse = freecad_cast<Part::GeomArcOfEllipse*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomArcOfEllipse>(arcOfEllipse, PosId);
|
||||
}
|
||||
else if (auto arcOfHyperbola = freecad_cast<Part::GeomArcOfHyperbola*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomArcOfHyperbola>(arcOfHyperbola, PosId);
|
||||
}
|
||||
else if (auto arcOfParabola = freecad_cast<Part::GeomArcOfParabola*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomArcOfParabola>(arcOfParabola, PosId);
|
||||
}
|
||||
else if (auto bSplineCurve = freecad_cast<Part::GeomBSplineCurve*>(geo)) {
|
||||
return getPointForGeometry<Part::GeomBSplineCurve>(bSplineCurve, PosId);
|
||||
}
|
||||
return Base::Vector3d();
|
||||
return SketchGeometryType::getPoint(geo, PosId);
|
||||
}
|
||||
|
||||
Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const
|
||||
|
||||
@@ -437,13 +437,6 @@ public:
|
||||
/// retrieves the coordinates of a point
|
||||
static Base::Vector3d getPoint(const Part::Geometry* geo, PointPos PosId);
|
||||
Base::Vector3d getPoint(int GeoId, PointPos PosId) const;
|
||||
template<class GeomType>
|
||||
static Base::Vector3d getPointForGeometry(const GeomType* geo, PointPos PosId)
|
||||
{
|
||||
(void)geo;
|
||||
(void)PosId;
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
/// toggle geometry to draft line
|
||||
int toggleConstruction(int GeoId);
|
||||
|
||||
Reference in New Issue
Block a user