FreeCAD/src/Mod/Sketcher/App/Sketch.h
2017-01-10 23:34:49 +01:00

445 lines
21 KiB
C++

/***************************************************************************
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2010 *
* *
* 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_SKETCH_H
#define SKETCHER_SKETCH_H
#include <App/PropertyStandard.h>
#include <App/PropertyFile.h>
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/TopoShape.h>
#include "Constraint.h"
#include "planegcs/GCS.h"
#include <Base/Persistence.h>
namespace Sketcher
{
class SketcherExport Sketch :public Base::Persistence
{
TYPESYSTEM_HEADER();
public:
Sketch();
~Sketch();
// from base class
virtual unsigned int getMemSize(void) const;
virtual void Save(Base::Writer &/*writer*/) const;
virtual void Restore(Base::XMLReader &/*reader*/);
/// solve the actual set up sketch
int solve(void);
/// resets the solver
int resetSolver();
/// get standard (aka fine) solver precision
double getSolverPrecision(){ return GCSsys.getFinePrecision(); }
/// delete all geometry and constraints, leave an empty sketch
void clear(void);
/** set the sketch up with geoms and constraints
*
* returns the degree of freedom of a sketch and calculates a list of
* conflicting constraints
*
* 0 degrees of freedom correspond to a fully constrained sketch
* -1 degrees of freedom correspond to an over-constrained sketch
* positive degrees of freedom correspond to an under-constrained sketch
*
* an over-constrained sketch will always contain conflicting constraints
* a fully constrained or under-constrained sketch may contain conflicting
* constraints or may not
*/
int setUpSketch(const std::vector<Part::Geometry *> &GeoList, const std::vector<Constraint *> &ConstraintList,
int extGeoCount=0);
/// return the actual geometry of the sketch a TopoShape
Part::TopoShape toShape(void) const;
/// add unspecified geometry
int addGeometry(const Part::Geometry *geo, bool fixed=false);
/// add unspecified geometry
int addGeometry(const std::vector<Part::Geometry *> &geo, bool fixed=false);
/// returns the actual geometry
std::vector<Part::Geometry *> extractGeometry(bool withConstructionElements=true,
bool withExternalElements=false) const;
/// get the geometry as python objects
Py::Tuple getPyGeometry(void) const;
/// retrieves the index of a point
int getPointId(int geoId, PointPos pos) const;
/// retrieves a point
Base::Vector3d getPoint(int geoId, PointPos pos);
// Inline methods
inline bool hasConflicts(void) const { return !Conflicting.empty(); }
inline const std::vector<int> &getConflicting(void) const { return Conflicting; }
inline bool hasRedundancies(void) const { return !Redundant.empty(); }
inline const std::vector<int> &getRedundant(void) const { return Redundant; }
/** set the datum of a distance or angle constraint to a certain value and solve
* This can cause the solving to fail!
*/
int setDatum(int constrId, double value);
/** initializes a point (or curve) drag by setting the current
* sketch status as a reference
*/
int initMove(int geoId, PointPos pos, bool fine=true);
/** move this point (or curve) to a new location and solve.
* This will introduce some additional weak constraints expressing
* a condition for satisfying the new point location!
* The relative flag permits moving relatively to the current position
*/
int movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false);
/// add dedicated geometry
//@{
/// add a point
int addPoint(const Part::GeomPoint &point, bool fixed=false);
/// add an infinite line
int addLine(const Part::GeomLineSegment &line, bool fixed=false);
/// add a line segment
int addLineSegment(const Part::GeomLineSegment &lineSegment, bool fixed=false);
/// add a arc (circle segment)
int addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed=false);
/// add a circle
int addCircle(const Part::GeomCircle &circle, bool fixed=false);
/// add an ellipse
int addEllipse(const Part::GeomEllipse &ellipse, bool fixed=false);
/// add an arc of ellipse
int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false);
/// add an arc of hyperbola
int addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, bool fixed=false);
/// add an arc of parabola
int addArcOfParabola(const Part::GeomArcOfParabola &parabolaSegment, bool fixed=false);
/// add a BSpline
int addBSpline(const Part::GeomBSplineCurve &spline, bool fixed=false);
//@}
/// constraints
//@{
/// add all constraints in the list
int addConstraints(const std::vector<Constraint *> &ConstraintList);
/// add one constraint to the sketch
int addConstraint(const Constraint *constraint);
/**
* add a fixed X coordinate constraint to a point
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addCoordinateXConstraint(int geoId, PointPos pos, double * value);
/**
* add a fixed Y coordinate constraint to a point
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addCoordinateYConstraint(int geoId, PointPos pos, double * value);
/**
* add a horizontal distance constraint to two points or line ends
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceXConstraint(int geoId, double * value);
/**
* add a horizontal distance constraint to two points or line ends
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceXConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value);
/**
* add a vertical distance constraint to two points or line ends
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceYConstraint(int geoId, double * value);
/**
* add a vertical distance constraint to two points or line ends
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceYConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value);
/// add a horizontal constraint to a geometry
int addHorizontalConstraint(int geoId);
int addHorizontalConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/// add a vertical constraint to a geometry
int addVerticalConstraint(int geoId);
int addVerticalConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/// add a coincident constraint to two points of two geometries
int addPointCoincidentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/**
* add a length or distance constraint
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceConstraint(int geoId1, double * value);
/**
* add a length or distance constraint
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, double * value);
/**
* add a length or distance constraint
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value);
/// add a parallel constraint between two lines
int addParallelConstraint(int geoId1, int geoId2);
/// add a perpendicular constraint between two lines
int addPerpendicularConstraint(int geoId1, int geoId2);
/// add a tangency constraint between two geometries
int addTangentConstraint(int geoId1, int geoId2);
int addAngleAtPointConstraint(
int geoId1, PointPos pos1,
int geoId2, PointPos pos2,
int geoId3, PointPos pos3,
double * value,
ConstraintType cTyp);
/**
* add a radius constraint on a circle or an arc
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addRadiusConstraint(int geoId, double * value);
/**
* add an angle constraint on a line or between two lines
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addAngleConstraint(int geoId, double * value);
/**
* add an angle constraint on a line or between two lines
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addAngleConstraint(int geoId1, int geoId2, double * value);
/**
* add an angle constraint on a line or between two lines
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value);
/**
* add angle-via-point constraint between any two curves
*
* double * value is a pointer to double allocated in the heap, containing the
* constraint value and already inserted into either the FixParameters or
* Parameters array, as the case may be.
*/
int addAngleViaPointConstraint(int geoId1, int geoId2, int geoId3, PointPos pos3, double value);
/// add an equal length or radius constraints between two lines or between circles and arcs
int addEqualConstraint(int geoId1, int geoId2);
/// add a point on line constraint
int addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2);
/// add a symmetric constraint between two points with respect to a line
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3);
/// add a symmetric constraint between three points, the last point is in the middle of the first two
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3, PointPos pos3);
/**
* add a snell's law constraint
*
* double * value and double * second are each a pointer to double
* allocated in the heap and already inserted into either the
* FixParameters or Parameters array, as the case may be.
*
* value must contain the constraint value (the ratio of n2/n1)
* second may be initialized to any value, however the solver will
* provide n1 in value and n2 in second.
*/
int addSnellsLawConstraint(int geoIdRay1, PointPos posRay1,
int geoIdRay2, PointPos posRay2,
int geoIdBnd,
double * value,
double * second);
//@}
/// Internal Alignment constraints
//@{
/// add InternalAlignmentEllipseMajorDiameter to a line and an ellipse
int addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2);
int addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2);
int addInternalAlignmentEllipseFocus1(int geoId1, int geoId2);
int addInternalAlignmentEllipseFocus2(int geoId1, int geoId2);
/// add InternalAlignmentHyperbolaMajorRadius to a line and a hyperbola
int addInternalAlignmentHyperbolaMajorDiameter(int geoId1, int geoId2);
int addInternalAlignmentHyperbolaMinorDiameter(int geoId1, int geoId2);
int addInternalAlignmentHyperbolaFocus(int geoId1, int geoId2);
int addInternalAlignmentParabolaFocus(int geoId1, int geoId2);
int addInternalAlignmentBSplineControlPoint(int geoId1, int geoId2, int poleindex);
//@}
public:
//This func is to be used during angle-via-point constraint creation. It calculates
//the angle between geoId1,geoId2 at point px,py. The point should be on both curves,
//otherwise the result will be systematically off (but smoothly approach the correct
//value as the point approaches intersection of curves).
double calculateAngleViaPoint(int geoId1, int geoId2, double px, double py );
//This is to be used for rendering of angle-via-point constraint.
Base::Vector3d calculateNormalAtPoint(int geoIdCurve, double px, double py);
//icstr should be the value returned by addXXXXConstraint
//see more info in respective function in GCS.
double calculateConstraintError(int icstr) { return GCSsys.calculateConstraintErrorByTag(icstr);}
/// Returns the size of the Geometry
int getGeometrySize(void) const {return Geoms.size();}
enum GeoType {
None = 0,
Point = 1, // 1 Point(start), 2 Parameters(x,y)
Line = 2, // 2 Points(start,end), 4 Parameters(x1,y1,x2,y2)
Arc = 3, // 3 Points(start,end,mid), (4)+5 Parameters((x1,y1,x2,y2),x,y,r,a1,a2)
Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r)
Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of elipse with respect of sketch xaxis
ArcOfEllipse = 6,
ArcOfHyperbola = 7,
ArcOfParabola = 8,
BSpline = 9
};
float SolveTime;
protected:
/// container element to store and work with the geometric elements of this sketch
struct GeoDef {
GeoDef() : geo(0),type(None),external(false),index(-1),
startPointId(-1),midPointId(-1),endPointId(-1) {}
Part::Geometry * geo; // pointer to the geometry
GeoType type; // type of the geometry
bool external; // flag for external geometries
int index; // index in the corresponding storage vector (Lines, Arcs, Circles, ...)
int startPointId; // index in Points of the start point of this geometry
int midPointId; // index in Points of the start point of this geometry
int endPointId; // index in Points of the end point of this geometry
};
/// container element to store and work with the constraints of this sketch
struct ConstrDef {
ConstrDef() : constr(0)
, driving(true)
, value(0)
, secondvalue(0) {}
Constraint * constr; // pointer to the constraint
bool driving;
double * value;
double * secondvalue; // this is needed for SnellsLaw
};
std::vector<GeoDef> Geoms;
std::vector<ConstrDef> Constrs;
GCS::System GCSsys;
int ConstraintsCounter;
std::vector<int> Conflicting;
std::vector<int> Redundant;
// solving parameters
std::vector<double*> Parameters; // with memory allocation
std::vector<double*> FixParameters; // with memory allocation
std::vector<double> MoveParameters, InitParameters;
std::vector<GCS::Point> Points;
std::vector<GCS::Line> Lines;
std::vector<GCS::Arc> Arcs;
std::vector<GCS::Circle> Circles;
std::vector<GCS::Ellipse> Ellipses;
std::vector<GCS::ArcOfEllipse> ArcsOfEllipse;
std::vector<GCS::ArcOfHyperbola> ArcsOfHyperbola;
std::vector<GCS::ArcOfParabola> ArcsOfParabola;
std::vector<GCS::BSpline> BSplines;
bool isInitMove;
bool isFine;
public:
GCS::Algorithm defaultSolver;
GCS::Algorithm defaultSolverRedundant;
inline void setDogLegGaussStep(GCS::DogLegGaussStep mode){GCSsys.dogLegGaussStep=mode;}
inline void setDebugMode(GCS::DebugMode mode) {debugMode=mode;GCSsys.debugMode=mode;}
inline GCS::DebugMode getDebugMode(void) {return debugMode;}
inline void setMaxIter(int maxiter){GCSsys.maxIter=maxiter;}
inline void setMaxIterRedundant(int maxiter){GCSsys.maxIterRedundant=maxiter;}
inline void setSketchSizeMultiplier(bool mult){GCSsys.sketchSizeMultiplier=mult;}
inline void setSketchSizeMultiplierRedundant(bool mult){GCSsys.sketchSizeMultiplierRedundant=mult;}
inline void setConvergence(double conv){GCSsys.convergence=conv;}
inline void setConvergenceRedundant(double conv){GCSsys.convergenceRedundant=conv;}
inline void setQRAlgorithm(GCS::QRAlgorithm alg){GCSsys.qrAlgorithm=alg;}
inline void setQRPivotThreshold(double val){GCSsys.qrpivotThreshold=val;}
inline void setLM_eps(double val){GCSsys.LM_eps=val;}
inline void setLM_eps1(double val){GCSsys.LM_eps1=val;}
inline void setLM_tau(double val){GCSsys.LM_tau=val;}
inline void setDL_tolg(double val){GCSsys.DL_tolg=val;}
inline void setDL_tolx(double val){GCSsys.DL_tolx=val;}
inline void setDL_tolf(double val){GCSsys.DL_tolf=val;}
inline void setLM_epsRedundant(double val){GCSsys.LM_epsRedundant=val;}
inline void setLM_eps1Redundant(double val){GCSsys.LM_eps1Redundant=val;}
inline void setLM_tauRedundant(double val){GCSsys.LM_tauRedundant=val;}
inline void setDL_tolgRedundant(double val){GCSsys.DL_tolgRedundant=val;}
inline void setDL_tolxRedundant(double val){GCSsys.DL_tolxRedundant=val;}
inline void setDL_tolfRedundant(double val){GCSsys.DL_tolfRedundant=val;}
protected:
GCS::DebugMode debugMode;
private:
bool updateGeometry(void);
bool updateNonDrivingConstraints(void);
/// checks if the index bounds and converts negative indices to positive
int checkGeoId(int geoId);
GCS::Curve* getGCSCurveByGeoId(int geoId);
};
} //namespace Part
#endif // SKETCHER_SKETCH_H