/*************************************************************************** * 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 #include #include #include #include "Constraint.h" #include "planegcs/GCS.h" #include 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 &GeoList, const std::vector &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 &geo, bool fixed=false); /// returns the actual geometry std::vector 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 &getConflicting(void) const { return Conflicting; } inline bool hasRedundancies(void) const { return !Redundant.empty(); } inline const std::vector &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 ¶bolaSegment, 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 &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 Geoms; std::vector Constrs; GCS::System GCSsys; int ConstraintsCounter; std::vector Conflicting; std::vector Redundant; // solving parameters std::vector Parameters; // with memory allocation std::vector FixParameters; // with memory allocation std::vector MoveParameters, InitParameters; std::vector Points; std::vector Lines; std::vector Arcs; std::vector Circles; std::vector Ellipses; std::vector ArcsOfEllipse; std::vector ArcsOfHyperbola; std::vector ArcsOfParabola; std::vector 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