Movement of B-spline curve.
QWidget* ModuleBase_IWidgetCreator::createPanelByType(const std::string& theType,
QWidget* theParent,
- const FeaturePtr& theFeature)
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* theWidgetApi)
{
return 0;
}
/// \param theType a panel type
/// \param theParent a parent widget
/// \param theFeature a feature modified in the panel
+ /// \param theWidgetApi a low-level API for reading xml definitions of widget
/// \return created widget or null
virtual QWidget* createPanelByType(const std::string& theType,
QWidget* theParent,
- const FeaturePtr& theFeature);
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* theWidgetApi = 0);
/// Create page by its type
/// The default implementation is empty
/// \param theFeature a feature object
/// \param theToStoreValue a value about necessity to store the widget value to the feature
/// \param isUpdateFlushed a flag if update should be flushed on store value
- void setFeature(const FeaturePtr& theFeature, const bool theToStoreValue = false,
- const bool isUpdateFlushed = true);
+ virtual void setFeature(const FeaturePtr& theFeature, const bool theToStoreValue = false,
+ const bool isUpdateFlushed = true);
/// Editing mode depends on mode of current operation. This value is defined by it.
virtual void setEditingMode(bool isEditing) { myIsEditing = isEditing; }
QWidget* ModuleBase_WidgetCreatorFactory::createPanelByType(const std::string& theType,
QWidget* theParent,
- const FeaturePtr& theFeature)
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* myWidgetApi)
{
QWidget* aPanel = 0;
if (myPanelToCreator.contains(theType)) {
WidgetCreatorPtr aCreator = myPanelToCreator[theType];
- aPanel = aCreator->createPanelByType(theType, theParent, theFeature);
+ aPanel = aCreator->createPanelByType(theType, theParent, theFeature, myWidgetApi);
}
return aPanel;
}
/// \param theType a type
/// \param theParent a parent widget
/// \param theFeature a feature to fill the panel
+ /// \param theWidgetApi the widget configuration.
+ /// The attribute of the model widget is obtained from XML
/// \return a created panel or null
QWidget* createPanelByType(const std::string& theType, QWidget* theParent,
- const FeaturePtr& theFeature);
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* theWidgetApi = 0);
/// Returns true if there is a creator, which can make a page by the type
/// \param theType a type
std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName)) {
QWidget* aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanelByType(aPanelName,
- thePage->pageWidget(), theFeature);
- thePage->addWidget(aPanel);
+ thePage->pageWidget(), theFeature, myWidgetApi);
+ ModuleBase_ModelWidget* aModelWdg = dynamic_cast<ModuleBase_ModelWidget*>(aPanel);
+ if (aModelWdg)
+ thePage->addModelWidget(aModelWdg);
+ else
+ thePage->addWidget(aPanel);
thePage->alignToTop();
}
}
SketchPlugin.h
SketchPlugin_Arc.h
SketchPlugin_BSpline.h
+ SketchPlugin_BSplineWidget.h
SketchPlugin_Circle.h
SketchPlugin_Constraint.h
SketchPlugin_ConstraintAngle.h
SketchPlugin_Point.h
SketchPlugin_Projection.h
SketchPlugin_Sketch.h
+ SketchPlugin_SketchDrawer.h
SketchPlugin_SketchEntity.h
SketchPlugin_Split.h
SketchPlugin_Tools.h
SketchPlugin_Trim.h
SketchPlugin_Validators.h
- SketchPlugin_SketchDrawer.h
+ SketchPlugin_WidgetCreator.h
+)
+
+SET(PROJECT_MOC_HEADERS
+ SketchPlugin_BSplineWidget.h
)
SET(PROJECT_SOURCES
SketchPlugin_Arc.cpp
SketchPlugin_BSpline.cpp
+ SketchPlugin_BSplineWidget.cpp
SketchPlugin_Circle.cpp
SketchPlugin_Constraint.cpp
SketchPlugin_ConstraintAngle.cpp
SketchPlugin_Point.cpp
SketchPlugin_Projection.cpp
SketchPlugin_Sketch.cpp
+ SketchPlugin_SketchDrawer.cpp
SketchPlugin_SketchEntity.cpp
SketchPlugin_Split.cpp
SketchPlugin_Tools.cpp
SketchPlugin_Trim.cpp
SketchPlugin_Validators.cpp
- SketchPlugin_SketchDrawer.cpp
+ SketchPlugin_WidgetCreator.cpp
)
SET(PROJECT_LIBRARIES
GeomAlgoAPI
ModelAPI
ModelGeomAlgo
+ ModuleBase
SketcherPrs
GeomDataAPI
)
)
SET(TEXT_RESOURCES
- SketchPlugin_msg_en.ts
- SketchPlugin_msg_fr.ts
+ SketchPlugin_msg_en.ts
+ SketchPlugin_msg_fr.ts
)
+# sources / moc wrappings
+QT_WRAP_MOC(PROJECT_AUTOMOC ${PROJECT_MOC_HEADERS})
+
+SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC})
SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES})
ADD_DEFINITIONS(-DSKETCHPLUGIN_EXPORTS)
-ADD_LIBRARY(SketchPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES})
+ADD_LIBRARY(SketchPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES} ${PROJECT_AUTOMOC})
TARGET_LINK_LIBRARIES(SketchPlugin ${PROJECT_LIBRARIES})
INCLUDE_DIRECTORIES(
../Events
../ModelAPI
../ModelGeomAlgo
+ ../ModuleBase
../GeomAPI
../GeomAlgoAPI
../GeomDataAPI
../SketcherPrs
+ ${OpenCASCADE_INCLUDE_DIR}
)
INSTALL(TARGETS SketchPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES})
#include <GeomAPI_Pnt2d.h>
+#include <GeomDataAPI_Point2D.h>
#include <GeomDataAPI_Point2DArray.h>
#include <ModelAPI_AttributeDoubleArray.h>
void SketchPlugin_BSpline::initDerivedClassAttributes()
{
+ data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
+
data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
data()->addAttribute(WEIGHTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
data()->addAttribute(KNOTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
return ID;
}
+ /// start point of B-spline curve
+ inline static const std::string& START_ID()
+ {
+ static const std::string ID("start_point");
+ return ID;
+ }
+ /// end point of B-spline curve
+ inline static const std::string& END_ID()
+ {
+ static const std::string ID("end_point");
+ return ID;
+ }
+
/// Returns the kind of a feature
SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
{
--- /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 <SketchPlugin_BSplineWidget.h>
+
+#include <SketchPlugin_BSpline.h>
+
+#include <ModuleBase_Tools.h>
+
+#include <ModelAPI_AttributeDoubleArray.h>
+
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <GeomAPI_Pnt2d.h>
+
+#include <QFormLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QVBoxLayout>
+
+
+SketchPlugin_BSplineWidget::SketchPlugin_BSplineWidget(
+ QWidget* theParent,
+ const Config_WidgetAPI* theData)
+ : ModuleBase_ModelWidget(theParent, theData)
+{
+ QVBoxLayout* aMainLayout = new QVBoxLayout(this);
+
+ // GroupBox to keep widgets for B-spline poles and weights
+ myPolesGroupBox = new QGroupBox(tr("Poles and weights"), theParent);
+ aMainLayout->addWidget(myPolesGroupBox);
+ // layout of GroupBox
+ QGridLayout* aGroupLayout = new QGridLayout(myPolesGroupBox);
+ aGroupLayout->setSpacing(4);
+ aGroupLayout->setColumnStretch(1, 1);
+
+ restoreValueCustom();
+}
+
+void SketchPlugin_BSplineWidget::setFeature(const FeaturePtr& theFeature,
+ const bool theToStoreValue,
+ const bool isUpdateFlushed)
+{
+ ModuleBase_ModelWidget::setFeature(theFeature, theToStoreValue, isUpdateFlushed);
+ restoreValueCustom();
+}
+
+void SketchPlugin_BSplineWidget::deactivate()
+{
+ ModuleBase_ModelWidget::deactivate();
+ storeValueCustom();
+}
+
+
+QList<QWidget*> SketchPlugin_BSplineWidget::getControls() const
+{
+ QList<QWidget*> aControls;
+ std::list<BSplinePoleWidgets>::const_iterator anIt = myPoles.begin();
+ for (; anIt != myPoles.end(); ++anIt) {
+ aControls.append(anIt->myX);
+ aControls.append(anIt->myY);
+ aControls.append(anIt->myWeight);
+ }
+ return aControls;
+}
+
+void SketchPlugin_BSplineWidget::storePolesAndWeights() const
+{
+ std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+ AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(SketchPlugin_BSpline::POLES_ID()));
+ AttributeDoubleArrayPtr aWeightsArray = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
+
+ aPointArray->setSize((int)myPoles.size());
+ aWeightsArray->setSize((int)myPoles.size());
+
+ std::list<BSplinePoleWidgets>::const_iterator anIt = myPoles.begin();
+ for (int anIndex = 0; anIt != myPoles.end(); ++anIndex, ++anIt) {
+ aPointArray->setPnt(anIndex, anIt->myX->value(), anIt->myY->value());
+ aWeightsArray->setValue(anIndex, anIt->myWeight->value());
+ }
+}
+
+bool SketchPlugin_BSplineWidget::storeValueCustom()
+{
+ std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
+ if (!aData || !aData->isValid()) // can be on abort of sketcher element
+ return false;
+
+ AttributePoint2DArrayPtr aPoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(SketchPlugin_BSpline::POLES_ID()));
+ AttributeDoubleArrayPtr aWeights = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
+
+ bool isBlocked = blockSignals(true);
+ bool isImmutable = aPoles->setImmutable(true);
+
+ storePolesAndWeights();
+ ModuleBase_Tools::flushUpdated(myFeature);
+
+ aPoles->setImmutable(isImmutable);
+ blockSignals(isBlocked);
+
+ return true;
+}
+
+bool SketchPlugin_BSplineWidget::restoreValueCustom()
+{
+ if (!myFeature)
+ return false;
+
+ DataPtr aData = myFeature->data();
+
+ AttributePoint2DArrayPtr aPoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aData->attribute(SketchPlugin_BSpline::POLES_ID()));
+ AttributeDoubleArrayPtr aWeights = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
+
+ while (myPoles.size() < aPoles->size())
+ addPoleWidget();
+
+ std::list<BSplinePoleWidgets>::iterator anIt = myPoles.begin();
+ for (int anIndex = 0; anIt != myPoles.end(); ++anIt, ++anIndex) {
+ GeomPnt2dPtr aPoint = aPoles->pnt(anIndex);
+ anIt->myX->setValue(aPoint->x());
+ anIt->myY->setValue(aPoint->y());
+ anIt->myWeight->setValue(aWeights->value(anIndex));
+ }
+
+ return true;
+}
+
+void SketchPlugin_BSplineWidget::addPoleWidget()
+{
+ QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myPolesGroupBox->layout());
+
+ int aNbPoles = (int)myPoles.size();
+
+ QString aPoleStr = tr("Pole %1");
+ aPoleStr = aPoleStr.arg(aNbPoles + 1);
+
+ QGroupBox* aPoleGroupBox = new QGroupBox(aPoleStr, myPolesGroupBox);
+ QFormLayout* aPoleLay = new QFormLayout(aPoleGroupBox);
+ ModuleBase_Tools::adjustMargins(aPoleLay);
+ aPoleLay->setSpacing(2);
+
+ myPoles.push_back(BSplinePoleWidgets());
+ BSplinePoleWidgets& aPoleWidgets = myPoles.back();
+
+ aPoleWidgets.myX = new ModuleBase_LabelValue(aPoleGroupBox, tr("X"));
+ aPoleLay->addRow(aPoleWidgets.myX);
+ aPoleWidgets.myY = new ModuleBase_LabelValue(aPoleGroupBox, tr("Y"));
+ aPoleLay->addRow(aPoleWidgets.myY);
+ aPoleWidgets.myWeight = new ModuleBase_ParamSpinBox(aPoleGroupBox);
+ aPoleWidgets.myWeight->setMinimum(0.0);
+ aPoleLay->addRow(tr("Weight") + " : ", aPoleWidgets.myWeight);
+
+ aGroupLay->addWidget(aPoleGroupBox, aNbPoles, 1);
+
+ // we should listen textChanged signal as valueChanged do not send when text is modified
+ connect(aPoleWidgets.myWeight, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(valuesModified()));
+}
--- /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 SketchPlugin_BSplineWidget_H
+#define SketchPlugin_BSplineWidget_H
+
+
+#include <SketchPlugin.h>
+
+#include <ModelAPI_Feature.h>
+
+#include <ModuleBase_LabelValue.h>
+#include <ModuleBase_ModelWidget.h>
+#include <ModuleBase_ParamSpinBox.h>
+
+class QGroupBox;
+
+
+/** \brief Represent a content of the property panel to show/modify parameters of B-spline curve.
+ * \ingroup GUI
+ */
+class SketchPlugin_BSplineWidget : public ModuleBase_ModelWidget
+{
+Q_OBJECT
+public:
+ /// Constructor
+ /// \param theParent the parent object
+ /// \param theData the widget configuation. The attribute of the model widget is obtained from
+ SketchPlugin_BSplineWidget(QWidget* theParent,
+ const Config_WidgetAPI* theData);
+
+ virtual ~SketchPlugin_BSplineWidget() {}
+
+ /// The methiod called when widget is deactivated
+ virtual void deactivate();
+
+ /// Returns list of widget controls
+ /// \return a control list
+ virtual QList<QWidget*> getControls() const;
+
+ /// Set feature which is processing by active operation
+ /// \param theFeature a feature object
+ /// \param theToStoreValue a value about necessity to store the widget value to the feature
+ /// \param isUpdateFlushed a flag if update should be flushed on store value
+ virtual void setFeature(const FeaturePtr& theFeature, const bool theToStoreValue = false,
+ const bool isUpdateFlushed = true);
+
+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();
+
+ /// Create group of widgets related to coordinates of pole and its weight
+ void addPoleWidget();
+
+ /// Update attributes of B-spline feature
+ void storePolesAndWeights() const;
+
+private:
+ struct BSplinePoleWidgets {
+ ModuleBase_LabelValue* myX;
+ ModuleBase_LabelValue* myY;
+ ModuleBase_ParamSpinBox* myWeight;
+ };
+
+ QGroupBox* myPolesGroupBox; ///< widget to show poles and weights of B-spline curve
+ std::list<BSplinePoleWidgets> myPoles; ///< list of B-spline poles and their weights
+};
+
+#endif
\ No newline at end of file
data()->addAttribute(REF_POLES_ID(), ModelAPI_AttributeRefAttrList::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), REF_POLES_ID());
+ data()->addAttribute(CONTROL_POLYGON_ID(), ModelAPI_AttributeBoolean::typeId());
+
data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
}
{
FeaturePtr aBSpline = createBSplineFeature();
- std::list<FeaturePtr> aControlPoles;
- createControlPolygon(aBSpline, aControlPoles);
- constraintsForPoles(aControlPoles);
-
- // message to init reentrant operation
- static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
- ReentrantMessagePtr aMessage(new ModelAPI_EventReentrantMessage(anId, this));
- // set here the last pole to make coincidence with the start point of the next B-spline curve
- aMessage->setCreatedFeature(aControlPoles.back());
- Events_Loop::loop()->send(aMessage);
+ if (boolean(CONTROL_POLYGON_ID())->value()) {
+ std::list<FeaturePtr> aControlPoles;
+ createControlPolygon(aBSpline, aControlPoles);
+ constraintsForPoles(aControlPoles);
+
+ // message to init reentrant operation
+ static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
+ ReentrantMessagePtr aMessage(new ModelAPI_EventReentrantMessage(anId, this));
+ // set here the last pole to make coincidence with the start point of the next B-spline curve
+ aMessage->setCreatedFeature(aControlPoles.back());
+ Events_Loop::loop()->send(aMessage);
+ }
}
// LCOV_EXCL_START
for (int index = 0; index < aSize; ++index, ++aMIt)
aMults->setValue(index, *aMIt);
+ SketchPlugin_Sketch* aSketch =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
+
+ AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
+ aStartPoint->setValue(aPoles->pnt(0));
+ // internal constraint to keep position of the point
+ createInternalConstraint(aSketch, aStartPoint, aPoles, 0);
+
+ AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
+ aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
+ // internal constraint to keep position of the point
+ createInternalConstraint(aSketch, aEndPoint, aPoles, aPoles->size() - 1);
+
aBSpline->boolean(SketchPlugin_BSpline::AUXILIARY_ID())->setValue(
boolean(AUXILIARY_ID())->value());
return ID;
}
+ /// flag attribute whether control polygon is need to be created
+ inline static const std::string& CONTROL_POLYGON_ID()
+ {
+ static const std::string ID("need_control_poly");
+ return ID;
+ }
+
/// Returns the kind of a feature
SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
{
#include <SketchPlugin_EllipticArc.h>
#include <SketchPlugin_MacroEllipticArc.h>
#include <SketchPlugin_SketchDrawer.h>
+#include <SketchPlugin_WidgetCreator.h>
#include <SketcherPrs_Tools.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_Data.h>
+#include <ModuleBase_WidgetCreatorFactory.h>
+
#include <Config_PropManager.h>
#include <memory>
SketchPlugin_Plugin::SketchPlugin_Plugin()
{
+ WidgetCreatorFactoryPtr aWidgetCreatorFactory = ModuleBase_WidgetCreatorFactory::get();
+ aWidgetCreatorFactory->registerCreator(
+ std::shared_ptr<SketchPlugin_WidgetCreator>(new SketchPlugin_WidgetCreator()));
+
SessionPtr aMgr = ModelAPI_Session::get();
ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
aFactory->registerValidator("SketchPlugin_DistanceAttr",
--- /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 <SketchPlugin_WidgetCreator.h>
+#include <SketchPlugin_BSplineWidget.h>
+
+
+SketchPlugin_WidgetCreator::SketchPlugin_WidgetCreator()
+ : ModuleBase_IWidgetCreator()
+{
+ myPanelTypes.insert("bspline-panel");
+}
+
+void SketchPlugin_WidgetCreator::panelTypes(std::set<std::string>& theTypes)
+{
+ theTypes = myPanelTypes;
+}
+
+QWidget* SketchPlugin_WidgetCreator::createPanelByType(
+ const std::string& theType,
+ QWidget* theParent,
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* theWidgetApi)
+{
+ QWidget* aWidget = 0;
+ if (theType == "bspline-panel") {
+ SketchPlugin_BSplineWidget* aPanel = new SketchPlugin_BSplineWidget(theParent, theWidgetApi);
+ aPanel->setFeature(theFeature);
+ aWidget = aPanel;
+ }
+ return aWidget;
+}
--- /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 SketchPlugin_WidgetCreator_H
+#define SketchPlugin_WidgetCreator_H
+
+
+#include <SketchPlugin.h>
+#include <ModuleBase_IWidgetCreator.h>
+
+#include <string>
+#include <set>
+
+class QWidget;
+
+/**
+ * \ingroup GUI
+ * Interface to WidgetCreator which can create specific widgets by type
+ */
+class SketchPlugin_WidgetCreator : public ModuleBase_IWidgetCreator
+{
+public:
+ /// Default constructor
+ SketchPlugin_WidgetCreator();
+
+ /// Virtual destructor
+ virtual ~SketchPlugin_WidgetCreator() {}
+
+ /// Returns a container of possible page types, which this creator can process
+ /// \param theTypes a list of type names
+ virtual void panelTypes(std::set<std::string>& theTypes);
+
+ /// Create panel control by its type.
+ /// The default implementation is empty
+ /// \param theType a panel type
+ /// \param theParent a parent widget
+ /// \param theFeature a feature modified in the panel
+ /// \return created widget or null
+ virtual QWidget* createPanelByType(const std::string& theType,
+ QWidget* theParent,
+ const FeaturePtr& theFeature,
+ Config_WidgetAPI* theWidgetApi);
+private:
+ std::set<std::string> myPanelTypes; ///< types of panels
+};
+
+#endif
\ No newline at end of file
<feature id="SketchBSpline"
title="B-spline"
tooltip="Create B-spline curve"
+ property_panel_id="bspline-panel"
icon="icons/Sketch/bspline.png"
helpfile="bsplineFeature.html"
internal="1">
- <sketch-bspline_selector id="poles"
- weights="weights"
- title="Poles and weights"
- tooltip="B-spline poles and weights"
- enable_value="enable_by_preferences">
+ <sketch-2dpoint_selector id="start_point" accept_expressions="0" title="Start point" tooltip="Start point coordinates"
+ enable_value="enable_by_preferences"/>
+ <sketch-2dpoint_selector id="end_point" accept_expressions="0" title="End point" tooltip="End point coordinates"
+ enable_value="enable_by_preferences"/>
+ <bspline-panel id="poles"
+ weights="weights"
+ title="Poles and weights"
+ tooltip="B-spline poles and weights"
+ enable_value="enable_by_preferences">
<validator id="SketchPlugin_BSplineValidator"/>
- </sketch-bspline_selector>
+ </bspline-panel>
<boolvalue id="Auxiliary"
label="Auxiliary"
default="false"
enable_value="enable_by_preferences">
<validator id="SketchPlugin_BSplineValidator"/>
</sketch-bspline_selector>
+ <boolvalue id="need_control_poly"
+ label="Create control polygon"
+ default="true"
+ tooltip="Specify if the control polygon should be created"/>
<boolvalue id="Auxiliary"
label="Auxiliary"
default="false"
#include <PlaneGCSSolver_ScalarWrapper.h>
#include <PlaneGCSSolver_ScalarArrayWrapper.h>
#include <PlaneGCSSolver_BooleanWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomDataAPI_Point2D.h>
static EntityWrapperPtr createScalarArray(const AttributePtr& theAttribute,
PlaneGCSSolver_Storage* theStorage)
{
- class ArrayAttribute {
- public:
- ArrayAttribute(AttributePtr theAttribute)
- {
- myDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttribute);
- myInteger = std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttribute);
- }
-
- bool isInitialized() const
- {
- return (myDouble && myDouble->isInitialized()) || (myInteger && myInteger->isInitialized());
- }
-
- int size() const
- {
- return myDouble.get() ? myDouble->size() : myInteger->size();
- }
-
- double value(const int theIndex) const
- {
- return myDouble.get() ? myDouble->value(theIndex) : myInteger->value(theIndex);
- }
-
- private:
- AttributeDoubleArrayPtr myDouble;
- AttributeIntArrayPtr myInteger;
- } anArray(theAttribute);
+ PlaneGCSSolver_Tools::AttributeArray anArray(theAttribute);
if (!anArray.isInitialized())
return EntityWrapperPtr();
aResult->setExternal(true);
return aResult;
}
+
+bool PlaneGCSSolver_AttributeBuilder::updateAttribute(
+ AttributePtr theAttribute,
+ EntityWrapperPtr theEntity)
+{
+ bool isUpdated = false;
+ GCS::SET_pD aParamsToRemove;
+ // rebuild array if its size is changed
+ if (theEntity->type() == ENTITY_POINT_ARRAY) {
+ std::shared_ptr<PlaneGCSSolver_PointArrayWrapper> aWrapper =
+ std::dynamic_pointer_cast<PlaneGCSSolver_PointArrayWrapper>(theEntity);
+ std::shared_ptr<GeomDataAPI_Point2DArray> anAttribute =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(theAttribute);
+
+ if (aWrapper->size() != anAttribute->size()) {
+ std::vector<PointWrapperPtr> aPointsArray = aWrapper->array();
+ while (anAttribute->size() > (int)aPointsArray.size()) {
+ // add points to the middle of array
+ aPointsArray.insert(--aPointsArray.end(), createPoint(GeomPnt2dPtr(), myStorage));
+ }
+
+ while (anAttribute->size() < (int)aPointsArray.size()) {
+ // remove middle points
+ std::vector<PointWrapperPtr>::iterator anIt = --aPointsArray.end();
+ GCS::SET_pD aParams = PlaneGCSSolver_Tools::parameters(*anIt);
+ aParamsToRemove.insert(aParams.begin(), aParams.end());
+ aPointsArray.erase(anIt);
+ }
+
+ aWrapper->setArray(aPointsArray);
+ }
+ }
+ else if (theEntity->type() == ENTITY_SCALAR_ARRAY) {
+ std::shared_ptr<PlaneGCSSolver_ScalarArrayWrapper> aWrapper =
+ std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(theEntity);
+ if (aWrapper->size() != PlaneGCSSolver_Tools::AttributeArray(theAttribute).size()) {
+ aParamsToRemove = PlaneGCSSolver_Tools::parameters(aWrapper);
+ std::shared_ptr<PlaneGCSSolver_ScalarArrayWrapper> aNewArray =
+ std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(
+ createAttribute(theAttribute));
+ aWrapper->setArray(aNewArray->array());
+ isUpdated = true;
+ }
+ }
+
+ if (!aParamsToRemove.empty()) {
+ if (myStorage)
+ myStorage->removeParameters(aParamsToRemove);
+ else {
+ std::for_each(aParamsToRemove.begin(), aParamsToRemove.end(),
+ [](double* theParam) { delete theParam; });
+ }
+ }
+
+ return isUpdated || theEntity->update(theAttribute);
+}
/// \return Created wrapper of the attribute applicable for specific solver
virtual EntityWrapperPtr createAttribute(AttributePtr theAttribute);
+ /// \brief Update entity by the attribute values.
+ /// \return \c true if any value is updated.
+ virtual bool updateAttribute(AttributePtr theAttribute, EntityWrapperPtr theEntity);
+
/// \brief Blank. To be defined in derived class.
virtual EntityWrapperPtr createFeature(FeaturePtr)
{ return EntityWrapperPtr(); }
#include <PlaneGCSSolver_BooleanWrapper.h>
+#include <ModelAPI_AttributeBoolean.h>
+
PlaneGCSSolver_BooleanWrapper::PlaneGCSSolver_BooleanWrapper(bool theParam)
: myValue(theParam)
{
}
+
+bool PlaneGCSSolver_BooleanWrapper::update(AttributePtr theAttribute)
+{
+ bool isUpdated = false;
+ AttributeBooleanPtr aBoolean =
+ std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttribute);
+ if (aBoolean) {
+ isUpdated = value() != aBoolean->value();
+ setValue(aBoolean->value());
+ }
+ return isUpdated;
+}
virtual SketchSolver_EntityType type() const
{ return ENTITY_BOOLEAN; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute);
+
protected:
bool myValue;
};
#include <PlaneGCSSolver_Defs.h>
#include <PlaneGCSSolver_ScalarWrapper.h>
+#include <list>
+
/**
* Wrapper providing operations with PlaneGCS constraints.
*/
#include <PlaneGCSSolver_Defs.h>
-#include <ModelAPI_Attribute.h>
-#include <ModelAPI_Feature.h>
-
-#include <list>
+#include <map>
#include <memory>
+class ModelAPI_Attribute;
+
class PlaneGCSSolver_EntityWrapper;
typedef std::shared_ptr<PlaneGCSSolver_EntityWrapper> EntityWrapperPtr;
const std::map<std::string, EntityWrapperPtr>& additionalAttributes() const
{ return myAdditionalAttributes; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute)
+ { return false; }
+
+ friend class PlaneGCSSolver_AttributeBuilder;
+
private:
bool myExternal;
std::map<std::string, EntityWrapperPtr> myAdditionalAttributes;
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_XY.h>
-static bool isAttributeApplicable(const std::string& theAttrName,
- const std::string& theOwnerName);
static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
{
FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
EntityWrapperPtr anAttr;
- if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
+ if (PlaneGCSSolver_Tools::isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
if (anAttr)
myAttributes[theAttribute] = anAttr;
return EdgeWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewSpline));
}
-
-bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
-{
- if (theOwnerName == SketchPlugin_Arc::ID()) {
- return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
- theAttrName == SketchPlugin_Arc::START_ID() ||
- theAttrName == SketchPlugin_Arc::END_ID() ||
- theAttrName == SketchPlugin_Arc::REVERSED_ID();
- }
- else if (theOwnerName == SketchPlugin_Circle::ID()) {
- return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
- theAttrName == SketchPlugin_Circle::RADIUS_ID();
- }
- else if (theOwnerName == SketchPlugin_Line::ID()) {
- return theAttrName == SketchPlugin_Line::START_ID() ||
- theAttrName == SketchPlugin_Line::END_ID();
- }
- else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
- return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
- theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
- theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
- theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
- theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
- theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
- theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
- theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
- theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
- }
- else if (theOwnerName == SketchPlugin_EllipticArc::ID()) {
- return theAttrName == SketchPlugin_EllipticArc::CENTER_ID() ||
- theAttrName == SketchPlugin_EllipticArc::FIRST_FOCUS_ID() ||
- theAttrName == SketchPlugin_EllipticArc::SECOND_FOCUS_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_START_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_END_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MAJOR_RADIUS_ID() ||
- theAttrName == SketchPlugin_EllipticArc::MINOR_RADIUS_ID() ||
- theAttrName == SketchPlugin_EllipticArc::START_POINT_ID() ||
- theAttrName == SketchPlugin_EllipticArc::END_POINT_ID() ||
- theAttrName == SketchPlugin_EllipticArc::REVERSED_ID();
- }
- else if (theOwnerName == SketchPlugin_BSpline::ID()) {
- return theAttrName == SketchPlugin_BSpline::POLES_ID() ||
- theAttrName == SketchPlugin_BSpline::WEIGHTS_ID() ||
- theAttrName == SketchPlugin_BSpline::KNOTS_ID() ||
- theAttrName == SketchPlugin_BSpline::MULTS_ID() ||
- theAttrName == SketchPlugin_BSpline::DEGREE_ID();
- }
-
- // suppose that all remaining features are points
- return theAttrName == SketchPlugin_Point::COORD_ID();
-}
//
#include <PlaneGCSSolver_PointArrayWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
+
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <GeomAPI_Pnt2d.h>
PlaneGCSSolver_PointArrayWrapper::PlaneGCSSolver_PointArrayWrapper(
const std::vector<PointWrapperPtr>& thePoints)
: myPoints(thePoints)
{
}
+
+bool PlaneGCSSolver_PointArrayWrapper::update(AttributePtr theAttribute)
+{
+ bool isUpdated = false;
+ std::shared_ptr<GeomDataAPI_Point2DArray> aPointArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(theAttribute);
+ if (aPointArray && aPointArray->size() == (int)myPoints.size()) {
+ std::vector<PointWrapperPtr>::iterator aPIt = myPoints.begin();
+ for (int anIndex = 0; aPIt != myPoints.end(); ++aPIt, ++anIndex) {
+ GeomPnt2dPtr aPnt = aPointArray->pnt(anIndex);
+
+ const GCSPointPtr& aGCSPoint = (*aPIt)->point();
+ isUpdated = PlaneGCSSolver_Tools::updateValue(aPnt->x(), *(aGCSPoint->x)) || isUpdated;
+ isUpdated = PlaneGCSSolver_Tools::updateValue(aPnt->y(), *(aGCSPoint->y)) || isUpdated;
+ }
+ }
+ return isUpdated;
+}
/// \breif Size of array
int size() const { return (int)myPoints.size(); }
+ /// \brief Return array of points
+ const std::vector<PointWrapperPtr>& array() const { return myPoints; }
+ /// \breif Set points
+ void setArray(const std::vector<PointWrapperPtr>& thePoints) { myPoints = thePoints; }
+
/// \brief Return type of current entity
virtual SketchSolver_EntityType type() const
{ return ENTITY_POINT_ARRAY; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute);
+
private:
std::vector<PointWrapperPtr> myPoints;
};
//
#include <PlaneGCSSolver_PointWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
+
+#include <GeomDataAPI_Point2D.h>
PlaneGCSSolver_PointWrapper::PlaneGCSSolver_PointWrapper(const GCSPointPtr thePoint)
: myPoint(thePoint)
{
}
+
+bool PlaneGCSSolver_PointWrapper::update(AttributePtr theAttribute)
+{
+ bool isUpdated = false;
+ std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
+ if (aPoint2D) {
+ isUpdated = PlaneGCSSolver_Tools::updateValue(aPoint2D->x(), *(myPoint->x)) || isUpdated;
+ isUpdated = PlaneGCSSolver_Tools::updateValue(aPoint2D->y(), *(myPoint->y)) || isUpdated;
+ }
+ return isUpdated;
+}
virtual SketchSolver_EntityType type() const
{ return ENTITY_POINT; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute);
+
private:
GCSPointPtr myPoint;
};
//
#include <PlaneGCSSolver_ScalarArrayWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
PlaneGCSSolver_ScalarArrayWrapper::PlaneGCSSolver_ScalarArrayWrapper(const GCS::VEC_pD& theParam)
: myValue(theParam)
{
}
+
+bool PlaneGCSSolver_ScalarArrayWrapper::update(AttributePtr theAttribute)
+{
+ bool isUpdated = false;
+ PlaneGCSSolver_Tools::AttributeArray anArray(theAttribute);
+ if (anArray.isInitialized() && anArray.size() == (int)myValue.size()) {
+ for (int anIndex = 0; anIndex < anArray.size(); ++anIndex) {
+ isUpdated = PlaneGCSSolver_Tools::updateValue(anArray.value(anIndex), *(myValue[anIndex]))
+ || isUpdated;
+ }
+ }
+ return isUpdated;
+}
public:
PlaneGCSSolver_ScalarArrayWrapper(const GCS::VEC_pD& theParam);
+ /// \breif Size of array
+ int size() const { return (int)myValue.size(); }
+
/// \brief Return array of PlaneGCS parameters
const GCS::VEC_pD& array() const { return myValue; }
+ /// \breif Set array of parameters
+ void setArray(const GCS::VEC_pD& theParams) { myValue = theParams; }
/// \brief Return type of current entity
virtual SketchSolver_EntityType type() const
{ return ENTITY_SCALAR_ARRAY; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute);
+
protected:
GCS::VEC_pD myValue; ///< list of pointers to values provided by the storage
};
//
#include <PlaneGCSSolver_ScalarWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
PlaneGCSSolver_ScalarWrapper::PlaneGCSSolver_ScalarWrapper(double *const theParam)
: myValue(theParam)
{
return *myValue;
}
+
+bool PlaneGCSSolver_ScalarWrapper::update(AttributePtr theAttribute)
+{
+ double anAttrValue = 0.0;
+ AttributeDoublePtr aDouble =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
+ if (aDouble)
+ anAttrValue = aDouble->value();
+ else {
+ AttributeIntegerPtr anInt =
+ std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttribute);
+ if (anInt)
+ anAttrValue = anInt->value();
+ else
+ return false;
+ }
+
+ // There is possible an angular value, which is converted between degrees and radians.
+ // So, we use its value instead of using direct pointer to variable.
+ double aCurrentValue = value();
+
+ bool isUpdated = PlaneGCSSolver_Tools::updateValue(anAttrValue, aCurrentValue);
+ if (isUpdated)
+ setValue(aCurrentValue);
+ return isUpdated;
+}
virtual SketchSolver_EntityType type() const
{ return ENTITY_SCALAR; }
+protected:
+ /// \brief Update entity by the values of theAttribute
+ /// \return \c true if any value of attribute is not equal to the stored in the entity
+ virtual bool update(std::shared_ptr<ModelAPI_Attribute> theAttribute);
+
protected:
double* myValue; ///< pointer to value provided by the storage
};
return aResult;
}
-/// \brief Update value
-static bool updateValue(const double& theSource, double& theDest)
-{
- static const double aTol = 1.e4 * tolerance;
- bool isUpdated = fabs(theSource - theDest) > aTol;
- if (isUpdated)
- theDest = theSource;
- return isUpdated;
-}
-
-/// \brief Update coordinates of the point or scalar using its base attribute
-static bool updateValues(AttributePtr& theAttribute, EntityWrapperPtr& theEntity)
-{
- bool isUpdated = false;
-
- std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
- if (aPoint2D) {
- const GCSPointPtr& aGCSPoint =
- std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity)->point();
- isUpdated = updateValue(aPoint2D->x(), *(aGCSPoint->x)) || isUpdated;
- isUpdated = updateValue(aPoint2D->y(), *(aGCSPoint->y)) || isUpdated;
- } else {
- AttributeDoublePtr aScalar =
- std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
- if (aScalar) {
- ScalarWrapperPtr aWrapper =
- std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(theEntity);
- // There is possible angular value, which is converted between degrees and radians.
- // So, we use its value instead of using direct pointer to value.
- double aValue = aWrapper->value();
- isUpdated = updateValue(aScalar->value(), aValue);
- if (isUpdated)
- aWrapper->setValue(aValue);
- } else {
- AttributeBooleanPtr aBoolean =
- std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttribute);
- if (aBoolean) {
- BooleanWrapperPtr aWrapper =
- std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(theEntity);
- isUpdated = aWrapper->value() != aBoolean->value();
- aWrapper->setValue(aBoolean->value());
- }
- }
- }
-
- return isUpdated;
-}
-
static bool hasReference(std::shared_ptr<SketchPlugin_Feature> theFeature,
const std::string& theFeatureKind)
{
std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
std::list<AttributePtr>::iterator anAttrIt = anAttributes.begin();
for (; anAttrIt != anAttributes.end(); ++anAttrIt)
- if ((*anAttrIt)->attributeType() == GeomDataAPI_Point2D::typeId() ||
- (*anAttrIt)->attributeType() == ModelAPI_AttributeDouble::typeId() ||
- (*anAttrIt)->attributeType() == ModelAPI_AttributeBoolean::typeId())
+ if (PlaneGCSSolver_Tools::isAttributeApplicable((*anAttrIt)->id(), theFeature->getKind()))
isUpdated = update(*anAttrIt) || isUpdated;
// check external attribute is changed
return aRelated.get() != 0;
}
- bool isUpdated = updateValues(anAttribute, aRelated);
+ PlaneGCSSolver_AttributeBuilder aBuilder(aRelated->isExternal() ? 0 : this);
+ bool isUpdated = aBuilder.updateAttribute(anAttribute, aRelated);
if (isUpdated) {
setNeedToResolve(true);
notify(aFeature);
#include <PlaneGCSSolver_Tools.h>
#include <PlaneGCSSolver_EdgeWrapper.h>
+#include <PlaneGCSSolver_PointArrayWrapper.h>
#include <PlaneGCSSolver_PointWrapper.h>
+#include <PlaneGCSSolver_ScalarArrayWrapper.h>
#include <PlaneGCSSolver_ScalarWrapper.h>
#include <PlaneGCSSolver_ConstraintWrapper.h>
#include <SketchSolver_ConstraintMultiRotation.h>
#include <SketchSolver_ConstraintMultiTranslation.h>
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_BSpline.h>
+#include <SketchPlugin_Circle.h>
#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_ConstraintCollinear.h>
#include <SketchPlugin_ConstraintRigid.h>
#include <SketchPlugin_ConstraintPerpendicular.h>
#include <SketchPlugin_ConstraintTangent.h>
+#include <SketchPlugin_Ellipse.h>
+#include <SketchPlugin_EllipticArc.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_MultiRotation.h>
#include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_Point.h>
#include <GeomAPI_Circ2d.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Lin2d.h>
#include <GeomAPI_Pnt2d.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeIntArray.h>
+
#include <cmath>
std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2);
static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
+static GCS::SET_pD scalarArrayParameters(const EntityWrapperPtr& theArray);
static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
+static GCS::SET_pD pointArrayParameters(const EntityWrapperPtr& theArray);
static GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine);
static GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle);
static GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc);
case ENTITY_SCALAR:
case ENTITY_ANGLE:
return scalarParameters(GCS_SCALAR_WRAPPER(theEntity));
+ case ENTITY_SCALAR_ARRAY:
+ return scalarArrayParameters(theEntity);
case ENTITY_POINT:
return pointParameters(GCS_POINT_WRAPPER(theEntity));
+ case ENTITY_POINT_ARRAY:
+ return pointArrayParameters(theEntity);
case ENTITY_LINE:
return lineParameters(GCS_EDGE_WRAPPER(theEntity));
case ENTITY_CIRCLE:
return GCS::SET_pD();
}
+bool PlaneGCSSolver_Tools::isAttributeApplicable(const std::string& theAttrName,
+ const std::string& theOwnerName)
+{
+ if (theOwnerName == SketchPlugin_Arc::ID()) {
+ return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
+ theAttrName == SketchPlugin_Arc::START_ID() ||
+ theAttrName == SketchPlugin_Arc::END_ID() ||
+ theAttrName == SketchPlugin_Arc::REVERSED_ID();
+ }
+ else if (theOwnerName == SketchPlugin_Circle::ID()) {
+ return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
+ theAttrName == SketchPlugin_Circle::RADIUS_ID();
+ }
+ else if (theOwnerName == SketchPlugin_Line::ID()) {
+ return theAttrName == SketchPlugin_Line::START_ID() ||
+ theAttrName == SketchPlugin_Line::END_ID();
+ }
+ else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
+ return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
+ theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
+ theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
+ theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
+ }
+ else if (theOwnerName == SketchPlugin_EllipticArc::ID()) {
+ return theAttrName == SketchPlugin_EllipticArc::CENTER_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::FIRST_FOCUS_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::SECOND_FOCUS_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_START_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_END_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MAJOR_RADIUS_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::MINOR_RADIUS_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::START_POINT_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::END_POINT_ID() ||
+ theAttrName == SketchPlugin_EllipticArc::REVERSED_ID();
+ }
+ else if (theOwnerName == SketchPlugin_BSpline::ID()) {
+ return theAttrName == SketchPlugin_BSpline::POLES_ID() ||
+ theAttrName == SketchPlugin_BSpline::WEIGHTS_ID() ||
+ theAttrName == SketchPlugin_BSpline::KNOTS_ID() ||
+ theAttrName == SketchPlugin_BSpline::MULTS_ID() ||
+ theAttrName == SketchPlugin_BSpline::DEGREE_ID() ||
+ theAttrName == SketchPlugin_BSpline::START_ID() ||
+ theAttrName == SketchPlugin_BSpline::END_ID();
+ }
+
+ // suppose that all remaining features are points
+ return theAttrName == SketchPlugin_Point::COORD_ID();
+}
+
+/// \brief Update value
+bool PlaneGCSSolver_Tools::updateValue(const double& theSource, double& theDest,
+ const double theTolerance)
+{
+ bool isUpdated = fabs(theSource - theDest) > theTolerance;
+ if (isUpdated)
+ theDest = theSource;
+ return isUpdated;
+}
+
+
+
+
+
+// ================ AttributeArray methods ==========================
+PlaneGCSSolver_Tools::AttributeArray::AttributeArray(AttributePtr theAttribute)
+{
+ myDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttribute);
+ myInteger = std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttribute);
+}
+
+bool PlaneGCSSolver_Tools::AttributeArray::isInitialized() const
+{
+ return (myDouble && myDouble->isInitialized()) || (myInteger && myInteger->isInitialized());
+}
+
+int PlaneGCSSolver_Tools::AttributeArray::size() const
+{
+ return myDouble.get() ? myDouble->size() : myInteger->size();
+}
+
+double PlaneGCSSolver_Tools::AttributeArray::value(const int theIndex) const
+{
+ return myDouble.get() ? myDouble->value(theIndex) : myInteger->value(theIndex);
+}
+
return aParams;
}
+GCS::SET_pD scalarArrayParameters(const EntityWrapperPtr& theArray)
+{
+ ScalarArrayWrapperPtr anArray =
+ std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(theArray);
+ return GCS::SET_pD(anArray->array().begin(), anArray->array().end());
+}
+
GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
{
GCS::SET_pD aParams;
return aParams;
}
+GCS::SET_pD pointArrayParameters(const EntityWrapperPtr& theArray)
+{
+ GCS::SET_pD aParams;
+ PointArrayWrapperPtr aPoints =
+ std::dynamic_pointer_cast<PlaneGCSSolver_PointArrayWrapper>(theArray);
+ for (std::vector<PointWrapperPtr>::const_iterator anIt = aPoints->array().begin();
+ anIt != aPoints->array().end(); ++anIt) {
+ GCS::SET_pD aPointParams = PlaneGCSSolver_Tools::parameters(*anIt);
+ aParams.insert(aPointParams.begin(), aPointParams.end());
+ }
+ return aParams;
+}
+
GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine)
{
GCS::SET_pD aParams;
class GeomAPI_Lin2d;
class GeomAPI_Pnt2d;
+class ModelAPI_AttributeDoubleArray;
+class ModelAPI_AttributeIntArray;
+
/** \namespace PlaneGCSSolver_Tools
* \ingroup Plugins
* \brief Converter tools
const EntityWrapperPtr& theEntity3 = EntityWrapperPtr(),
const EntityWrapperPtr& theEntity4 = EntityWrapperPtr());
+ /// \brief Return \c true if the attribute is used in PlaneGCS solver
+ /// \param[in] theAttrName name of the attribute
+ /// \param[in] theOwnerName name of the parent feature
+ bool isAttributeApplicable(const std::string& theAttrName,
+ const std::string& theOwnerName);
+
/// \brief Convert entity to point
/// \return empty pointer if the entity is not a point
std::shared_ptr<GeomAPI_Pnt2d> point(EntityWrapperPtr theEntity);
/// brief Return list of parameters for the given entity
GCS::SET_pD parameters(const EntityWrapperPtr& theEntity);
+
+ /// \brief Update value in theDest if theSource is differ more than theTolerance
+ /// \return \c true if the value was updated.
+ bool updateValue(const double& theSource, double& theDest,
+ const double theTolerance = 1.e-4 * tolerance);
+
+ /// \brief Provide an interface to access values in attribute which is an array of values
+ class AttributeArray
+ {
+ public:
+ AttributeArray(AttributePtr theAttribute);
+
+ bool isInitialized() const;
+
+ int size() const;
+
+ double value(const int theIndex) const;
+
+ private:
+ std::shared_ptr<ModelAPI_AttributeDoubleArray> myDouble;
+ std::shared_ptr<ModelAPI_AttributeIntArray> myInteger;
+ };
};
#endif
QString aXmlRepr = anOperation->getDescription()->xmlRepresentation();
ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myOperationMgr->workshop());
- aFactory.createPanel(contentWidget(), theFeature);
- /// Apply button should be update if the feature was modified by the panel
+ ModuleBase_PageBase* aPage = contentWidget();
+ aFactory.createPanel(aPage, theFeature);
+ // update model widgets if exist
+ setModelWidgets(aPage->modelWidgets());
+ // Apply button should be update if the feature was modified by the panel
myOperationMgr->onValidateOperation();
}
ModuleBase_OperationFeature* aFeatureOp =