508 lines
13 KiB
C++
508 lines
13 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2019 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#ifndef SKETCHER_SOLVERGEOMETRYEXTENSION_H
|
|
#define SKETCHER_SOLVERGEOMETRYEXTENSION_H
|
|
|
|
#include <Base/Exception.h>
|
|
#include <Mod/Part/App/GeometryExtension.h>
|
|
#include <Mod/Sketcher/SketcherGlobal.h>
|
|
|
|
#include "GeoEnum.h"
|
|
|
|
|
|
namespace Sketcher
|
|
{
|
|
|
|
class SketcherExport SolverGeometryExtension: public Part::GeometryExtension
|
|
{
|
|
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
|
|
|
public:
|
|
enum SolverStatus
|
|
{
|
|
FullyConstraint = 0,
|
|
NotFullyConstraint = 1,
|
|
NumSolverStatus
|
|
};
|
|
|
|
enum ParameterStatus
|
|
{
|
|
Dependent = 0,
|
|
Independent = 1,
|
|
NumParameterStatus
|
|
};
|
|
|
|
class PointParameterStatus
|
|
{
|
|
public:
|
|
explicit PointParameterStatus(ParameterStatus status)
|
|
{
|
|
setStatus(status);
|
|
}
|
|
PointParameterStatus(ParameterStatus statusx, ParameterStatus statusy)
|
|
{
|
|
setStatus(statusx, statusy);
|
|
}
|
|
|
|
PointParameterStatus(const PointParameterStatus&) = default;
|
|
PointParameterStatus& operator=(const PointParameterStatus&) = default;
|
|
PointParameterStatus(PointParameterStatus&&) = default;
|
|
PointParameterStatus& operator=(PointParameterStatus&&) = default;
|
|
|
|
ParameterStatus getStatus() const
|
|
{
|
|
return (xstatus == Independent && ystatus == Independent) ? Independent : Dependent;
|
|
}
|
|
ParameterStatus getStatusx() const
|
|
{
|
|
return xstatus;
|
|
}
|
|
ParameterStatus getStatusy() const
|
|
{
|
|
return ystatus;
|
|
}
|
|
|
|
bool isXDoF()
|
|
{
|
|
return xstatus == Dependent;
|
|
}
|
|
bool isYDoF()
|
|
{
|
|
return ystatus == Dependent;
|
|
}
|
|
|
|
int getDoFs()
|
|
{
|
|
bool xfree = isXDoF();
|
|
bool yfree = isYDoF();
|
|
|
|
if (xfree && yfree) {
|
|
return 2;
|
|
}
|
|
else if (xfree || yfree) {
|
|
return 1;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void setStatus(ParameterStatus status)
|
|
{
|
|
xstatus = status;
|
|
ystatus = status;
|
|
}
|
|
void setStatus(ParameterStatus statusx, ParameterStatus statusy)
|
|
{
|
|
xstatus = statusx;
|
|
ystatus = statusy;
|
|
}
|
|
void setStatusx(ParameterStatus statusx)
|
|
{
|
|
xstatus = statusx;
|
|
}
|
|
void setStatusy(ParameterStatus statusy)
|
|
{
|
|
ystatus = statusy;
|
|
}
|
|
|
|
private:
|
|
ParameterStatus xstatus;
|
|
ParameterStatus ystatus;
|
|
};
|
|
|
|
class EdgeParameterStatus
|
|
{
|
|
public:
|
|
EdgeParameterStatus() = default;
|
|
|
|
void init(int nparams)
|
|
{
|
|
pstatus.resize(nparams, ParameterStatus::Dependent);
|
|
}
|
|
|
|
ParameterStatus getStatus() const
|
|
{
|
|
return std::all_of(pstatus.begin(),
|
|
pstatus.end(),
|
|
[](const auto& v) {
|
|
return v == Independent;
|
|
})
|
|
? Independent
|
|
: Dependent;
|
|
}
|
|
|
|
void setStatus(ParameterStatus status)
|
|
{
|
|
std::fill(pstatus.begin(), pstatus.end(), status);
|
|
}
|
|
|
|
void setStatus(int index, ParameterStatus status)
|
|
{
|
|
if (index >= int(pstatus.size())) {
|
|
pstatus.resize(index + 1, ParameterStatus::Dependent);
|
|
}
|
|
|
|
pstatus.at(index) = status;
|
|
};
|
|
|
|
protected:
|
|
std::vector<ParameterStatus> pstatus;
|
|
};
|
|
|
|
class Point: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
Point() = default;
|
|
};
|
|
|
|
class Line: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
Line() = default;
|
|
};
|
|
|
|
class Arc: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
Arc() = default;
|
|
|
|
ParameterStatus getRadiusStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
bool isRadiusDoF() const
|
|
{
|
|
return pstatus[0] == Dependent;
|
|
}
|
|
ParameterStatus getStartParameter() const
|
|
{
|
|
return pstatus[1];
|
|
}
|
|
ParameterStatus getEndParameter() const
|
|
{
|
|
return pstatus[2];
|
|
}
|
|
};
|
|
|
|
class Circle: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
Circle() = default;
|
|
|
|
ParameterStatus getRadiusStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
bool isRadiusDoF() const
|
|
{
|
|
return pstatus[0] == Dependent;
|
|
}
|
|
};
|
|
|
|
class ArcOfEllipse: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
ArcOfEllipse() = default;
|
|
|
|
ParameterStatus getFocusXStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
ParameterStatus getFocusYStatus() const
|
|
{
|
|
return pstatus[1];
|
|
}
|
|
ParameterStatus getFocusMinorRadiusStatus() const
|
|
{
|
|
return pstatus[2];
|
|
}
|
|
ParameterStatus getStartParameter() const
|
|
{
|
|
return pstatus[3];
|
|
}
|
|
ParameterStatus getEndParameter() const
|
|
{
|
|
return pstatus[4];
|
|
}
|
|
|
|
bool isFocusDoF() const
|
|
{
|
|
return pstatus[0] == Dependent || pstatus[1] == Dependent;
|
|
}
|
|
bool isMinorRadiusDoF() const
|
|
{
|
|
return (pstatus[2] == Dependent);
|
|
}
|
|
};
|
|
|
|
class Ellipse: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
Ellipse() = default;
|
|
|
|
ParameterStatus getFocusXStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
ParameterStatus getFocusYStatus() const
|
|
{
|
|
return pstatus[1];
|
|
}
|
|
ParameterStatus getFocusMinorRadiusStatus() const
|
|
{
|
|
return pstatus[2];
|
|
}
|
|
|
|
bool isFocusDoF() const
|
|
{
|
|
return pstatus[0] == Dependent || pstatus[1] == Dependent;
|
|
}
|
|
bool isMinorRadiusDoF() const
|
|
{
|
|
return (pstatus[2] == Dependent);
|
|
}
|
|
};
|
|
|
|
class ArcOfHyperbola: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
ArcOfHyperbola() = default;
|
|
|
|
ParameterStatus getFocusXStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
ParameterStatus getFocusYStatus() const
|
|
{
|
|
return pstatus[1];
|
|
}
|
|
ParameterStatus getFocusMinorRadiusStatus() const
|
|
{
|
|
return pstatus[2];
|
|
}
|
|
ParameterStatus getStartParameter() const
|
|
{
|
|
return pstatus[3];
|
|
}
|
|
ParameterStatus getEndParameter() const
|
|
{
|
|
return pstatus[4];
|
|
}
|
|
};
|
|
|
|
class ArcOfParabola: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
ArcOfParabola() = default;
|
|
|
|
ParameterStatus getFocusXStatus() const
|
|
{
|
|
return pstatus[0];
|
|
}
|
|
ParameterStatus getFocusYStatus() const
|
|
{
|
|
return pstatus[1];
|
|
}
|
|
};
|
|
|
|
class BSpline: public EdgeParameterStatus
|
|
{
|
|
public:
|
|
BSpline() = default;
|
|
|
|
ParameterStatus getPoleXStatus(int poleindex) const
|
|
{
|
|
int npoles = pstatus.size() / 3;
|
|
|
|
if (poleindex < npoles) {
|
|
return pstatus[poleindex * 2];
|
|
}
|
|
|
|
THROWM(Base::IndexError, "Pole index out of range")
|
|
}
|
|
|
|
ParameterStatus getPoleYStatus(int poleindex) const
|
|
{
|
|
int npoles = pstatus.size() / 3;
|
|
|
|
if (poleindex < npoles) {
|
|
return pstatus[poleindex * 2 + 1];
|
|
}
|
|
|
|
THROWM(Base::IndexError, "Pole index out of range")
|
|
}
|
|
|
|
ParameterStatus getWeightStatus(int weightindex) const
|
|
{
|
|
int nweights = pstatus.size() / 3;
|
|
|
|
if (weightindex < nweights) {
|
|
return pstatus[nweights * 2 + weightindex];
|
|
}
|
|
|
|
THROWM(Base::IndexError, "Weight index out of range")
|
|
}
|
|
};
|
|
|
|
|
|
SolverGeometryExtension();
|
|
~SolverGeometryExtension() override = default;
|
|
|
|
std::unique_ptr<Part::GeometryExtension> copy() const override;
|
|
|
|
PyObject* getPyObject() override;
|
|
|
|
void notifyAttachment(Part::Geometry* geo) override;
|
|
|
|
SolverStatus getGeometry() const
|
|
{
|
|
return (Edge.getStatus() == Independent && Start.getStatus() == Independent
|
|
&& End.getStatus() == Independent && Mid.getStatus() == Independent)
|
|
? FullyConstraint
|
|
: NotFullyConstraint;
|
|
}
|
|
|
|
ParameterStatus getEdge() const
|
|
{
|
|
return Edge.getStatus();
|
|
}
|
|
Point& getPoint();
|
|
Line& getLine();
|
|
Arc& getArc();
|
|
Circle& getCircle();
|
|
ArcOfEllipse& getArcOfEllipse();
|
|
Ellipse& getEllipse();
|
|
ArcOfHyperbola& getArcOfHyperbola();
|
|
ArcOfParabola& getArcOfParabola();
|
|
BSpline& getBSpline();
|
|
EdgeParameterStatus getEdgeParameters()
|
|
{
|
|
return Edge;
|
|
}
|
|
void setEdge(ParameterStatus status)
|
|
{
|
|
Edge.setStatus(status);
|
|
}
|
|
void setEdge(int paramindex, ParameterStatus status)
|
|
{
|
|
Edge.setStatus(paramindex, status);
|
|
}
|
|
|
|
ParameterStatus getStart() const
|
|
{
|
|
return Start.getStatus();
|
|
}
|
|
PointParameterStatus getStartPoint() const
|
|
{
|
|
return Start;
|
|
}
|
|
void setStart(ParameterStatus xstatus, ParameterStatus ystatus)
|
|
{
|
|
Start.setStatus(xstatus, ystatus);
|
|
}
|
|
void setStartx(ParameterStatus xstatus)
|
|
{
|
|
Start.setStatusx(xstatus);
|
|
}
|
|
void setStarty(ParameterStatus ystatus)
|
|
{
|
|
Start.setStatusy(ystatus);
|
|
}
|
|
|
|
ParameterStatus getMid() const
|
|
{
|
|
return Mid.getStatus();
|
|
}
|
|
PointParameterStatus getMidPoint() const
|
|
{
|
|
return Mid;
|
|
}
|
|
void setMid(ParameterStatus xstatus, ParameterStatus ystatus)
|
|
{
|
|
Mid.setStatus(xstatus, ystatus);
|
|
}
|
|
void setMidx(ParameterStatus xstatus)
|
|
{
|
|
Mid.setStatusx(xstatus);
|
|
}
|
|
void setMidy(ParameterStatus ystatus)
|
|
{
|
|
Mid.setStatusy(ystatus);
|
|
}
|
|
|
|
ParameterStatus getEnd() const
|
|
{
|
|
return End.getStatus();
|
|
}
|
|
PointParameterStatus getEndPoint() const
|
|
{
|
|
return End;
|
|
}
|
|
|
|
void setEnd(ParameterStatus xstatus, ParameterStatus ystatus)
|
|
{
|
|
End.setStatus(xstatus, ystatus);
|
|
}
|
|
void setEndx(ParameterStatus xstatus)
|
|
{
|
|
End.setStatusx(xstatus);
|
|
}
|
|
void setEndy(ParameterStatus ystatus)
|
|
{
|
|
End.setStatusy(ystatus);
|
|
}
|
|
|
|
PointParameterStatus getPoint(Sketcher::PointPos pos) const;
|
|
|
|
void init(ParameterStatus status)
|
|
{
|
|
Edge.setStatus(status);
|
|
Start.setStatus(status);
|
|
Mid.setStatus(status);
|
|
End.setStatus(status);
|
|
}
|
|
|
|
protected:
|
|
void copyAttributes(Part::GeometryExtension* cpy) const override;
|
|
|
|
private:
|
|
SolverGeometryExtension(const SolverGeometryExtension&) = default;
|
|
|
|
void ensureType(const Base::Type& type);
|
|
|
|
private:
|
|
EdgeParameterStatus Edge;
|
|
|
|
PointParameterStatus Start;
|
|
PointParameterStatus Mid;
|
|
PointParameterStatus End;
|
|
|
|
Base::Type GeometryType;
|
|
};
|
|
|
|
} // namespace Sketcher
|
|
|
|
|
|
#endif // SKETCHER_SOLVERGEOMETRYEXTENSION_H
|