PartSet_TreeNodes.h
PartSet_FieldStepPrs.h
PartSet_WidgetBSplinePoints.h
+ PartSet_WidgetPolylinePoints.h
PartSet_BSplineWidget.h
)
PartSet_WidgetSketchCreator.h
PartSet_WidgetSketchLabel.h
PartSet_WidgetBSplinePoints.h
+ PartSet_WidgetPolylinePoints.h
PartSet_ExternalPointsMgr.h
PartSet_BSplineWidget.h
)
PartSet_TreeNodes.cpp
PartSet_FieldStepPrs.cpp
PartSet_WidgetBSplinePoints.cpp
+ PartSet_WidgetPolylinePoints.cpp
PartSet_BSplineWidget.cpp
)
#include "PartSet_Tools.h"
#include "PartSet_PreviewPlanes.h"
#include "PartSet_WidgetBSplinePoints.h"
+#include "PartSet_WidgetPolylinePoints.h"
#include "PartSet_WidgetPoint2d.h"
#include "PartSet_WidgetPoint2DFlyout.h"
#include "PartSet_WidgetShapeSelector.h"
aBSplineWgt->setSketch(mySketchMgr->activeSketch());
aWgt = aBSplineWgt;
}
+ else if (theType == "sketch-polyline_selector") {
+ PartSet_WidgetPolylinePoints* aBSplineWgt =
+ new PartSet_WidgetPolylinePoints(theParent, aWorkshop, theWidgetApi);
+ aBSplineWgt->setSketch(mySketchMgr->activeSketch());
+ aWgt = aBSplineWgt;
+ }
+
else if (theType == WDG_DOUBLEVALUE_EDITOR) {
aWgt = new PartSet_WidgetEditor(theParent, aWorkshop, theWidgetApi);
} else if (theType == "export_file_selector") {
--- /dev/null
+// Copyright (C) 2019-2020 CEA/DEN, EDF R&D
+//
+// This library 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.
+//
+// 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <PartSet_WidgetPolylinePoints.h>
+
+#include <PartSet_CenterPrs.h>
+#include <PartSet_ExternalObjectsMgr.h>
+#include <PartSet_Module.h>
+#include <PartSet_SketcherReentrantMgr.h>
+#include <PartSet_WidgetPoint2d.h>
+
+#include <XGUI_Tools.h>
+#include <XGUI_Workshop.h>
+#include <XGUI_Displayer.h>
+
+#include <ModuleBase_ISelection.h>
+#include <ModuleBase_IViewer.h>
+#include <ModuleBase_IViewWindow.h>
+#include <ModuleBase_LabelValue.h>
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_WidgetValidator.h>
+#include <ModuleBase_WidgetValidated.h>
+
+#include <Config_Keywords.h>
+#include <Config_WidgetAPI.h>
+
+#include <Events_Loop.h>
+
+#include <ModelAPI_Events.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_CompositeFeature.h>
+
+#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_IPresentable.h>
+
+#include <SketchPlugin_Feature.h>
+
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QMouseEvent>
+#include <QGraphicsEffect>
+#include <QScrollArea>
+
+static const double MaxCoordinate = 1e12;
+
+static bool IsPointCreated = false;
+
+PartSet_WidgetPolylinePoints::PartSet_WidgetPolylinePoints(QWidget* theParent,
+ ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData)
+: ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop),
+ myValueIsCashed(false), myIsFeatureVisibleInCash(true),
+ myXValueInCash(0), myYValueInCash(0), myFinished(false)
+{
+ QVBoxLayout* aMainLayout = new QVBoxLayout(this);
+ ModuleBase_Tools::zeroMargins(aMainLayout);
+
+ // the control should accept the focus, so the boolean flag is corrected to be true
+ myIsObligatory = true;
+ QString aPageName = translate(theData->getProperty(CONTAINER_PAGE_NAME));
+ myBox = new QGroupBox(aPageName, theParent);
+ myBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ myBox->setFlat(false);
+ aMainLayout->addWidget(myBox);
+
+ theData->getBooleanAttribute(DOUBLE_WDG_ACCEPT_EXPRESSIONS, true);
+
+ QVBoxLayout* aLayout = new QVBoxLayout(myBox);
+ ModuleBase_Tools::adjustMargins(aLayout);
+
+ myScrollArea = new QScrollArea(myBox);
+ myScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ myScrollArea->setWidgetResizable(true);
+ myScrollArea->setFrameStyle(QFrame::NoFrame);
+ aLayout->addWidget(myScrollArea);
+
+ QWidget* aContainer = new QWidget(myScrollArea);
+ QVBoxLayout* aBoxLay = new QVBoxLayout(aContainer);
+ aBoxLay->setContentsMargins(0, 0, 0, 0);
+
+ myGroupBox = new QWidget(aContainer);
+ QGridLayout* aGroupLay = new QGridLayout(myGroupBox);
+ ModuleBase_Tools::adjustMargins(aGroupLay);
+ aGroupLay->setSpacing(4);
+ aGroupLay->setColumnStretch(1, 1);
+ createNextPoint();
+ aBoxLay->addWidget(myGroupBox);
+ aBoxLay->addStretch(1);
+
+ myScrollArea->setWidget(aContainer);
+
+ myWidgetValidator = new ModuleBase_WidgetValidator(this, myWorkshop);
+
+}
+
+void PartSet_WidgetPolylinePoints::createNextPoint()
+{
+ storeCurentValue();
+
+ QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myGroupBox->layout());
+ int row = (int)myXSpin.size();
+
+ QString aPoleStr = translate("Point %1");
+ aPoleStr = aPoleStr.arg(myXSpin.size() + 1);
+
+ QGroupBox* aPoleGroupBox = new QGroupBox(aPoleStr, myGroupBox);
+ QGridLayout* aPoleLay = new QGridLayout(aPoleGroupBox);
+ ModuleBase_Tools::adjustMargins(aPoleLay);
+ aPoleLay->setSpacing(2);
+ aPoleLay->setColumnStretch(1, 1);
+
+ myXSpin.push_back(new ModuleBase_LabelValue(aPoleGroupBox, tr("X")));
+ aPoleLay->addWidget(myXSpin.back(), 0, 1);
+ myYSpin.push_back(new ModuleBase_LabelValue(aPoleGroupBox, tr("Y")));
+ aPoleLay->addWidget(myYSpin.back(), 1, 1);
+
+ aGroupLay->addWidget(aPoleGroupBox, row, 1);
+ IsPointCreated = true;
+}
+
+void PartSet_WidgetPolylinePoints::removeLastPoint()
+{
+ QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myGroupBox->layout());
+ QWidget* aXSpin = myXSpin.back();
+ QWidget* aYSpin = myYSpin.back();
+ QWidget* aBox = myXSpin.back()->parentWidget();
+ myYSpin.pop_back();
+ myXSpin.pop_back();
+
+ aGroupLay->removeWidget(aXSpin);
+ aGroupLay->removeWidget(aYSpin);
+ aGroupLay->removeWidget(aBox);
+
+ aBox->deleteLater();
+
+ // update polyline feature attributes
+ storeValueCustom();
+}
+
+
+PartSet_WidgetPolylinePoints::~PartSet_WidgetPolylinePoints()
+{
+}
+
+bool PartSet_WidgetPolylinePoints::setPoint(double theX, double theY)
+{
+ if (fabs(theX) >= MaxCoordinate || fabs(theY) >= MaxCoordinate)
+ return false;
+
+ myXSpin.back()->setValue(theX);
+ myYSpin.back()->setValue(theY);
+
+ storeValue();
+ return true;
+}
+
+void PartSet_WidgetPolylinePoints::storePoints() const
+{
+
+ std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+ AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(attributeID()));
+
+ int aSize = (int)myXSpin.size();
+ aPointArray->setSize(aSize);
+
+ std::vector<ModuleBase_LabelValue*>::const_iterator aXIt = myXSpin.begin();
+ std::vector<ModuleBase_LabelValue*>::const_iterator aYIt = myYSpin.begin();
+ for (int anIndex = 0; aXIt != myXSpin.end() && aYIt != myYSpin.end(); ++anIndex, ++aXIt, ++aYIt)
+ aPointArray->setPnt(anIndex, (*aXIt)->value(), (*aYIt)->value());
+
+}
+
+bool PartSet_WidgetPolylinePoints::storeValueCustom()
+{
+ std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+ if (!aData || !aData->isValid()) // can be on abort of sketcher element
+ return false;
+ AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(attributeID()));
+
+ PartSet_WidgetPolylinePoints* that = (PartSet_WidgetPolylinePoints*) this;
+ bool isBlocked = that->blockSignals(true);
+ bool isImmutable = aPointArray->setImmutable(true);
+
+ if (myFeature->isMacro()) {
+ // Moving points of macro-features has been processed directly (without solver)
+ storePoints();
+ updateObject(myFeature);
+
+ } else {
+ if (!aPointArray->isInitialized()) {
+ storePoints();
+ }
+ std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage(
+ new ModelAPI_ObjectMovedMessage(this));
+ aMessage->setMovedAttribute(aPointArray, aPointArray->size() - 1);
+ aMessage->setOriginalPosition(aPointArray->pnt(aPointArray->size() - 1));
+ aMessage->setCurrentPosition(myXSpin.back()->value(), myYSpin.back()->value());
+ Events_Loop::loop()->send(aMessage);
+ }
+
+ aPointArray->setImmutable(isImmutable);
+ that->blockSignals(isBlocked);
+
+ return true;
+}
+
+bool PartSet_WidgetPolylinePoints::restoreValueCustom()
+{
+
+ std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+ AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(attributeID()));
+
+ if (aPointArray->isInitialized()) {
+ while ((int)myXSpin.size() < aPointArray->size())
+ createNextPoint();
+
+ std::vector<ModuleBase_LabelValue*>::iterator aXIt = myXSpin.begin();
+ std::vector<ModuleBase_LabelValue*>::iterator aYIt = myYSpin.begin();
+ for (int anIndex = 0; aXIt != myXSpin.end() && aYIt != myYSpin.end();
+ ++anIndex, ++aXIt, ++aYIt) {
+ GeomPnt2dPtr aPoint = aPointArray->pnt(anIndex);
+ (*aXIt)->setValue(aPoint->x());
+ (*aYIt)->setValue(aPoint->y());
+ }
+ }
+ else {
+ if (myXSpin.empty())
+ createNextPoint();
+
+ myXSpin.back()->setValue(0.0);
+ myYSpin.back()->setValue(0.0);
+ }
+
+ return true;
+}
+
+static void storeArray(const std::vector<ModuleBase_LabelValue*>& theLabels,
+ std::vector<double>& theValues)
+{
+ theValues.clear();
+ theValues.reserve(theLabels.size());
+ for (std::vector<ModuleBase_LabelValue*>::const_iterator anIt = theLabels.begin();
+ anIt != theLabels.end(); ++anIt)
+ theValues.push_back((*anIt)->value());
+}
+
+void PartSet_WidgetPolylinePoints::storeCurentValue()
+{
+ myValueIsCashed = true;
+ myIsFeatureVisibleInCash = XGUI_Displayer::isVisible(
+ XGUI_Tools::workshop(myWorkshop)->displayer(), myFeature);
+
+ storeArray(myXSpin, myXValueInCash);
+ storeArray(myYSpin, myYValueInCash);
+}
+
+static void restoreArray(std::vector<double>& theCacheValues,
+ std::vector<ModuleBase_LabelValue*>& theLabels)
+{
+ std::vector<double>::iterator aCIt = theCacheValues.begin();
+ std::vector<ModuleBase_LabelValue*>::iterator anIt = theLabels.begin();
+ for (; anIt != theLabels.end(); ++anIt) {
+ if (aCIt != theCacheValues.end())
+ (*anIt)->setValue(*aCIt++);
+ else
+ (*anIt)->setValue(0.0);
+ }
+ theCacheValues.clear();
+}
+
+bool PartSet_WidgetPolylinePoints::restoreCurentValue()
+{
+ bool aRestoredAndHidden = true;
+
+ bool isVisible = myIsFeatureVisibleInCash;
+
+ myValueIsCashed = false;
+ myIsFeatureVisibleInCash = true;
+ // fill the control widgets by the cashed value
+ restoreArray(myXValueInCash, myXSpin);
+ restoreArray(myYValueInCash, myYSpin);
+
+ // store value to the model
+ storeValueCustom();
+ if (isVisible) {
+ setValueState(Stored);
+ aRestoredAndHidden = false;
+ }
+ else
+ aRestoredAndHidden = true;
+
+ return aRestoredAndHidden;
+}
+
+QList<QWidget*> PartSet_WidgetPolylinePoints::getControls() const
+{
+ QList<QWidget*> aControls;
+ aControls.append(myScrollArea);
+ return aControls;
+}
+
+void PartSet_WidgetPolylinePoints::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
+{
+ theModuleSelectionModes = -1;
+ theModes << TopAbs_VERTEX;
+}
+
+void PartSet_WidgetPolylinePoints::deactivate()
+{
+ // the value of the control should be stored to model if it was not
+ // initialized yet. It is important when we leave this control by Tab key.
+ // It should not be performed by the widget activation as the preview
+ // is visualized with default value. Line point is moved to origin.
+ AttributePtr anAttribute = myFeature->data()->attribute(attributeID());
+ if (anAttribute && !anAttribute->isInitialized())
+ storeValue();
+
+ ModuleBase_ModelWidget::deactivate();
+}
+
+void PartSet_WidgetPolylinePoints::mouseReleased(ModuleBase_IViewWindow* theWindow,
+ QMouseEvent* theEvent)
+{
+ // the contex menu release by the right button should not be processed by this widget
+ if (theEvent->button() != Qt::LeftButton)
+ return;
+
+ ModuleBase_ISelection* aSelection = myWorkshop->selection();
+ Handle(V3d_View) aView = theWindow->v3dView();
+
+ QList<ModuleBase_ViewerPrsPtr> aList = aSelection->getSelected(ModuleBase_ISelection::Viewer);
+ ModuleBase_ViewerPrsPtr aFirstValue =
+ aList.size() > 0 ? aList.first() : ModuleBase_ViewerPrsPtr();
+ if (!aFirstValue.get() && myPreSelected.get()) {
+ aFirstValue = myPreSelected;
+ }
+
+ TopoDS_Shape aSelectedShape;
+ ObjectPtr aSelectedObject;
+
+ // if we have selection and use it
+ if (aFirstValue.get() && aFirstValue->shape().get()) {
+ GeomShapePtr aGeomShape = aFirstValue->shape();
+ aSelectedShape = aGeomShape->impl<TopoDS_Shape>();
+ aSelectedObject = aFirstValue->object();
+
+ FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aSelectedObject);
+ std::shared_ptr<SketchPlugin_Feature> aSPFeature;
+ if (aSelectedFeature.get())
+ aSPFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
+
+ bool isSketchExternalFeature = aSPFeature.get() && aSPFeature->isExternal();
+ if ((!aSPFeature && !aSelectedShape.IsNull()) || isSketchExternalFeature) {
+ ObjectPtr aFixedObject =
+ PartSet_Tools::findFixedObjectByExternal(aSelectedShape, aSelectedObject, mySketch);
+ if (aFixedObject)
+ aSelectedObject = aFixedObject;
+ else if (!isSketchExternalFeature) {
+ FeaturePtr aCreatedFeature;
+ aSelectedObject = PartSet_Tools::createFixedObjectByExternal(
+ aGeomShape, aSelectedObject, mySketch, false, aCreatedFeature);
+ }
+ }
+ }
+ // The selection could be a center of an external circular object
+ else if (aFirstValue.get() && (!aFirstValue->interactive().IsNull())) {
+ Handle(PartSet_CenterPrs) aAIS =
+ Handle(PartSet_CenterPrs)::DownCast(aFirstValue->interactive());
+ if (!aAIS.IsNull()) {
+ gp_Pnt aPntComp = aAIS->Component()->Pnt();
+ GeomVertexPtr aVertPtr(new GeomAPI_Vertex(aPntComp.X(), aPntComp.Y(), aPntComp.Z()));
+ aSelectedShape = aVertPtr->impl<TopoDS_Shape>();
+
+ aSelectedObject =
+ PartSet_Tools::findFixedObjectByExternal(aSelectedShape, aAIS->object(), mySketch);
+ if (!aSelectedObject.get())
+ {
+ FeaturePtr aCreatedFeature;
+ aSelectedObject = PartSet_Tools::createFixedByExternalCenter(aAIS->object(), aAIS->edge(),
+ aAIS->centerType(), mySketch, false, aCreatedFeature);
+ }
+ }
+ }
+
+ GeomPnt2dPtr aSelectedPoint = PartSet_Tools::getPnt2d(aView, aSelectedShape, mySketch);
+ if (!aSelectedPoint) {
+ aSelectedPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, mySketch);
+ setValueState(Stored); // in case of edge selection, Apply state should also be updated
+ }
+ // next pole of B-spline
+ createNextPoint();
+}
+
+void PartSet_WidgetPolylinePoints::mouseMoved(ModuleBase_IViewWindow* theWindow,
+ QMouseEvent* theEvent)
+{
+ PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+
+ if (myFinished || isEditingMode() || aModule->sketchReentranceMgr()->isInternalEditActive())
+ return;
+
+ gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
+
+ double aX = 0, aY = 0;
+ PartSet_Tools::convertTo2D(aPoint, mySketch, theWindow->v3dView(), aX, aY);
+ if (myState != ModifiedInViewer)
+ storeCurentValue();
+
+ setPoint(aX, aY);
+
+ if (IsPointCreated) {
+ QPoint aPnt = myGroupBox->geometry().bottomLeft();
+ myScrollArea->ensureVisible(aPnt.x(), aPnt.y());
+ IsPointCreated = false;
+ }
+}
+
+
+bool PartSet_WidgetPolylinePoints::processEscape()
+{
+ bool isProcessed = !isEditingMode();
+ if (isProcessed) {
+ // remove widgets corrsponding to the last pole/weight of B-spline
+ removeLastPoint();
+ myFinished = true;
+
+ emit focusOutWidget(this);
+ }
+ return isProcessed;
+}
+
+bool PartSet_WidgetPolylinePoints::useSelectedShapes() const
+{
+ return true;
+}
+
+
+
--- /dev/null
+// Copyright (C) 2019-2020 CEA/DEN, EDF R&D
+//
+// This library 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.
+//
+// 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef PartSet_WidgetPolylinePoints_H
+#define PartSet_WidgetPolylinePoints_H
+
+#include "PartSet.h"
+#include "PartSet_MouseProcessor.h"
+
+#include <ModuleBase_ModelWidget.h>
+
+#include <QObject>
+
+class GeomAPI_Pnt2d;
+class ModelAPI_CompositeFeature;
+class ModuleBase_LabelValue;
+class PartSet_ExternalObjectsMgr;
+class QGroupBox;
+class QScrollArea;
+
+/**\class PartSet_WidgetPolylinePoints
+ * \ingroup Modules
+ * \brief Implementation of model widget to provide widget to input a list of 2D points
+ * of polyline
+ * In XML can be defined as following:
+ * \code
+ * <sketch-polyline_selector id="points"/>
+ * \endcode
+ */
+class PARTSET_EXPORT PartSet_WidgetPolylinePoints : public ModuleBase_ModelWidget,
+ public PartSet_MouseProcessor
+{
+Q_OBJECT
+public:
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theWorkshop a current workshop
+ /// \param theData the widget configuation. The attribute of the model widget is obtained from
+ PartSet_WidgetPolylinePoints(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,
+ const Config_WidgetAPI* theData);
+ /// Destructor
+ virtual ~PartSet_WidgetPolylinePoints();
+
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param theModes [out] a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
+ /// Fills the attribute with the value of the selected owner
+ /// \param thePrs a selected owner
+ bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue);
+
+ /// Returns list of widget controls
+ /// \return a control list
+ virtual QList<QWidget*> getControls() const;
+
+ /// The methiod called when widget is deactivated
+ virtual void deactivate();
+
+ /// \returns the sketch instance
+ std::shared_ptr<ModelAPI_CompositeFeature> sketch() const { return mySketch; }
+
+ /// Set sketch instance
+ void setSketch(std::shared_ptr<ModelAPI_CompositeFeature> theSketch) { mySketch = theSketch; }
+
+ /// Fill the widget values by given point
+ /// \param theX the X coordinate
+ /// \param theY the Y coordinate
+ /// \returns True in case of success
+ bool setPoint(double theX, double theY);
+
+ /// Returns true if the event is processed.
+ virtual bool processEscape();
+
+ /// Returns true if the attribute can be changed using the selected shapes in the viewer
+ /// and creating a coincidence constraint to them. This control use them.
+ virtual bool useSelectedShapes() const;
+
+ /// Processing the mouse move event in the viewer
+ /// \param theWindow a view window
+ /// \param theEvent a mouse event
+ virtual void mouseMoved(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent);
+
+ /// Processing the mouse release event in the viewer
+ /// \param theWindow a view window
+ /// \param theEvent a mouse event
+ virtual void mouseReleased(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent);
+
+protected:
+ /// Saves the internal parameters to the given feature
+ /// \return True in success
+ virtual bool storeValueCustom();
+
+ /// Restore value from attribute data to the widget's control
+ virtual bool restoreValueCustom();
+
+ /// Store current value in cashed value
+ void storeCurentValue();
+
+ /// Restore cashed value in the model attribute
+ /// \return boolean state if the restored feature shoud be hidden
+ bool restoreCurentValue();
+
+private:
+ /// Create labels for the next B-spline point
+ void createNextPoint();
+ /// Remove labels for the last B-spline point
+ void removeLastPoint();
+
+ /// Save polyline points to corresponding attributes
+ void storePoints() const;
+
+protected:
+ ModuleBase_IWorkshop* myWorkshop; ///< workshop
+
+private:
+ QGroupBox* myBox;
+ QWidget* myGroupBox; ///< the parent group box for all intenal widgets
+ QScrollArea* myScrollArea;
+ std::vector<ModuleBase_LabelValue*> myXSpin; ///< the label for the X coordinate
+ std::vector<ModuleBase_LabelValue*> myYSpin; ///< the label for the Y coordinate
+
+ /// value used as selection in mouse release method
+ std::shared_ptr<ModuleBase_ViewerPrs> myPreSelected;
+
+ /// it is important during restart operation
+ CompositeFeaturePtr mySketch;
+
+ bool myValueIsCashed; /// boolean state if the value is cashed during value state change
+ bool myIsFeatureVisibleInCash; /// boolean value if the feature was visible when cash if filled
+ std::vector<double> myXValueInCash; /// the cashed X value during value state change
+ std::vector<double> myYValueInCash; /// the cashed Y value during value state change
+
+ bool myFinished; /// \c true if building the polyline is finished (escape pressed)
+};
+#endif
SketchPlugin_Feature.h
SketchPlugin_IntersectionPoint.h
SketchPlugin_Line.h
+ SketchPlugin_Polyline.h
SketchPlugin_MacroArc.h
SketchPlugin_MacroArcReentrantMessage.h
SketchPlugin_MacroBSpline.h
SketchPlugin_Feature.cpp
SketchPlugin_IntersectionPoint.cpp
SketchPlugin_Line.cpp
+ SketchPlugin_Polyline.cpp
SketchPlugin_MacroArc.cpp
SketchPlugin_MacroBSpline.cpp
SketchPlugin_MacroCircle.cpp
#include <SketchPlugin_MacroArc.h>
#include <SketchPlugin_MacroBSpline.h>
#include <SketchPlugin_MacroCircle.h>
+#include <SketchPlugin_Polyline.h>
#include <SketchPlugin_MultiRotation.h>
#include <SketchPlugin_MultiTranslation.h>
#include <SketchPlugin_Offset.h>
new SketchPlugin_MultiRotationAngleValidator);
aFactory->registerValidator("SketchPlugin_BSplineValidator",
new SketchPlugin_BSplineValidator);
+ aFactory->registerValidator("SketchPlugin_PolylineValidator",
+ new SketchPlugin_PolylineValidator);
aFactory->registerValidator("SketchPlugin_CurveFittingValidator",
new SketchPlugin_CurveFittingValidator);
return FeaturePtr(new SketchPlugin_EllipticArc);
} else if (theFeatureID == SketchPlugin_MacroEllipticArc::ID()) {
return FeaturePtr(new SketchPlugin_MacroEllipticArc);
+ } else if (theFeatureID == SketchPlugin_Polyline::ID()) {
+ return FeaturePtr(new SketchPlugin_Polyline);
} else if (theFeatureID == SketchPlugin_CurveFitting::ID()) {
return FeaturePtr(new SketchPlugin_CurveFitting);
} else if (theFeatureID == SketchPlugin_SketchDrawer::ID()) {
aMsg->setState(SketchPlugin_MacroCircle::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_MacroEllipse::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_MacroEllipticArc::ID(), aHasSketchPlane);
+ aMsg->setState(SketchPlugin_Polyline::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_ConstraintDistanceHorizontal::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_ConstraintDistanceVertical::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_CurveFitting::ID(), aHasSketchPlane);
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library 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.
+//
+// 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SketchPlugin_Polyline.h"
+
+#include "SketchPlugin_Line.h"
+#include "SketchPlugin_Sketch.h"
+
+#include "SketchPlugin_ConstraintCoincidence.h"
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Session.h>
+
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <GeomDataAPI_Point2D.h>
+#include <GeomAlgoAPI_PointBuilder.h>
+#include <GeomAlgoAPI_EdgeBuilder.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <SketchPlugin_Tools.h>
+
+#include <iostream>
+
+SketchPlugin_Polyline::SketchPlugin_Polyline()
+ : SketchPlugin_SketchEntity()
+{}
+
+void SketchPlugin_Polyline::initAttributes()
+{
+ SketchPlugin_SketchEntity::initAttributes();
+}
+
+void SketchPlugin_Polyline::initDerivedClassAttributes()
+{
+
+ data()->addAttribute(POINTS_ID(), GeomDataAPI_Point2DArray::typeId());
+
+}
+
+void SketchPlugin_Polyline::execute()
+{
+ createLineFeature();
+}
+
+void SketchPlugin_Polyline::createLineFeature()
+{
+ AttributePoint2DArrayPtr aPointsArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POINTS_ID()));
+
+ getAISObject(AISObjectPtr());
+
+ if (aPointsArray->isInitialized())
+ {
+ FeaturePtr aLastline;
+ FeaturePtr aFirstline;
+ // collect points
+ for (int anIndex = 1; anIndex < aPointsArray->size(); ++anIndex) {
+
+ FeaturePtr aLine = sketch()->addFeature(SketchPlugin_Line::ID());
+ if (anIndex ==1) {
+ aFirstline = aLine;
+ }
+ std::shared_ptr<GeomDataAPI_Point2D> aStartA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::START_ID()));
+
+ aStartA->setValue(aPointsArray->pnt(anIndex-1));
+
+ std::shared_ptr<GeomDataAPI_Point2D> aEndA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::END_ID()));
+
+ aEndA->setValue(aPointsArray->pnt(anIndex));
+
+ aLine->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(
+ boolean(AUXILIARY_ID())->value());
+
+ if (aLastline) {
+ // Initialize new line with first point equal to end of previous
+ std::shared_ptr<ModelAPI_Data> aSFData = aLastline->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aSPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aSFData->attribute(SketchPlugin_Line::END_ID()));
+ std::shared_ptr<ModelAPI_Data> aNFData = aLine->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aNPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aNFData->attribute(SketchPlugin_Line::START_ID()));
+ aNPoint->setValue(aSPoint->x(), aSPoint->y());
+ SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(sketch(), aSPoint, aNPoint);
+ }
+
+ aLine->execute();
+ aLastline = aLine;
+ }
+ // Initialize new line with first point equal to end of previous
+ std::shared_ptr<ModelAPI_Data> aSFData = aLastline->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aSPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aSFData->attribute(SketchPlugin_Line::END_ID()));
+ std::shared_ptr<ModelAPI_Data> aNFData = aFirstline->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aNPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aNFData->attribute(SketchPlugin_Line::START_ID()));
+
+ double aDistance = aSPoint->pnt()->distance(aNPoint->pnt());
+ if (aDistance < 1) {
+ aNPoint->setValue(aSPoint->x(), aSPoint->y());
+ SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(sketch(), aSPoint, aNPoint);
+ }
+ }
+}
+
+const std::string& SketchPlugin_Polyline::getKind()
+{
+ static std::string MY_KIND = SketchPlugin_Polyline::ID();
+ return MY_KIND;
+}
+
+void SketchPlugin_Polyline::attributeChanged(const std::string& theID) {
+}
+
+AISObjectPtr SketchPlugin_Polyline::getAISObject(AISObjectPtr thePrevious)
+{
+
+ SketchPlugin_Sketch* aSketch = sketch();
+ if (!aSketch)
+ return AISObjectPtr();
+
+ AttributePoint2DArrayPtr aPointsArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POINTS_ID()));
+
+ if (aPointsArray->size() < 2)
+ return AISObjectPtr();
+
+ std::list<GeomShapePtr> aShapes;
+
+ // convert points to vertices
+ std::list<GeomPointPtr> aPoles3D;
+ for (int anIndex = 0; anIndex < aPointsArray->size()-1; ++anIndex) {
+
+ GeomPnt2dPtr aPoint1 = aPointsArray->pnt(anIndex);
+ GeomPnt2dPtr aPoint2 = aPointsArray->pnt(anIndex + 1);
+ GeomPointPtr aPole3D1 = aSketch->to3D(aPoint1->x(), aPoint1->y());
+ GeomPointPtr aPole3D2 = aSketch->to3D(aPoint2->x(), aPoint2->y());
+ aShapes.push_back(GeomAlgoAPI_PointBuilder::vertex(aPole3D1));
+
+ GeomShapePtr anEdge =
+ GeomAlgoAPI_EdgeBuilder::line(aPole3D1, aPole3D2);
+ if (anEdge)
+ aShapes.push_back(anEdge);
+
+ }
+
+ GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS)
+ anAIS.reset(new GeomAPI_AISObject());
+ anAIS->createShape(aCompound);
+
+ // Modify attributes
+ SketchPlugin_Tools::customizeFeaturePrs(anAIS, boolean(AUXILIARY_ID())->value());
+
+ return anAIS;
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library 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.
+//
+// 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SketchPlugin_Polyline_H_
+#define SketchPlugin_Polyline_H_
+
+#include <ModelAPI_IReentrant.h>
+
+#include "SketchPlugin.h"
+#include <SketchPlugin_SketchEntity.h>
+#include <SketchPlugin_Sketch.h>
+#include <list>
+
+#include <GeomAPI_IPresentable.h>
+
+class GeomAPI_Pnt2d;
+
+/**\class SketchPlugin_Polyline
+ * \ingroup Plugins
+ * \brief Feature for creation of polyline in PartSet.
+ */
+class SketchPlugin_Polyline : public SketchPlugin_SketchEntity,
+ public GeomAPI_IPresentable
+{
+ public:
+ /// Arc feature kind
+ inline static const std::string& ID()
+ {
+ static const std::string SKETCH_LINE_ID("SketchPolyline");
+ return SKETCH_LINE_ID;
+ }
+
+ /// list of polyline points
+ inline static const std::string& POINTS_ID()
+ {
+ static const std::string ID("points");
+ return ID;
+ }
+
+ /// Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind();
+
+ /// Request for initialization of data model of the feature: adding all attributes
+ virtual void initAttributes();
+
+ /// Creates a new part document if needed
+ SKETCHPLUGIN_EXPORT virtual void execute();
+
+ /// Reimplemented from ModelAPI_Feature::isMacro().
+ /// \returns true
+ SKETCHPLUGIN_EXPORT virtual bool isMacro() const {return true;};
+
+ SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
+
+ /// Called on change of any argument-attribute of this object
+ SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+ /// Returns the AIS preview
+ virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
+
+ /// Use plugin manager for features creation
+ SketchPlugin_Polyline();
+
+private:
+
+ void createLineFeature();
+
+protected:
+ /// \brief Initializes attributes of derived class.
+ virtual void initDerivedClassAttributes();
+};
+
+#endif
return true;
}
+bool SketchPlugin_PolylineValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributePoint2DArrayPtr aPolesArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(theAttribute);
+ if (!aPolesArray)
+ return false;
+
+ return true;
+}
+
bool SketchPlugin_CurveFittingValidator::isValid(const FeaturePtr& theFeature,
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
Events_InfoMessage& theError) const;
};
+/**\class SketchPlugin_PolylineValidator
+ * \ingroup Validators
+ * \brief Validator for checking points of polyline.
+ */
+class SketchPlugin_PolylineValidator : public ModelAPI_AttributeValidator
+{
+ //! returns true if attribute is valid
+ //! \param theAttribute the checked attribute
+ //! \param theArguments arguments of the attribute
+ //! \param theError error message
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
/**\class SketchPlugin_CurveFittingValidator
* \ingroup Validators
* \brief Validator for the selected vertices for the curve fitting feature.
<group id="Linear geometry">
<feature
id="Sketch"
- nested="SketchPoint SketchIntersectionPoint SketchLine
+ nested="SketchPoint SketchIntersectionPoint SketchLine SketchPolyline
SketchCircle SketchMacroCircle SketchArc SketchMacroArc
SketchEllipse SketchMacroEllipse SketchEllipticArc SketchMacroEllipticArc
SketchBSpline SketchMacroBSpline SketchMacroBSplinePeriodic SketchBSplinePeriodic
<boolvalue id="Auxiliary" label="Auxiliary" default="false" tooltip="Construction element" obligatory="0" change_visual_attributes="true"/>
<validator id="GeomValidators_Different" parameters="StartPoint,EndPoint"/>
</feature>
+ <!-- SketchPolyline -->
+ <feature id="SketchPolyline" title="Polyline" tooltip="Create polyline" icon="icons/Sketch/polyline.png"
+ helpfile="lineFeature.html">
+ <sketch-polyline_selector id="points"
+ title="Points"
+ tooltip="Polyline points"
+ enable_value="enable_by_preferences">
+ <validator id="SketchPlugin_PolylineValidator"/>
+ </sketch-polyline_selector>
+ <boolvalue id="Auxiliary" label="Auxiliary" default="false" tooltip="Construction element" obligatory="0" change_visual_attributes="true"/>
+ </feature>
</group>
<group id="Conical geometry">
<!-- SketchCircle is a hidden feature. It is created inside SketchMacroCircle. -->