/// \param theStdActions - a map of standard actions
virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions) {}
+ /// Updates the current operation state after undo/redo actions calling
+ virtual void updateOperationByUndoRedo() {}
+
/// Returns true if the action should be always enabled
/// \param theActionId an action index: Accept or Accept All
/// \return boolean value
}
}
-void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
-{
- //blockUpdateViewer(true);
-#ifdef DEBUG_WIDGET_INSTANCE
- qDebug("ModuleBase_ModelWidget::moveObject");
-#endif
-
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
- ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
- Events_Loop::loop()->flush(anEvent);
-
- //blockUpdateViewer(false);
-}
-
bool ModuleBase_ModelWidget::processEnter()
{
return false;
/// \param theObj is updating object
void updateObject(ObjectPtr theObj);
- /// Sends Move event for the given object
- /// \param theObj is object for moving
- static void moveObject(ObjectPtr theObj);
-
/// Translate passed string with widget context()
virtual QString translate(const std::string& theStr) const;
}
void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer aMode)
+ const Standard_Integer theMode)
{
- if (aMode > TopAbs_SHAPE) {
+ if (appendVertexSelection(aSelection, theMode))
+ return;
+
+ if (theMode > TopAbs_SHAPE) {
// In order to avoid using custom selection modes
- if (aMode == ModuleBase_ResultPrs::Sel_Result) {
+ if (theMode == ModuleBase_ResultPrs::Sel_Result) {
AIS_Shape::ComputeSelection(aSelection, TopAbs_COMPOUND);
}
return;
// TODO: OCCT issue should be created for the COMPOUND processing
// before it is fixed, the next workaround in necessary
- if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) {
+ if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) {
const TopoDS_Shape& aShape = Shape();
TopExp_Explorer aCompExp(aShape, TopAbs_COMPOUND);
// do not activate in compound mode shapes which do not contain compounds
return;
}
- if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
+ if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
// Limit selection area only by actual object (Shape)
ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
if (aCompSolid.get()) {
}
//AIS_Shape::ComputeSelection(aSelection, 0);
}
- AIS_Shape::ComputeSelection(aSelection, aMode);
+ AIS_Shape::ComputeSelection(aSelection, theMode);
if (myAdditionalSelectionPriority > 0) {
for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
}
}
-void ModuleBase_ResultPrs::appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
- const TopoDS_Shape& theShape)
+bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
+ const Standard_Integer theMode)
{
- static TopAbs_ShapeEnum TypOfSel
- = AIS_Shape::SelectionType(AIS_Shape::SelectionMode(TopAbs_WIRE));
- // POP protection against crash in low layers
- Standard_Real aDeflection = Prs3d::GetDeflection(theShape, myDrawer);
- try {
- StdSelect_BRepSelectionTool::Load(theSelection,
- this,
- theShape,
- TypOfSel,
- aDeflection,
- myDrawer->HLRAngle(),
- myDrawer->IsAutoTriangulation());
- } catch ( Standard_Failure ) {
+ if (Shape().ShapeType() == TopAbs_VERTEX) {
+ const TopoDS_Shape& aShape = Shape();
+
+ int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_VERTEX);
+ double aDeflection = Prs3d::GetDeflection(aShape, myDrawer);
+
+ /// The cause of this method is the last parameter of BRep owner setting into True.
+ /// That means that owner should behave like it comes from decomposition. (In this case, OCCT
+ /// visualizes it in Ring style) OCCT version is 7.0.0 with path for SHAPER module.
+ Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aShape, aPriority, Standard_True);
+ StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection,
+ aDeflection, myDrawer->HLRAngle(), 9, 500);
+
+ for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
+ Handle(SelectMgr_EntityOwner) anOwner =
+ Handle(SelectMgr_EntityOwner)
+ ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId());
+ anOwner->Set(this);
+ }
+ return true;
}
+ return false;
}
void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM,
/// Highlight the presentation with the given color
/// \param aPM a presentations manager
/// \param theStyle a style of presentation
- /// \param aMode a drawing mode
+ /// \param theMode a drawing mode
virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM,
- const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer aMode = 0)
+ const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0)
{
Selectable()->HilightOwnerWithColor(aPM, theStyle, this);
}
/// Redefinition of virtual function
Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer aMode) ;
+ const Standard_Integer theMode) ;
private:
- /// Appens sensitive and owners for wires of the given shape into selection
+ /// If the shape of this presentation is Vertex, it appends custom sensitive and owners for it.
+ /// Owner is a usual Brep owner with "isDecomposite" in true. It is necessary to have "Ring"
+ /// highlight/selected marker.
/// \param theSelection a current filled selection
- /// \param theShape a shape
- void appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
- const TopoDS_Shape& theShape);
+ /// \param theMode a selection mode
+ /// \return true if the owner is created
+ bool appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
+ const Standard_Integer theMode);
/// Reference to result object
ResultPtr myResult;
if (theData->getBooleanAttribute("use_in_title", false))
myButtonTitles = aList;
+ bool aHasDefaultValue;
+ int aDefaultVal = QString::fromStdString(getDefaultValue()).toInt(&aHasDefaultValue);
// Widget type can be combobox or radiobuttons
std::string aWgtType = theData->getProperty("widget_type");
if ((aWgtType.length() > 0) && (aWgtType == "radiobuttons")) {
myButtons->addButton(aBtn, aId++);
}
}
- myButtons->button(0)->setChecked(true);
+ int aCheckedId = aHasDefaultValue ? aDefaultVal : 0;
+ myButtons->button(aDefaultVal)->setChecked(true);
connect(myButtons, SIGNAL(buttonClicked(int)), this, SLOT(onCurrentIndexChanged(int)));
} else {
myLabel = new QLabel(aLabelText, this);
myCombo->addItems(aList);
+ if (aHasDefaultValue && aDefaultVal < aList.size())
+ myCombo->setCurrentIndex(aDefaultVal);
+
connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
}
}
PartSet_OperationPrs.h
PartSet_OverconstraintListener.h
PartSet_PreviewPlanes.h
+ PartSet_PreviewSketchPlane.h
PartSet_ResultSketchPrs.h
PartSet_SketcherMgr.h
PartSet_SketcherReentrantMgr.h
PartSet_Tools.h
PartSet_Validators.h
- PartSet_WidgetChoice.h
PartSet_WidgetEditor.h
PartSet_WidgetFeaturePointSelector.h
PartSet_WidgetFileSelector.h
PartSet_Module.h
PartSet_SketcherMgr.h
PartSet_SketcherReentrantMgr.h
- PartSet_WidgetChoice.h
PartSet_WidgetEditor.h
PartSet_WidgetFeaturePointSelector.h
PartSet_WidgetFileSelector.h
PartSet_OperationPrs.cpp
PartSet_OverconstraintListener.cpp
PartSet_PreviewPlanes.cpp
+ PartSet_PreviewSketchPlane.cpp
PartSet_ResultSketchPrs.cpp
PartSet_SketcherMgr.cpp
PartSet_SketcherReentrantMgr.cpp
/// Returns color lighter than sketch feature entity : pink
static const std::string OPERATION_REMOVE_FEATURE_COLOR() { return "255, 174, 201"; }
+
+ /// Returns color equal to default color of construction plugin : gray
+ static const std::string OPERATION_SKETCH_PLANE() { return "150,150,180"; }
public:
/// Constructor
/// \param theWorkshop a reference to workshop
{
ObjectPtr aSelectedObject = PartSet_Tools::findFixedObjectByExternal(
theShape->impl<TopoDS_Shape>(), theSelectedObject, theSketch);
- FeaturePtr aFeature = ModelAPI_Feature::feature(aSelectedObject);
- if (aFeature.get()) {
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- /// some sketch entities should be never shown, e.g. projection feature
- /// such external features should not be used in selection
- if (aSketchFeature.get() && !aSketchFeature->canBeDisplayed())
- return ObjectPtr();
- }
-
if (!aSelectedObject.get()) {
// Processing of external (non-sketch) object
- aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape->impl<TopoDS_Shape>(),
- theSelectedObject, theSketch, theTemporary);
+ FeaturePtr aCreatedFeature;
+ aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape,
+ theSelectedObject, theSketch, theTemporary, aCreatedFeature);
if (aSelectedObject.get() && theTemporary)
- myExternalObjectValidated = aSelectedObject;
+ myExternalObjectValidated = aCreatedFeature;
}
return aSelectedObject;
}
#include "PartSet_MenuMgr.h"
#include "PartSet_CustomPrs.h"
#include "PartSet_IconFactory.h"
-#include "PartSet_WidgetChoice.h"
#include "PartSet_OverconstraintListener.h"
#include "PartSet_Filters.h"
#include <ModuleBase_IViewer.h>
#include <ModuleBase_IViewWindow.h>
#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_WidgetChoice.h>
#include <ModuleBase_WidgetEditor.h>
#include <ModuleBase_WidgetValidated.h>
#include <ModuleBase_Tools.h>
Config_PropManager::registerProp("Visualization", "operation_remove_feature_color",
"Color of removed feature in operation", Config_Prop::Color,
PartSet_CustomPrs::OPERATION_REMOVE_FEATURE_COLOR());
+ Config_PropManager::registerProp("Visualization", "sketch_preview_plane",
+ "Color of sketch plane", Config_Prop::Color,
+ PartSet_CustomPrs::OPERATION_SKETCH_PLANE());
}
PartSet_Module::~PartSet_Module()
myMenuMgr->updateViewerMenu(theStdActions);
}
+void PartSet_Module::updateOperationByUndoRedo()
+{
+ PartSet_SketcherMgr* aSketchMgr = sketchMgr();
+ aSketchMgr->previewSketchPlane()->updatePlaneSize(aSketchMgr->activeSketch(), workshop());
+}
+
bool PartSet_Module::isActionEnableStateFixed(const int theActionId) const
{
bool isEnabledFixed = false;
} else if (theType == "sketch_launcher") {
aWgt = new PartSet_WidgetSketchCreator(theParent, this, theWidgetApi);
} else if (theType == "module_choice") {
- aWgt = new PartSet_WidgetChoice(theParent, theWidgetApi);
+ aWgt = new ModuleBase_WidgetChoice(theParent, theWidgetApi);
connect(aWgt, SIGNAL(itemSelected(ModuleBase_ModelWidget*, int)),
this, SLOT(onChoiceChanged(ModuleBase_ModelWidget*, int)));
}
void PartSet_Module::onChoiceChanged(ModuleBase_ModelWidget* theWidget,
int theIndex)
{
- PartSet_WidgetChoice* aChoiceWidget = dynamic_cast<PartSet_WidgetChoice*>(theWidget);
+ ModuleBase_WidgetChoice* aChoiceWidget = dynamic_cast<ModuleBase_WidgetChoice*>(theWidget);
if (!aChoiceWidget)
return;
/// \param theStdActions - a map of standard actions
virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions);
+ /// Updates the current operation state after undo/redo actions calling
+ virtual void updateOperationByUndoRedo();
+
/// Returns true if the action should be always enabled
/// \param theActionId an action index: Accept or Accept All
/// \return boolean value
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "PartSet_PreviewSketchPlane.h"
+#include "PartSet_Tools.h"
+
+#include <ModuleBase_IWorkshop.h>
+
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <XGUI_Tools.h>
+#include <XGUI_Displayer.h>
+#include <XGUI_Workshop.h>
+
+#include <Config_PropManager.h>
+#include <GeomAlgoAPI_FaceBuilder.h>
+
+#include <SketchPlugin_Sketch.h>
+#include <SketchPlugin_SketchEntity.h>
+
+#include <BRepBndLib.hxx>
+
+double maximumSize(double theXmin, double theYmin, double theZmin,
+ double theXmax, double theYmax, double theZmax)
+{
+ double aSize = fabs(theXmax - theXmin);
+ double aSizeToCompare = fabs(theYmax - theYmin);
+ if (aSizeToCompare > aSize)
+ aSize = aSizeToCompare;
+ aSizeToCompare = fabs(theZmax - theZmin);
+ if (aSizeToCompare > aSize)
+ aSize = aSizeToCompare;
+
+ return aSize;
+}
+
+PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane()
+ : mySketchDisplayed(false), myOtherSketchSize(0)
+{
+}
+
+void PartSet_PreviewSketchPlane::setOtherSketchParameters(const GeomShapePtr& theOtherSketchFace)
+{
+ myOtherSketchOrigin = std::shared_ptr<GeomAPI_Pnt>();
+ myOtherSketchSize = 0;
+ if (!theOtherSketchFace)
+ return;
+
+ getShapeParameters(theOtherSketchFace, myOtherSketchOrigin, myOtherSketchSize);
+}
+
+void PartSet_PreviewSketchPlane::eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop,
+ const bool isClearPlane)
+{
+ if (mySketchDisplayed) {
+ XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+ aDisp->eraseAIS(myPlane, false);
+ if (isClearPlane) {
+ myPlane = NULL;
+ myOrigin = NULL;
+ myNormal = NULL;
+ }
+ mySketchDisplayed = false;
+ }
+}
+
+void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& theSketch,
+ ModuleBase_IWorkshop* theWorkshop)
+{
+ if (mySketchDisplayed)
+ return;
+
+ // plane is visualized only if sketch plane is filled
+ std::shared_ptr<GeomAPI_Pln> aPlane = PartSet_Tools::sketchPlane(theSketch);
+ if (!aPlane.get())
+ return;
+
+ if (!myPlane) { // If planes are not created
+ std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+ theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+ std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+
+ // Create Preview
+ // default planes parameters
+ std::shared_ptr<GeomAPI_Pnt> anOriginPnt = anOrigin->pnt();
+ double aSize = 10;//Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size");
+ // another sketch parameters
+ if (myOtherSketchOrigin) {
+ anOriginPnt = myOtherSketchOrigin;
+ aSize = myOtherSketchSize;
+ setOtherSketchParameters(GeomShapePtr());
+ }
+ else {
+ // selected linear face parameters
+ AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+ (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+ if (aSelAttr) {
+ std::shared_ptr<GeomAPI_Shape> aSketchExternalFace = aSelAttr->value();
+ if (aSketchExternalFace)
+ getShapeParameters(aSketchExternalFace, anOriginPnt, aSize);
+ }
+ }
+ double aSketchSize = getSketchBoundingBoxSize(theSketch, anOriginPnt);
+ if (aSketchSize > 0)
+ aSize = aSketchSize;
+
+ myOrigin = anOriginPnt;
+ myNormal = aNormal->dir();
+ myPlane = createPreviewPlane(aSize);
+ }
+
+ XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+ aDisp->displayAIS(myPlane, true, 1/*shaded*/, false);
+ mySketchDisplayed = true;
+}
+
+void PartSet_PreviewSketchPlane::updatePlaneSize(const CompositeFeaturePtr& theSketch,
+ ModuleBase_IWorkshop* theWorkshop)
+{
+ std::shared_ptr<GeomAPI_Pnt> anOriginPnt;
+ double aSize = getSketchBoundingBoxSize(theSketch, anOriginPnt);
+ if (aSize <= 0)
+ return;
+ myOrigin = anOriginPnt;
+ createPreviewPlane(aSize);
+}
+
+AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane(double theSize)
+{
+ std::vector<int> aYZRGB(3, 0);
+#ifdef SET_PLANES_COLOR_IN_PREFERENCES
+ aYZRGB = Config_PropManager::color("Visualization", "yz_plane_color");
+#else
+ aYZRGB[0] = 225;
+#endif
+ int aR[] = {aYZRGB[0], aYZRGB[1], aYZRGB[2]};
+
+ std::shared_ptr<GeomAPI_Shape> aFace =
+ GeomAlgoAPI_FaceBuilder::squareFace(myOrigin, myNormal, theSize);
+
+ if (myPlane.get()) {
+ myPlane->createShape(aFace);
+ return myPlane;
+ }
+ else {
+ AISObjectPtr aAIS = AISObjectPtr(new GeomAPI_AISObject());
+ aAIS->createShape(aFace);
+ std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_preview_plane");
+ if (aColor.size() == 3)
+ aAIS->setColor(aColor[0], aColor[1], aColor[2]);
+ aAIS->setTransparensy(0.8);
+
+ int aDispMode = 1; // shading
+ Handle(AIS_InteractiveObject) anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAISIO.IsNull()) {
+ anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
+ anAISIO->SetDisplayMode(aDispMode);
+ }
+ return aAIS;
+ }
+}
+
+void PartSet_PreviewSketchPlane::getShapeParameters(const GeomShapePtr& theShape,
+ std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ double& theSize)
+{
+ theOrigin = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
+
+ // Create rectangular face close to the selected
+ double aXmin, anYmin, aZmin, aXmax, anYmax, aZmax;
+ theShape->computeSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+
+ theSize = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+}
+
+double PartSet_PreviewSketchPlane::getSketchBoundingBoxSize(
+ const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+ std::shared_ptr<GeomAPI_Pnt>& theCentralPnt)
+{
+ if (!theSketch.get() || theSketch->numberOfSubs() == 0)
+ return 0;
+
+ Bnd_Box aBox;
+ for (int aSubFeatureId = 0; aSubFeatureId < theSketch->numberOfSubs(); aSubFeatureId++) {
+ FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId);
+ if (!aFeature.get())
+ continue;
+
+ std::list<ResultPtr> aResults = aFeature->results();
+ std::list<ResultPtr>::const_iterator aResultIt;
+ for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) {
+ ResultPtr aResult = *aResultIt;
+ std::shared_ptr<GeomAPI_Shape> aShapePtr = aResult->shape();
+ if (aShapePtr.get()) {
+ TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
+ if (aShape.IsNull())
+ continue;
+ BRepBndLib::Add(aShape, aBox);
+ }
+ }
+ }
+ if (aBox.IsVoid())
+ return 0;
+
+ double aXmin, aXmax, anYmin, anYmax, aZmin, aZmax;
+ aBox.Get(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+
+ double aSize = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+ if (aSize > 0) {
+ gp_Pnt aCentre(aXmax-fabs(aXmax-aXmin)/2., anYmax-fabs(anYmax-anYmin)/2.,
+ aZmax - fabs(aZmax-aZmin)/2.);
+ theCentralPnt = std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(),
+ aCentre.Z()));
+ }
+ return aSize;
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef PartSet_PreviewSketchPlane_H
+#define PartSet_PreviewSketchPlane_H
+
+#include <GeomAPI_AISObject.h>
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_AISObject.h>
+
+class ModuleBase_IWorkshop;
+class ModelAPI_CompositeFeature;
+
+/**
+* \class PartSet_PreviewSketchPlane
+* \ingroup Modules
+* A class to show/hide sketch preview plane
+*/
+class PartSet_PreviewSketchPlane
+{
+public:
+ /// Constructor
+ PartSet_PreviewSketchPlane();
+
+ ~PartSet_PreviewSketchPlane() {};
+
+ /// Returns if the sketch plane was displayed
+ /// \return boolean value
+ bool isSketchDisplayed() const { return mySketchDisplayed; }
+
+ /// Sets parameters of another sketch to be used in createSketchPlane().
+ /// \param theOtherSketchFace a shape of other selected sketch. It is a planar face.
+ void setOtherSketchParameters(const std::shared_ptr<GeomAPI_Shape>& theOtherSketchFace);
+
+ /// Erase preview planes
+ /// \param theWorkshop the application workshop
+ /// \param isClearPlane flag whether the plane, origin and normal should be nullified
+ void eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop, const bool isClearPlane = true);
+
+ /// Show preview planes
+ /// \param theSketch source sketch to initialize plane
+ /// \param theWorkshop the application workshop
+ void createSketchPlane(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+ ModuleBase_IWorkshop* theWorkshop);
+
+ /// Resize plane size by sketch content
+ /// \param theSketch source sketch to build sketch sub features bounding box
+ /// \param theWorkshop the application workshop
+ void updatePlaneSize(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+ ModuleBase_IWorkshop* theWorkshop);
+
+private:
+ /// Create a square face by parameters
+ /// \param theSize a size of created square
+ AISObjectPtr createPreviewPlane(double theSize);
+
+ /// Finds origin and maximum size of the shape
+ /// \param theShape source shape
+ /// \param theOrigin a shape center of mass
+ /// \param theSize maximum of delta X, Y or Z
+ void getShapeParameters(const std::shared_ptr<GeomAPI_Shape>& theShape,
+ std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ double& theSize);
+
+ /// Calculate maximum bounding box size of sketch sub features
+ /// \param theSketch source sketch to build sketch sub features bounding box
+ /// \param theCentralPoint central point of the sketch sub features
+ /// \return double value
+ double getSketchBoundingBoxSize(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+ std::shared_ptr<GeomAPI_Pnt>& theCentralPnt);
+
+private:
+ bool mySketchDisplayed;
+ AISObjectPtr myPlane;
+ std::shared_ptr<GeomAPI_Pnt> myOrigin; //! an origin of the plane
+ std::shared_ptr<GeomAPI_Dir> myNormal; //! a normal vector of the plane
+
+ std::shared_ptr<GeomAPI_Pnt> myOtherSketchOrigin;
+ double myOtherSketchSize;
+};
+
+#endif
\ No newline at end of file
#include "PartSet_WidgetEditor.h"
#include "PartSet_ResultSketchPrs.h"
#include "PartSet_ExternalPointsMgr.h"
+#include "PartSet_PreviewSketchPlane.h"
#include <XGUI_ModuleConnector.h>
#include <XGUI_Displayer.h>
#include <SketchPlugin_MultiRotation.h>
#include <SketchPlugin_MultiTranslation.h>
#include <SketchPlugin_IntersectionPoint.h>
+#include <SketchPlugin_Projection.h>
#include <SketcherPrs_Tools.h>
myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
myIsConstraintsShown[PartSet_Tools::Expressions] = false;
+
+ mySketchPlane = new PartSet_PreviewSketchPlane();
}
PartSet_SketcherMgr::~PartSet_SketcherMgr()
FeaturePtr aFeature = myCurrentSelection.begin().key();
std::shared_ptr<SketchPlugin_Feature> aSPFeature =
std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- if (aSPFeature && (!aSPFeature->isExternal())) {
- myModule->editFeature(aSPFeature);
+ if (aSPFeature) {
+ if (!aSPFeature->isExternal())
+ myModule->editFeature(aSPFeature);
+ else {
+ FeaturePtr aProjectionFeature = PartSet_Tools::findRefsToMeFeature(aFeature,
+ SketchPlugin_Projection::ID());
+ if (aProjectionFeature.get())
+ myModule->editFeature(aProjectionFeature);
+ }
}
}
}
// Display all sketcher sub-Objects
myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
+ mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop());
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
// Hide sketcher result
XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
// The sketch was aborted
myCurrentSketch = CompositeFeaturePtr();
+ mySketchPlane->eraseSketchPlane(myModule->workshop());
// TODO: move this outside of if-else
myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
myCurrentSketch->setDisplayed(true);
myCurrentSketch = CompositeFeaturePtr();
+ mySketchPlane->eraseSketchPlane(myModule->workshop());
myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
{
+ previewSketchPlane()->updatePlaneSize(activeSketch(), myModule->workshop());
myIsMouseOverViewProcessed = true;
operationMgr()->onValidateOperation();
// when sketch nested operation is stopped the cursor should be restored unconditionally
#include "PartSet_Filters.h"
#include "PartSet_Tools.h"
+#include "PartSet_PreviewSketchPlane.h"
#include <ModelAPI_Feature.h>
#include <ModelAPI_Attribute.h>
/// Returns current Sketch feature/ Returns NULL if there is no launched sketch operation
CompositeFeaturePtr activeSketch() const { return myCurrentSketch; }
+ /// Returns help class to visualize sketcher plane
+ /// \return a preview plane
+ PartSet_PreviewSketchPlane* previewSketchPlane() const { return mySketchPlane; }
+
/// Starts sketch operation
void startSketch(ModuleBase_Operation* );
private:
PartSet_Module* myModule;
+ PartSet_PreviewSketchPlane* mySketchPlane; // display/erase sketch plane on start/stop sketch operation
bool myPreviousDrawModeEnabled; // the previous selection enabled state in the viewer
bool myIsEditLaunching;
#include <SketchPlugin_Arc.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Point.h>
+#include <SketchPlugin_Projection.h>
#include <ModuleBase_IWorkshop.h>
#include <ModuleBase_ViewerPrs.h>
const ObjectPtr& theObject,
CompositeFeaturePtr theSketch)
{
- ResultPtr aResult;
- if (theShape.ShapeType() == TopAbs_EDGE) {
- // Check that we already have such external edge
- std::shared_ptr<GeomAPI_Edge> aInEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge());
- aInEdge->setImpl(new TopoDS_Shape(theShape));
- aResult = findExternalEdge(theSketch, aInEdge);
- }
- if (theShape.ShapeType() == TopAbs_VERTEX) {
- std::shared_ptr<GeomAPI_Vertex> aInVert = std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex());
- aInVert->setImpl(new TopoDS_Shape(theShape));
- aResult = findExternalVertex(theSketch, aInVert);
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ if (!aResult.get())
+ return ResultPtr();
+
+ for (int i = 0, aNbSubs = theSketch->numberOfSubs(); i < aNbSubs; i++) {
+ FeaturePtr aFeature = theSketch->subFeature(i);
+ if (aFeature->getKind() != SketchPlugin_Projection::PROJECTED_FEATURE_ID())
+ continue;
+ if (aFeature->lastResult() == aResult)
+ return aResult;
}
- return aResult;
+ return ResultPtr();
}
-ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape,
- const ObjectPtr& theObject,
- CompositeFeaturePtr theSketch,
- const bool theTemporary)
+ResultPtr PartSet_Tools::createFixedObjectByExternal(
+ const std::shared_ptr<GeomAPI_Shape>& theShape,
+ const ObjectPtr& theObject,
+ CompositeFeaturePtr theSketch,
+ const bool theTemporary,
+ FeaturePtr& theCreatedFeature)
{
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+
+ if (!aResult.get())
+ return ResultPtr();
+
+ FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID());
+ theCreatedFeature = aProjectionFeature;
+ AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
+ aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID()));
+ anExternalAttr->setValue(aResult, theShape);
+ AttributeBooleanPtr anIntoResult = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>
+ (aProjectionFeature->data()->attribute(SketchPlugin_Projection::INCLUDE_INTO_RESULT()));
+ anIntoResult->setValue(false);
+
+ aProjectionFeature->execute();
+
+ AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr(
+ SketchPlugin_Projection::PROJECTED_FEATURE_ID());
+ if (!aRefAttr || !aRefAttr->isInitialized())
+ return ResultPtr();
+
+ FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aProjection.get() && aProjection->lastResult().get())
+ return aProjection->lastResult();
+
+ //return aProjectionFeature->lastResult();//ResultPtr();//aFeature->attribute(;
+ /*
if (theShape.ShapeType() == TopAbs_EDGE) {
Standard_Real aStart, aEnd;
Handle(V3d_View) aNullView;
return aMyFeature->lastResult();
}
}
- }
+ }*/
return ResultPtr();
}
return false;
}
-ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch,
- std::shared_ptr<GeomAPI_Edge> theEdge)
-{
- for (int i = 0; i < theSketch->numberOfSubs(); i++) {
- FeaturePtr aFeature = theSketch->subFeature(i);
- std::shared_ptr<SketchPlugin_Feature> aSketchFea =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- // not displayed result of feature projection should not be returned as external edge
- if (aSketchFea && aSketchFea->canBeDisplayed()) {
- if (aSketchFea->isExternal()) {
- std::list<ResultPtr> aResults = aSketchFea->results();
- std::list<ResultPtr>::const_iterator aIt;
- for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
- ResultConstructionPtr aRes =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
- if (aRes) {
- std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
- if (aShape) {
- if (theEdge->isEqual(aShape))
- return aRes;
- }
- }
- }
- }
- }
- }
- return ResultPtr();
-}
-
-
-ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch,
- std::shared_ptr<GeomAPI_Vertex> theVert)
-{
- for (int i = 0; i < theSketch->numberOfSubs(); i++) {
- FeaturePtr aFeature = theSketch->subFeature(i);
- std::shared_ptr<SketchPlugin_Feature> aSketchFea =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- if (aSketchFea) {
- if (aSketchFea->isExternal()) {
- std::list<ResultPtr> aResults = aSketchFea->results();
- std::list<ResultPtr>::const_iterator aIt;
- for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
- ResultConstructionPtr aRes =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
- if (aRes) {
- std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
- if (aShape) {
- if (theVert->isEqual(aShape))
- return aRes;
- }
- }
- }
- }
- }
- }
- return ResultPtr();
-}
-
-
-bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrsPtr& thePrs, FeaturePtr theSketch,
- Handle(V3d_View) theView, double& theX, double& theY)
-{
- bool aHasVertex = false;
-
- const GeomShapePtr& aShape = thePrs->shape();
- if (aShape.get() && !aShape->isNull() && aShape->shapeType() == GeomAPI_Shape::VERTEX)
- {
- const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
- const TopoDS_Vertex& aVertex = TopoDS::Vertex(aTDShape);
- if (!aVertex.IsNull())
- {
- gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
- PartSet_Tools::convertTo2D(aPoint, theSketch, theView, theX, theY);
- aHasVertex = true;
- }
- }
-
- return aHasVertex;
-}
-
GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute,
ModuleBase_IWorkshop* theWorkshop)
{
/// \param theObject a selected result object
/// \param theSketch a sketch feature
/// \param theTemporary the created external object is temporary, execute is not performed for it
+ /// \param theCreatedFeature a new projection feature
/// \return result of created feature
static std::shared_ptr<ModelAPI_Result> createFixedObjectByExternal(
- const TopoDS_Shape& theShape,
+ const std::shared_ptr<GeomAPI_Shape>& theShape,
const ObjectPtr& theObject,
CompositeFeaturePtr theSketch,
- const bool theTemporary = false);
+ const bool theTemporary,
+ FeaturePtr& theCreatedFeature);
/// Checks whether the list of selected presentations contains the given one
/// \param theSelected a list of presentations
static bool isContainPresentation(const QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theSelected,
const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- /// Returns Result object if the given skietch contains external edge equal to the given
- /// \param theSketch - the sketch feature
- /// \param theEdge - the edge
- /// \return result object with external edge if it is found
- static std::shared_ptr<ModelAPI_Result> findExternalEdge(CompositeFeaturePtr theSketch,
- std::shared_ptr<GeomAPI_Edge> theEdge);
-
- /// Returns Result object if the given sketch contains external vertex equal to the given
- /// \param theSketch - the sketch feature
- /// \param theVert - the vertex
- /// \return result object with external vertex if it is found
- static std::shared_ptr<ModelAPI_Result> findExternalVertex(CompositeFeaturePtr theSketch,
- std::shared_ptr<GeomAPI_Vertex> theVert);
-
- /// Returns whether the selected presentation has a shape with the vertex type
- /// \param thePrs a selected presentation
- /// \param theSketch the sketch feature
- /// \param theView a 3D view
- /// \param theX the output horizontal coordinate of the point
- /// \param theY the output vertical coordinate of the point
- static bool hasVertexShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,
- FeaturePtr theSketch,
- Handle(V3d_View) theView, double& theX, double& theY);
-
-
/**
* Find attribute of object which corresponds to the given shape
* \param theObj - an object
QList<FeaturePtr>& theCoincidencies,
std::string theAttr, QList<bool>& theIsAttributes);
+ /*
+ * Finds and returns feature reerenced to the paramenter feature with the given name if found
+ * \param theFeature a source feature where refsToMe is obtained
+ * \param theFeatureId an indentifier of the searched feature
+ */
+ static FeaturePtr findRefsToMeFeature(FeaturePtr theFeature, const std::string& theFeatureId)
+ {
+ if (!theFeature.get())
+ return FeaturePtr();
+
+ // find first projected feature and edit it
+ const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator anIt;
+ for (anIt = aRefsList.cbegin(); anIt != aRefsList.cend(); ++anIt) {
+ FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*anIt)->owner());
+ if (aRefFeature->getKind() == theFeatureId)
+ return aRefFeature;
+ }
+ return FeaturePtr();
+ }
+
/**
* Returns point of a coincedence
* \param theStartCoin the coincedence feature
+++ /dev/null
-// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
-//
-
-#ifndef PartSet_WidgetChoice_H
-#define PartSet_WidgetChoice_H
-
-#include "PartSet.h"
-#include <ModuleBase_WidgetChoice.h>
-
-/**
-* \ingroup GUI
-* Implementation of a proxy of choice widget in order to geat access to it on moment
-* of creation in module
-*/
-class PARTSET_EXPORT PartSet_WidgetChoice : public ModuleBase_WidgetChoice
-{
-Q_OBJECT
- public:
- /// Constructor
- /// \param theParent the parent object
- /// \param theData the widget configuation. The attribute of the model widget is obtained from
- PartSet_WidgetChoice(QWidget* theParent, const Config_WidgetAPI* theData)
- : ModuleBase_WidgetChoice(theParent, theData) {}
-};
-
-#endif
\ No newline at end of file
if (myFeature->isMacro()) {
// Moving points of macro-features has been processed directly (without solver)
aPoint->setValue(myXSpin->value(), myYSpin->value());
- moveObject(myFeature);
+ updateObject(myFeature);
+
} else {
if (!aPoint->isInitialized())
aPoint->setValue(0., 0.);
if (!aFirstValue.get() && myPreSelected.get()) {
aFirstValue = myPreSelected;
}
+
// if we have selection and use it
if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) &&
aFirstValue->shape().get()) { /// Trihedron Axis may be selected, but shape is empty
else {
anExternal = true;
if (!aFixedObject.get())
- aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
+ {
+ FeaturePtr aCreatedFeature;
+ aFixedObject = PartSet_Tools::createFixedObjectByExternal(aGeomShape, aObject, mySketch,
+ false, aCreatedFeature);
+ }
}
}
if (anExternal) {
myExternalObjectMgr->getGeomSelection(thePrs, theObject, theShape,
myWorkshop, sketch(), myIsInValidate);
- /*
- FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(theObject);
- std::shared_ptr<SketchPlugin_Feature> aSPFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
- // there is no a sketch feature is selected, but the shape exists,
- // try to create an exernal object
- // TODO: unite with the same functionality in PartSet_WidgetShapeSelector
- if (aSPFeature.get() == NULL) {
- ObjectPtr anExternalObject = ObjectPtr();
- GeomShapePtr anExternalShape = GeomShapePtr();
- if (myExternalObjectMgr->useExternal()) {
- if (myExternalObjectMgr->canCreateExternal()) {
- GeomShapePtr aShape = theShape;
- if (!aShape.get()) {
- ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
- if (aResult.get())
- aShape = aResult->shape();
- }
- if (aShape.get() != NULL && !aShape->isNull())
- anExternalObject =
- myExternalObjectMgr->externalObject(theObject, aShape, sketch(), myIsInValidate);
- }
- else { /// use objects of found selection
- anExternalObject = theObject;
- anExternalShape = theShape;
- }
- }
- /// the object is null if the selected feature is "external"(not sketch entity feature of the
- /// current sketch) and it is not created by object manager
- theObject = anExternalObject;
- theShape = anExternalShape;
- }*/
}
//********************************************************************
void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrsPtr& thePrs)
{
- // 1. hide main planes if they have been displayed
+ // 1. hide main planes if they have been displayed and display sketch preview plane
myPreviewPlanes->erasePreviewPlanes(myWorkshop);
+
+ PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+ if (aModule) {
+ // if selected object is a shape of another sketch, the origin of selected shape does not stored
+ // in argument, so we need to find parameters of selected shape on the sketch
+ if (thePrs->object() && (feature() != thePrs->object())) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(thePrs->object());
+ if (aFeature.get() && (aFeature != feature())) {
+ if (aFeature->getKind() == SketchPlugin_Sketch::ID()) {
+ CompositeFeaturePtr aSketch =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+ std::shared_ptr<GeomAPI_Pln> aPlane = PartSet_Tools::sketchPlane(aSketch);
+ if (aPlane.get())
+ aModule->sketchMgr()->previewSketchPlane()->setOtherSketchParameters(thePrs->shape());
+ }
+ }
+ }
+ CompositeFeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+ aModule->sketchMgr()->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
+ }
// 2. if the planes were displayed, change the view projection
const GeomShapePtr& aShape = thePrs->shape();
std::shared_ptr<GeomAPI_Shape> aGShape;
#include <SketcherPrs_Factory.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Result.h>
data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+
+ data()->addAttribute(SketchPlugin_ConstraintLength::LOCATION_TYPE_ID(),
+ ModelAPI_AttributeInteger::typeId());
}
void SketchPlugin_ConstraintLength::colorConfigInfo(std::string& theSection, std::string& theName,
static const std::string MY_CONSTRAINT_LENGTH_ID("SketchConstraintLength");
return MY_CONSTRAINT_LENGTH_ID;
}
+
/// \brief Returns the kind of a feature
SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
{
return MY_KIND;
}
+ /// attribute name of dimension location type
+ inline static const std::string& LOCATION_TYPE_ID()
+ {
+ static const std::string MY_LOCATION_TYPE_ID("LocationType");
+ return MY_LOCATION_TYPE_ID;
+ }
+
/// \brief Creates a new part document if needed
SKETCHPLUGIN_EXPORT virtual void execute();
<doublevalue_editor label="Value" tooltip="Length" id="ConstraintValue" default="computed">
<validator id="GeomValidators_Positive"/>
</doublevalue_editor>
+ <module_choice id="LocationType"
+ widget_type="radiobuttons"
+ buttons_dir="horizontal"
+ label="Location type"
+ tooltip="Type of location"
+ string_list="Left Automatic Right"
+ icons_list="icons/Sketch/location_left.png icons/Sketch/location_automatic.png icons/Sketch/location_right.png"
+ default="1"
+ />
<validator id="PartSet_LengthSelection"/>
</feature>
#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <AIS_DisplaySpecialSymbol.hxx>
/// \param theDimValue an arrow value
/// \param theTextSize an arrow value
void updateArrows(Handle(Prs3d_DimensionAspect) theDimAspect,
- double theDimValue, double theTextSize)
+ double theDimValue, double theTextSize, SketcherPrs_Tools::LocationType theLocationType)
{
- double anArrowLength = theDimAspect->ArrowAspect()->Length();
- // This is not realy correct way to get viewer scale.
- double aViewerScale = (double) SketcherPrs_Tools::getDefaultArrowSize() / anArrowLength;
-
- if(theTextSize > ((theDimValue - 3 * SketcherPrs_Tools::getArrowSize()) * aViewerScale)) {
+ if (theLocationType == SketcherPrs_Tools::LOCATION_AUTOMATIC) {
+ double anArrowLength = theDimAspect->ArrowAspect()->Length();
+ // This is not realy correct way to get viewer scale.
+ double aViewerScale = (double) SketcherPrs_Tools::getDefaultArrowSize() / anArrowLength;
+
+ if(theTextSize > ((theDimValue - 3 * SketcherPrs_Tools::getArrowSize()) * aViewerScale)) {
+ theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Left);
+ theDimAspect->SetArrowOrientation(Prs3d_DAO_External);
+ theDimAspect->SetExtensionSize(
+ (theTextSize / aViewerScale + SketcherPrs_Tools::getArrowSize()) / 2.0);
+ } else {
+ theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Center);
+ theDimAspect->SetArrowOrientation(Prs3d_DAO_Internal);
+ }
+ }
+ else if (theLocationType == SketcherPrs_Tools::LOCATION_RIGHT ||
+ theLocationType == SketcherPrs_Tools::LOCATION_LEFT) {
theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Left);
+ //theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Right);
theDimAspect->SetArrowOrientation(Prs3d_DAO_External);
- theDimAspect->SetExtensionSize(
- (theTextSize / aViewerScale + SketcherPrs_Tools::getArrowSize()) / 2.0);
- } else {
- theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Center);
- theDimAspect->SetArrowOrientation(Prs3d_DAO_Internal);
}
+
theDimAspect->SetArrowTailSize(theDimAspect->ArrowAspect()->Length());
// The value of vertical aligment is sometimes changed
theDimAspect->TextAspect()->SetVerticalJustification(Graphic3d_VTA_CENTER);
double aTextSize = 0.0;
GetValueString(aTextSize);
- updateArrows(DimensionAspect(), GetValue(), aTextSize);
+ SketcherPrs_Tools::LocationType aLocationType = SketcherPrs_Tools::LOCATION_AUTOMATIC;
+ std::string aLocationAttribute;
+ if (myConstraint->getKind() == SketchPlugin_ConstraintLength::ID())
+ aLocationAttribute = SketchPlugin_ConstraintLength::LOCATION_TYPE_ID();
+ if (!aLocationAttribute.empty())
+ {
+ std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
+ ModelAPI_AttributeInteger>(myConstraint->data()->attribute(aLocationAttribute));
+ aLocationType = (SketcherPrs_Tools::LocationType)(aTypeAttr->value());
+ }
+ updateArrows(DimensionAspect(), GetValue(), aTextSize, aLocationType);
// Update text visualization: parameter value or parameter text
myStyleListener->updateDimensions(this, myValue);
/// \param theDimValue an arrow value
/// \param theTextSize an arrow value
extern void updateArrows(Handle_Prs3d_DimensionAspect theDimAspect,
- double theDimValue, double theTextSize);
+ double theDimValue, double theTextSize, SketcherPrs_Tools::LocationType theLocationType);
static const gp_Circ MyDefCirc(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), 1);
// Update variable aspect parameters (depending on viewer scale)
double aTextSize = 0.0;
GetValueString(aTextSize);
- updateArrows(DimensionAspect(), GetValue(), aTextSize);
+ updateArrows(DimensionAspect(), GetValue(), aTextSize, SketcherPrs_Tools::LOCATION_AUTOMATIC);
AIS_RadiusDimension::Compute(thePresentationManager, thePresentation, theMode);
ANGLE_BACKWARD ///< Angle from the second line to the first line
};
+ /// Type of dimension location
+ enum LocationType{
+ LOCATION_RIGHT, ///< Position is marked by right arrow placed on the left
+ LOCATION_AUTOMATIC, ///< Position is marked by two arrow placed on the both sides
+ LOCATION_LEFT ///< Position is marked by left arrow placed on the left
+ };
+
/// Event ID about expression visual state has been changed, the symbol with a digit
/// or parameter text is shown
}
bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes,
- bool theUpdateViewer)
+ const Standard_Integer theDisplayMode, bool theUpdateViewer)
{
bool aDisplayed = false;
Handle(AIS_InteractiveContext) aContext = AISContext();
Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
if (!aContext.IsNull() && !anAISIO.IsNull()) {
- aContext->Display(anAISIO, 0/*wireframe*/, 0, false/*update viewer*/, true, AIS_DS_Displayed);
+ aContext->Display(anAISIO, theDisplayMode, 0, false/*update viewer*/, true, AIS_DS_Displayed);
#ifdef TINSPECTOR
if (getCallBack()) getCallBack()->Display(anAISIO);
#endif
/// \param theAIS AIOS object to display
/// \param toActivateInSelectionModes boolean value whether the presentation should be
/// activated in the current selection modes
+ /// \param theDisplayMode mode how the presentation should be displayed
/// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
/// \return true if the object visibility state is changed
bool displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes,
- bool theUpdateViewer = true);
+ const Standard_Integer theDisplayMode = 0, bool theUpdateViewer = true);
/// Redisplay the shape if it was displayed
/// \param theObject an object instance
}
if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
- QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
+ QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
aNestedActList << anAction;
}
}
}
if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
- QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
+ QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
aNestedActList << anAction;
}
anAction = aSalomeConnector->addFeatureOfNested(theWchName.c_str(), aFeatureInfo,
return isStarted;
}
-bool XGUI_OperationMgr::abortAllOperations()
+bool XGUI_OperationMgr::abortAllOperations(const XGUI_MessageKind& theMessageKind)
{
bool aResult = true;
if(!hasOperation())
if (operationsCount() == 1) {
ModuleBase_Operation* aCurrentOperation = currentOperation();
- if (canStopOperation(aCurrentOperation)) {
+ if (canStopOperation(aCurrentOperation, theMessageKind)) {
abortOperation(aCurrentOperation);
}
else
aResult = false;
}
else {
- aResult = QMessageBox::question(qApp->activeWindow(),
- tr("Abort operation"),
- tr("All active operations will be aborted."),
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Cancel) == QMessageBox::Ok;
+ if (theMessageKind == XGUI_AbortOperationMessage) {
+ aResult = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ tr("All active operations will be aborted."),
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel) == QMessageBox::Ok;
+ }
+ else if (theMessageKind == XGUI_InformationMessage) {
+ QString aMessage = tr("Please validate all your active operations before saving.");
+ QMessageBox::question(qApp->activeWindow(),
+ tr("Validate operation"),
+ aMessage,
+ QMessageBox::Ok,
+ QMessageBox::Ok);
+ aResult = false; // do not perform abort
+ }
while(aResult && hasOperation()) {
abortOperation(currentOperation());
}
while (hasOperation()) {
ModuleBase_Operation* anOperation = currentOperation();
if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
- anOperationProcessed = onCommitOperation();
+ anOperationProcessed = commitOperation();
} else {
abortOperation(anOperation);
anOperationProcessed = true;
onValidateOperation();
}
-bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
+void XGUI_OperationMgr::updateOperationByUndoRedo()
+{
+ ModuleBase_IModule* aModule = myWorkshop->module();
+ if (aModule)
+ aModule->updateOperationByUndoRedo();
+}
+
+bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation,
+ const XGUI_OperationMgr::XGUI_MessageKind& theMessageKind)
{
//in case of nested (sketch) operation no confirmation needed
if (isGrantedOperation(theOperation->id()))
return true;
if (theOperation && theOperation->isModified()) {
- QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
- int anAnswer = QMessageBox::question(qApp->activeWindow(),
- tr("Abort operation"),
- aMessage,
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Cancel);
- return anAnswer == QMessageBox::Ok;
+ if (theMessageKind == XGUI_AbortOperationMessage) {
+ QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
+ int anAnswer = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ aMessage,
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+ return anAnswer == QMessageBox::Ok;
+ }
+ else if (theMessageKind == XGUI_InformationMessage) {
+ QString aMessage = tr("Please validate your %1 before saving.").arg(theOperation->id());
+ QMessageBox::question(qApp->activeWindow(),
+ tr("Validate operation"),
+ aMessage,
+ QMessageBox::Ok,
+ QMessageBox::Ok);
+ return false;
+ }
}
return true;
}
-bool XGUI_OperationMgr::commitOperation()
-{
- //if (hasOperation() && currentOperation()->isValid()) {
- // onCommitOperation();
- // return true;
- //}
- //return false;
- return onCommitOperation();
-}
-
void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
{
theOperation->resume();
}
}
-bool XGUI_OperationMgr::onCommitOperation()
+bool XGUI_OperationMgr::commitOperation()
{
bool isCommitted = false;
ModuleBase_Operation* anOperation = currentOperation();
}
}
+void XGUI_OperationMgr::onAbortAllOperation()
+{
+ abortAllOperations();
+}
+
void XGUI_OperationMgr::onBeforeOperationStarted()
{
ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
class XGUI_EXPORT XGUI_OperationMgr : public QObject
{
Q_OBJECT
- public:
+public:
+ /// Enumeration of kind of message that is used when trying to stop the active operation
+ enum XGUI_MessageKind
+ {
+ XGUI_AbortOperationMessage, //< warns and give possibility to abort current operation
+ XGUI_InformationMessage //< ask to apply the current operation before performing something
+ };
+
+public:
/// Constructor
/// \param theParent the parent
/// \param theWorkshop a reference to workshop
/// Returns true if the operation can be aborted. If the operation is modified,
/// the warning message box is shown.
/// \param theOperation an operation which is checked on stop
- bool canStopOperation(ModuleBase_Operation* theOperation);
+ /// \param theMessageKind a kind of message in warning message box
+ bool canStopOperation(ModuleBase_Operation* theOperation,
+ const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
/// Find and return operation by its Id.
ModuleBase_Operation* findOperation(const QString& theId) const;
/// \param theOperation an aborted operation
void abortOperation(ModuleBase_Operation* theOperation);
- /// Slot that commits the current operation.
- bool onCommitOperation();
+ /// Abort all operations
+ /// \param theMessageKind kind of shown warning message
+ bool abortAllOperations(const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
+
+ /// Commits the current operation.
+ bool commitOperation();
/// Returns true if SHIFT is pressed
/// \param thePressed new boolean state
public slots:
/// Slot that aborts the current operation.
void onAbortOperation();
+ /// Slot that aborts all operations. It shows aborting message
+ void onAbortAllOperation();
/// Slot that validates the current operation using the validateOperation method.
void onValidateOperation();
/// Commit all operations
bool commitAllOperations();
- /// Abort all operations
- bool abortAllOperations();
signals:
/// Signal about an operation is stopped. It is emitted after the stop() of operation is done.
/// \param theOperation the sent operation. If it is NULL, all operations in the stack are sent.
void updateApplyOfOperations(ModuleBase_Operation* theOperation = 0);
- /// Commits the current operatin if it is valid
- bool commitOperation();
+ /// Updates the current operation state after undo/redo actions calling
+ void updateOperationByUndoRedo();
protected: // TEMPORARY
/// Sets the current operation or NULL
XGUI_Workshop* workshop(ModuleBase_IWorkshop* theWorkshop)
{
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
- return aConnector->workshop();
+ return aConnector ? aConnector->workshop() : 0;
}
}
(anOperationMgr->currentOperation());
if (aFOperation) {
//if (errorMgr()->canProcessClick(anAction, aFOperation->feature()))
- myOperationMgr->onCommitOperation();
+ myOperationMgr->commitOperation();
}
}
}
//******************************************************
bool XGUI_Workshop::onSave()
{
- if(!abortAllOperations())
+ if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
return false;
if (myCurrentDir.isEmpty()) {
return onSaveAs();
//******************************************************
bool XGUI_Workshop::onSaveAs()
{
- if(!abortAllOperations())
+ if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
return false;
QFileDialog dialog(desktop());
dialog.setWindowTitle(tr("Select directory to save files..."));
}
operationMgr()->updateApplyOfOperations();
+ operationMgr()->updateOperationByUndoRedo();
updateCommandStatus();
}
myObjectBrowser->rebuildDataTree();
}
operationMgr()->updateApplyOfOperations();
+ operationMgr()->updateOperationByUndoRedo();
updateCommandStatus();
// unblock the viewer update functionality and make update on purpose
MyTCommunicator->RegisterPlugin("TKDFBrowser");
MyTCommunicator->RegisterPlugin("TKShapeView");
MyTCommunicator->RegisterPlugin("TKVInspector");
- MyTCommunicator->RegisterPlugin("SMBrowser"); // custom plugin to view ModelAPI
+ MyTCommunicator->RegisterPlugin("TKSMBrowser"); // custom plugin to view ModelAPI
MyTCommunicator->Init(aParameters);
- MyTCommunicator->Activate("SMBrowser"); // to have button in TInspector
+ MyTCommunicator->Activate("TKSMBrowser"); // to have button in TInspector
MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
MyTCommunicator->Activate("TKDFBrowser");
}