/*************************************************************************** * Copyright (c) 2009 Juergen Riegel * * * * 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 SKETCHERGUI_VIEWPROVIDERSKETCH_H #define SKETCHERGUI_VIEWPROVIDERSKETCH_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PropertyVisualLayerList.h" #include "ShortcutListener.h" class TopoDS_Shape; class TopoDS_Face; class SoSeparator; class SbLine; class SbVec2f; class SbVec3f; class SoCoordinate3; class SoInfo; class SoPointSet; class SoTransform; class SoLineSet; class SoMarkerSet; class SoPickedPoint; class SoRayPickAction; class SoImage; class QImage; class QColor; class SoText2; class SoTranslation; class SbString; class SbTime; namespace Part { class Geometry; } namespace Gui { class View3DInventorViewer; } namespace Sketcher { class Constraint; class Sketch; class SketchObject; } // namespace Sketcher namespace SketcherGui { class EditModeCoinManager; class SnapManager; class DrawSketchHandler; using GeoList = Sketcher::GeoList; using GeoListFacade = Sketcher::GeoListFacade; /** @brief The Sketch ViewProvider * * @details * * As any ViewProvider, this class is responsible for the view representation * of Sketches. * * Functionality inherited from parent classes deal with the majority of the * representation of a sketch when it is ** not ** in edit mode. * * This class handles mainly the drawing and editing of the sketch. * * The class delegates a substantial part of this functionality on two main * classes, DrawSketchHandler and EditModeCoinManager. * * In order to enforce a certain degree of encapsulation and promote a not * too tight coupling, while still allowing well defined collaboration, * DrawSketchHandler and EditModeCoinManager access ViewProviderSketch via * two Attorney classes (Attorney-Client pattern), ViewProviderSketchDrawSketchHandlerAttorney * and ViewProviderSketchCoinAttorney. * * Given the substantial amount of code involved in coin node management, EditModeCoinManager * further delegates on other specialised helper classes. Some of them share the * ViewProviderSketchCoinAttorney, which defines the maximum coupling and minimum encapsulation. * * DrawSketchHandler aids temporary edit mode drawing and is extensively used for the creation * of geometry. * * EditModeCoinManager takes over the responsibility of creating the Coin (Inventor) scenograph * and modifying it, including all the drawing of geometry, constraints and overlay layer. This * is an exclusive responsibility under the Single Responsibility Principle. * * EditModeCoinManager exposes a public interface to be used by ViewProviderSketch. Where, * EditModeCoinManager needs special access to facilities of ViewProviderSketch in order to fulfil * its responsibility, this access is defined by ViewProviderSketchCoinAttorney. * * Similarly, DrawSketchHandler takes over the responsibility of drawing edit temporal curves and * markers necessary to enable visual feedback to the user, as well as the UI interaction during * such edits. This is its exclusive responsibility under the Single Responsibility Principle. * * A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing * (see for example all the handlers for creation of new geometry). These derived classes do * not * * have direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep * coupling under control. However, generic functionality requiring access to the Attorney can be * implemented in DrawSketchHandler and used from its derived classes by virtue of the inheritance. * This promotes a concentrating the coupling in a single point (and code reuse). * */ class SketcherGuiExport ViewProviderSketch: public PartGui::ViewProvider2DObject, public PartGui::ViewProviderGridExtension, public PartGui::ViewProviderAttachExtension, public Gui::SelectionObserver { Q_DECLARE_TR_FUNCTIONS(SketcherGui::ViewProviderSketch) PROPERTY_HEADER_WITH_OVERRIDE(SketcherGui::ViewProviderSketch); private: /** * @brief * This nested class is responsible for attaching to the parameters relevant for * ViewProviderSketch, initialising the ViewProviderSketch to the current configuration * and handle in real time any change to their values. */ class ParameterObserver: public ParameterGrp::ObserverType { public: explicit ParameterObserver(ViewProviderSketch& client); ~ParameterObserver() override; void initParameters(); void subscribeToParameters(); void unsubscribeToParameters(); /** Observer for parameter group. */ void OnChange(Base::Subject& rCaller, const char* sReason) override; void updateFromParameter(const char* property); private: void updateBoolProperty(const std::string& string, App::Property* property, bool defaultvalue); void updateGridSize(const std::string& string, App::Property* property); // Only for colors outside of edit mode, edit mode colors are handled by // EditModeCoinManager. void updateColorProperty(const std::string& string, App::Property* property, float r, float g, float b); void updateEscapeKeyBehaviour(const std::string& string, App::Property* property); void updateAutoRecompute(const std::string& string, App::Property* property); void updateRecalculateInitialSolutionWhileDragging(const std::string& string, App::Property* property); private: ViewProviderSketch& Client; std::map, App::Property*>> parameterMap; }; /** @name Classes storing the state of Dragging, Selection and Preselection * All these classes enable the identification of a Vertex, a Curve, the root * Point, axes, and constraints. * * A word on indices and ways to identify elements and parts of them: * * The Sketcher has a general main way to identify geometry, {GeoId, PointPos}, * these can be provided as separate data, or using Sketcher::GeoElementId. The * latter defines comparison and equality operators enabling, for example to use * it as key in a std::map. * * While it is indeed possible to refer to any point using that nomenclature, creating * maps in certain circumnstances leads to a performance drawback. Additionally, the * legacy selection mechanism refers to positive indexed Vertices (for both normal and * external vertices). Both reasons discourage moving to a single identification. This * situation has been identified at different levels: * * (1) In sketch.cpp, the solver facade defining the interface with GCS, both * {GeoId, PointPos} and PointId are used. * * (2) In SketchObject.cpp, the actual document object, both {GeoId, PointPos} and VertexId * are used (see VertexId2GeoId and VertexId2GeoPosId). * * (3) In ViewProviderSketch, both {GeoId, PointPos} an Point indices are used (see these * structures) * * (4) At CoinManager level, {GeoId, PointPos}, Point indices (for selection) and MultiFieldIds * (specific structure defining a coin multifield index and layer) are used. * * Using a single index instead of a multi-index field, allows mappings to be implemented via * std::vectors instead of std::maps. Direct mappings using std::vectors are accessed in * constant time. Multi-index mappings relying on std::maps involve a search for the key. This * leads to a drop in performance. * * What are these indices and how do they relate each other? * 1. PointId, VertexId depend on the order of the geometries in the sketch. GeoList and * GeoListFacade enable to convert between indices. * 2. CurveId is basically the GeoId assuming PointPos to be PointPos::none (edge) * 3. Sometimes, Axes and root point are separated into a third index or enum. Legacy reasons * aside, the root point is has GeoId=-1, which is sometimes used as invalid value in positive * only indices. Additionally, root point and the Horizontal Axes both have GeoId=-1 (differing * in PointPos only). Following the decision not to rely on PointPos, creating a separate index, * best when enum-ed, appears justified. */ //@{ /** @brief Class to store vector and item Id for dragging. * * @details * Ids are zero-indexed points and curves. * * The DragPoint indexing matches PreselectPoint indexing. * */ class Drag { public: Drag() { reset(); } void reset() { resetVector(); resetIds(); } void resetVector() { xInit = 0; yInit = 0; relative = false; } void resetIds() { Dragged.clear(); DragConstraintSet.clear(); } double xInit, yInit; // starting point of the dragging operation bool relative; // whether the dragging move vector is relative or absolute std::vector Dragged; // dragged geometries std::set DragConstraintSet; // dragged constraints ids }; // TODO: Selection and Preselection should use a same structure. Probably Drag should use the // same structure too. To be refactored separately. /** @brief Class to store preselected element ids. * * @details * * PreselectPoint is the positive VertexId. * * PreselectCurve is the GeoID, but without the Axes (indices -1 and -2). * * VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root * point) * * EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N = * -PreselectCurve - 2 * * The PreselectPoint indexing matches DragPoint indexing (it further includes negative edges, * which are not meaningful for Dragging). * */ class Preselection { public: enum SpecialValues { InvalidPoint = -1, InvalidCurve = -1, ExternalCurve = -3 }; enum class Axes { None = -1, RootPoint = 0, HorizontalAxis = 1, VerticalAxis = 2 }; Preselection() { reset(); } void reset() { PreselectPoint = InvalidPoint; PreselectCurve = InvalidCurve; PreselectCross = Axes::None; PreselectConstraintSet.clear(); blockedPreselection = false; } bool isPreselectPointValid() const { return PreselectPoint > InvalidPoint; } bool isPreselectCurveValid() const { return PreselectCurve > InvalidCurve || PreselectCurve <= ExternalCurve; } bool isCrossPreselected() const { return PreselectCross != Axes::None; } bool isEdge() const { return PreselectCurve > InvalidCurve; } bool isExternalEdge() const { return PreselectCurve <= ExternalCurve; } int getPreselectionVertexIndex() const { return PreselectPoint + 1; } int getPreselectionEdgeIndex() const { return PreselectCurve + 1; } int getPreselectionExternalEdgeIndex() const { return -PreselectCurve - 2; } int PreselectPoint; // VertexN, with N = PreselectPoint + 1, same as DragPoint indexing // (NOTE -1 is NOT the root point) int PreselectCurve; // EdgeN, with N = PreselectCurve + 1 for positive values ; // ExternalEdgeN, with N = -PreselectCurve - 2 Axes PreselectCross; // 0 => rootPoint, 1 => HAxis, 2 => VAxis std::set PreselectConstraintSet; // ConstraintN, N = index + 1 bool blockedPreselection; }; /** @brief Class to store selected element ids. * * @details * Selection follows yet a different mechanism than preselection. * * SelPointSet indices as PreselectPoint, with the addition that -1 is indeed the rootpoint. * * SelCurvSet indices as PreselectCurve, with the addition that -1 is the HAxis and -2 is the * VAxis * */ class Selection { public: enum SpecialValues { RootPoint = -1, HorizontalAxis = -1, VerticalAxis = -2 }; Selection() { reset(); } void reset() { SelPointSet.clear(); SelCurvSet.clear(); SelConstraintSet.clear(); } std::set SelPointSet; // Indices as PreselectPoint (and -1 for rootpoint) std::set SelCurvSet; // also holds cross axes at -1 and -2 std::set SelConstraintSet; // ConstraintN, N = index + 1. }; //@} /** @brief Private struct maintaining information necessary for detecting double click. */ struct DoubleClick { static SbTime prvClickTime; static SbVec2s prvClickPos; // used by double-click-detector static SbVec2s prvCursorPos; static SbVec2s newCursorPos; }; /** @brief Private struct grouping ViewProvider parameters and internal variables */ struct ViewProviderParameters { bool handleEscapeButton = false; bool autoRecompute = false; bool recalculateInitialSolutionWhileDragging = false; bool isShownVirtualSpace = false; // indicates whether the present virtual space view is the // Real Space or the Virtual Space (virtual space 1 or 2) bool buttonPress = false; int stdCountSegments = 50; // preferences controlled default geometry sampling for selection }; /** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode * sensor data */ struct VPRender { ViewProviderSketch* vp; SoRenderManager* renderMgr; }; public: /* API to retrieve information about the active DrawSketchHandler. In particular related to how * tool widgets should be handled. */ class ToolManager { public: explicit ToolManager(ViewProviderSketch* vp); /** @brief Factory function returning a tool widget of the type appropriate for the current * active tool. If no tool is active, expect a nullptr. */ std::unique_ptr createToolWidget() const; /** @brief Returns whether the current tool's widget is intended to be visible for the user */ bool isWidgetVisible() const; /** @brief Returns the intended icon for a visible tool widget (e.g. for header/title).*/ QPixmap getToolIcon() const; /** @brief Returns the intended text for a visible tool widget (e.g. for header/title).*/ QString getToolWidgetText() const; private: ViewProviderSketch* vp; }; public: /// constructor ViewProviderSketch(); /// destructor ~ViewProviderSketch() override; /** @name Properties */ //@{ App::PropertyBool Autoconstraints; App::PropertyBool AvoidRedundant; App::PropertyPythonObject TempoVis; App::PropertyBool HideDependent; App::PropertyBool ShowLinks; App::PropertyBool ShowSupport; App::PropertyBool RestoreCamera; App::PropertyBool ForceOrtho; App::PropertyBool SectionView; App::PropertyBool AutoColor; App::PropertyString EditingWorkbench; SketcherGui::PropertyVisualLayerList VisualLayerList; //@} const ToolManager toolManager; // TODO: It is difficult to imagine that these functions are necessary in the public interface. // This requires review at a second stage and possibly refactor it. /** @name handler control */ //@{ /// sets an DrawSketchHandler in control void activateHandler(std::unique_ptr newHandler); /// removes the active handler void purgeHandler(); //@} // TODO: SketchMode should be refactored. DrawSketchHandler, its inheritance and free functions // should access this mode via the DrawSketchHandler Attorney. I will not refactor this at this // moment, as the refactor will be even more extensive and difficult to review. But this should // be done in a second stage. /** @name modus handling */ //@{ /// mode table enum SketchMode { STATUS_NONE, /**< enum value View provider is in neutral. */ STATUS_SELECT_Point, /**< enum value a point was selected. */ STATUS_SELECT_Edge, /**< enum value an edge was selected. */ STATUS_SELECT_Constraint, /**< enum value a constraint was selected. */ STATUS_SELECT_Cross, /**< enum value the base coordinate system was selected. */ STATUS_SELECT_Wire, /**< enum value and edge was double clicked. */ STATUS_SKETCH_Drag, /**< enum value while dragging curves and or points. */ STATUS_SKETCH_DragConstraint, /**< enum value while dragging a compatible constraint. */ STATUS_SKETCH_UseHandler, /**< enum value a DrawSketchHandler is in control. */ STATUS_SKETCH_StartRubberBand, /**< enum value for initiating a rubber band selection */ STATUS_SKETCH_UseRubberBand /**< enum value when making a rubber band selection */ }; /// is called by GuiCommands to set the drawing mode void setSketchMode(SketchMode mode) { Mode = mode; } /// get the sketch mode SketchMode getSketchMode() const { return Mode; } // create right click context menu based on selection in the 3D view void generateContextMenu(); //@} /** @name Drawing functions */ //@{ /// draw the sketch in the inventor nodes /// temp => use temporary solver solution in SketchObject /// recreateinformationscenography => forces a rebuild of the information overlay scenography void draw(bool temp = false, bool rebuildinformationoverlay = true); /// helper change the color of the sketch according to selection and solver status void updateColor(); //@} /** @name Selection functions */ //@{ /// Is the view provider selectable bool isSelectable() const override; /// Observer message from the Selection void onSelectionChanged(const Gui::SelectionChanges& msg) override; //@} /** @name Toggle angle snapping and set the reference point */ //@{ /// Toggle angle snapping and set the reference point void setAngleSnapping(bool enable, Base::Vector2d referencePoint = Base::Vector2d(0., 0.)); /** @name Access to Sketch and Solver objects */ //@{ /// get the pointer to the sketch document object Sketcher::SketchObject* getSketchObject() const; /** returns a const reference to the last solved sketch object. It guarantees that * the solver object does not lose synchronisation with the SketchObject properties. * * NOTE: Operations requiring * write * access to the solver must be done via SketchObject * interface. See for example functions: * -> inline void setRecalculateInitialSolutionWhileMovingPoint(bool * recalculateInitialSolutionWhileMovingPoint) * -> inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true) * -> inline int moveGeometryTemporary(int geoId, PointPos pos, Base::Vector3d toPoint, bool * relative=false) * -> inline void updateSolverExtension(int geoId, std::unique_ptr && * ext) */ const Sketcher::Sketch& getSolvedSketch() const; //@} /** @name miscelanea utilities */ //@{ /*! Look at the center of the bounding of all selected items */ void centerSelection(); /// returns the scale factor float getScaleFactor() const; /// returns view orientation factor int getViewOrientationFactor() const; //@} /** @name constraint Virtual Space visibility management */ //@{ /// updates the visibility of the virtual space of constraints void updateVirtualSpace(); /// determines whether the constraints in the normal space or the ones in the virtual are to be /// shown void setIsShownVirtualSpace(bool isshownvirtualspace); /// returns whether the virtual space is being shown bool getIsShownVirtualSpace() const; //@} /** @name base class implementer */ //@{ void attach(App::DocumentObject*) override; void updateData(const App::Property*) override; void setupContextMenu(QMenu* menu, QObject* receiver, const char* member) override; /// is called when the Provider is in edit and a deletion request occurs bool onDelete(const std::vector&) override; /// Is called by the tree if the user double clicks on the object. It returns the string /// for the transaction that will be shown in the undo/redo dialog. /// If null is returned then no transaction will be opened. const char* getTransactionText() const override { return nullptr; } /// is called when the provider is in edit and a "Select All" command was issued /// Provider shall return 'false' is it ignores the command, 'true' otherwise bool selectAll() override; /// is called by the tree if the user double clicks on the object bool doubleClicked() override; /// is called when the Provider is in edit and the mouse is moved bool mouseMove(const SbVec2s& pos, Gui::View3DInventorViewer* viewer) override; /// is called when the Provider is in edit and a key event ocours. Only ESC ends edit. bool keyPressed(bool pressed, int key) override; /// is called when the Provider is in edit and the mouse is clicked bool mouseButtonPressed(int Button, bool pressed, const SbVec2s& cursorPos, const Gui::View3DInventorViewer* viewer) override; bool mouseWheelEvent(int delta, const SbVec2s& cursorPos, const Gui::View3DInventorViewer* viewer) override; //@} void deleteSelected(); /// Control the overlays appearing on the Tree and reflecting different sketcher states QIcon mergeColorfulOverlayIcons(const QIcon& orig) const override; /** @name Signals for controlling information in Task dialogs */ //@{ /// signals if the constraints list has changed boost::signals2::signal signalConstraintsChanged; /// signals if the sketch has been set up boost::signals2::signal< void(const QString& state, const QString& msg, const QString& url, const QString& linkText)> signalSetUp; /// signals if the elements list has changed boost::signals2::signal signalElementsChanged; //@} /** @name Register slot for signal */ //@{ template boost::signals2::connection registerToolChanged(F&& f) { return signalToolChanged.connect(std::forward(f)); } //@} /** @name Attorneys for collaboration with helper classes */ //@{ friend class ViewProviderSketchDrawSketchHandlerAttorney; friend class ViewProviderSketchCoinAttorney; friend class ViewProviderSketchSnapAttorney; //@} protected: /** @name enter/exit edit mode */ //@{ bool setEdit(int ModNum) override; void unsetEdit(int ModNum) override; void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override; void unsetEditViewer(Gui::View3DInventorViewer*) override; static void camSensCB(void* data, SoSensor*); // camera sensor callback static void camSensDeleteCB(void* data, SoSensor*); // camera sensor callback void onCameraChanged(SoCamera* cam); //@} /** @name miscelanea editing functions */ //@{ /// purges the DrawHandler if existing and tidies up void deactivateHandler(); /// get called if a subelement is double clicked while editing void editDoubleClicked(); /// get called when an edge is double clicked to select/unselect the whole wire void toggleWireSelelection(int geoId); //@} /** @name Solver Information */ //@{ /// update solver information based on last solving at SketchObject void UpdateSolverInformation(); /// Auxiliary function to generate messages about conflicting, redundant and malformed /// constraints static QString appendConstraintMsg(const QString& singularmsg, const QString& pluralmsg, const std::vector& vector); //@} /** @name manage updates during undo/redo operations */ //@{ void slotUndoDocument(const Gui::Document&); void slotRedoDocument(const Gui::Document&); void slotSolverUpdate(); void forceUpdateData(); //@} /** @name base class implementer */ //@{ /// get called by the container whenever a property has been changed void onChanged(const App::Property* prop) override; //@} /// hook after property restoring to change some property statuses void startRestoring() override; void finishRestoring() override; private: /// function to handle OCCT BSpline weight calculation singularities and representation void scaleBSplinePoleCirclesAndUpdateSolverAndSketchObjectGeometry( GeoListFacade& geolist, bool geometrywithmemoryallocation); /** @name geometry and coordinates auxiliary functions */ //@{ /// give the coordinates of a line on the sketch plane in sketcher (2D) coordinates void getCoordsOnSketchPlane(const SbVec3f& point, const SbVec3f& normal, double& u, double& v) const; /// give projecting line of position void getProjectingLine(const SbVec2s&, const Gui::View3DInventorViewer* viewer, SbLine&) const; //@} /** @name preselection functions */ //@{ /// helper to detect preselection bool detectAndShowPreselection(SoPickedPoint* Point, const SbVec2s& cursorPos); int getPreselectPoint() const; int getPreselectCurve() const; int getPreselectCross() const; void setPreselectPoint(int PreselectPoint); void setPreselectRootPoint(); void resetPreselectPoint(); bool setPreselect(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0); //@} /** @name dragging functions */ //@{ /// dragging helpers void initDragging(int geoId, Sketcher::PointPos pos, Gui::View3DInventorViewer* viewer); void doDragStep(double x, double y); void commitDragMove(double x, double y); //@} /** @name Selection functions */ //@{ /// box selection method void doBoxSelection(const SbVec2s& startPos, const SbVec2s& endPos, const Gui::View3DInventorViewer* viewer); void addSelectPoint(int SelectPoint); void removeSelectPoint(int SelectPoint); void clearSelectPoints(); bool isSelected(const std::string& ss) const; void rmvSelection(const std::string& subNameSuffix); bool addSelection(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0); bool addSelection2(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0); void preselectToSelection(const std::stringstream& ss, boost::scoped_ptr& pp, bool toggle); //@} /** @name miscelanea utilities */ //@{ /// moves a selected constraint void moveConstraint(int constNum, const Base::Vector2d& toPos); void moveConstraint(Sketcher::Constraint*, int constNum, const Base::Vector2d& toPos); void moveAngleConstraint(Sketcher::Constraint*, int constNum, const Base::Vector2d& toPos); /// returns whether the sketch is in edit mode. bool isInEditMode() const; //@} /** @name signals*/ //@{ /// signals a tool change boost::signals2::signal signalToolChanged; //@} void slotToolWidgetChanged(QWidget* newwidget); /** @name Attorney functions*/ //@{ /* private functions to decouple Attorneys and Clients from the internal implementation of the ViewProvider and its members, such as sketchObject (see friend attorney classes) and improve encapsulation. */ //********* ViewProviderSketchCoinAttorney *********************** bool constraintHasExpression(int constrid) const; const std::vector getConstraints() const; /// gets the corresponding constraint to the given \a constid /// or null if it doesn't exist. Sketcher::Constraint* getConstraint(int constid) const; // gets the list of geometry of the sketchobject or of the solver instance const GeoList getGeoList() const; GeoListFacade getGeoListFacade() const; Base::Placement getEditingPlacement() const; std::unique_ptr getRayPickAction() const; SbVec2f getScreenCoordinates(SbVec2f sketchcoordinates) const; QFont getApplicationFont() const; int defaultFontSizePixels() const; int getApplicationLogicalDPIX() const; double getRotation(SbVec3f pos0, SbVec3f pos1) const; bool isSketchInvalid() const; bool isSketchFullyConstrained() const; bool haveConstraintsInvalidGeometry() const; void addNodeToRoot(SoSeparator* node); void removeNodeFromRoot(SoSeparator* node); bool isConstraintPreselected(int constraintId) const; bool isPointSelected(int pointId) const; void executeOnSelectionPointSet(std::function&& operation) const; bool isCurveSelected(int curveId) const; bool isConstraintSelected(int constraintId) const; //********* ViewProviderSketchDrawSketchHandlerAttorney **********// void setConstraintSelectability(bool enabled = true); void setPositionText(const Base::Vector2d& Pos, const SbString& txt); void setPositionText(const Base::Vector2d& Pos); void resetPositionText(); /// draw the edit curve void drawEdit(const std::vector& EditCurve); void drawEdit(const std::list>& list); /// draw the edit markers void drawEditMarkers(const std::vector& EditMarkers, unsigned int augmentationlevel = 0); /// set the pick style of the sketch coordinate axes void setAxisPickStyle(bool on); void moveCursorToSketchPoint(Base::Vector2d point); void ensureFocus(); void preselectAtPoint(Base::Vector2d point); //@} private: /** @name Solver message creation*/ //@{ /* private functions to decouple Attorneys and Clients from the internal implementation of the ViewProvider and its members, such as sketchObject (see friend attorney classes) and improve encapsulation. */ /// generates a warning message about constraint conflicts and appends it to the given message static QString appendConflictMsg(const std::vector& conflicting); /// generates a warning message about redundant constraints and appends it to the given message static QString appendRedundantMsg(const std::vector& redundant); /// generates a warning message about partially redundant constraints and appends it to the /// given message static QString appendPartiallyRedundantMsg(const std::vector& partiallyredundant); /// generates a warning message about redundant constraints and appends it to the given message static QString appendMalformedMsg(const std::vector& redundant); //@} private: boost::signals2::connection connectUndoDocument; boost::signals2::connection connectRedoDocument; boost::signals2::connection connectSolverUpdate; // modes while sketching SketchMode Mode; // reference coordinates for relative operations Drag drag; Preselection preselection; Selection selection; std::unique_ptr rubberband; std::string editDocName; std::string editObjName; std::string editSubName; ShortcutListener* listener; std::unique_ptr editCoinManager; std::unique_ptr snapManager; std::unique_ptr pObserver; std::unique_ptr sketchHandler; ViewProviderParameters viewProviderParameters; using Connection = boost::signals2::connection; Connection connectionToolWidget; SoNodeSensor cameraSensor; int viewOrientationFactor; // stores if sketch viewed from front or back }; } // namespace SketcherGui #endif // SKETCHERGUI_VIEWPROVIDERSKETCH_H