X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherReentrantMgr.cpp;h=5dfd5a26ffdcead2416ca5dab32e7c9a41104dff;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=cab4e9945363d6912af1c7045d259d88ef00109a;hpb=a2ab2dc339b560c7309540e1f10b6ad60e5ed0af;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherReentrantMgr.cpp b/src/PartSet/PartSet_SketcherReentrantMgr.cpp index cab4e9945..5dfd5a26f 100644 --- a/src/PartSet/PartSet_SketcherReentrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReentrantMgr.cpp @@ -1,6 +1,24 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "PartSet_SketcherReentrantMgr.h" +#include "PartSet_ExternalObjectsMgr.h" #include "PartSet_Module.h" #include "PartSet_SketcherMgr.h" #include "PartSet_WidgetPoint2d.h" @@ -8,10 +26,16 @@ #include "ModelAPI_Session.h" #include "ModelAPI_AttributeString.h" #include "ModelAPI_AttributeRefAttr.h" +#include "ModelAPI_AttributeReference.h" +#include "ModelAPI_EventReentrantMessage.h" #include "GeomDataAPI_Point2D.h" +#include "GeomAPI_Lin2d.h" +#include "GeomAPI_Dir2d.h" + #include +#include #include #include #include @@ -28,6 +52,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -38,15 +66,17 @@ #include +//#define DEBUG_RESTART + PartSet_SketcherReentrantMgr::PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* theWorkshop) : QObject(theWorkshop), myWorkshop(theWorkshop), myRestartingMode(RM_None), myIsFlagsBlocked(false), myIsInternalEditOperation(false), - myIsValueChangedBlocked(false), - myInternalActiveWidget(0), - myNoMoreWidgetsAttribute("") + myNoMoreWidgetsAttribute(""), + myIsAutoConstraints(true), + myLastAutoConstraint(0) { } @@ -54,24 +84,6 @@ PartSet_SketcherReentrantMgr::~PartSet_SketcherReentrantMgr() { } -ModuleBase_ModelWidget* PartSet_SketcherReentrantMgr::internalActiveWidget() const -{ - ModuleBase_ModelWidget* aWidget = 0; - if (!isActiveMgr()) - return aWidget; - - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (anOperation) { - ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel(); - if (aPanel) { // check for case when the operation is started but property panel is not filled - ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); - if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector())) - aWidget = myInternalActiveWidget; - } - } - return aWidget; -} - bool PartSet_SketcherReentrantMgr::isInternalEditActive() const { return myIsInternalEditOperation; @@ -114,12 +126,13 @@ void PartSet_SketcherReentrantMgr::operationStarted(ModuleBase_Operation* theOpe if (!isActiveMgr()) return; - if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) { - ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast( - myWorkshop->currentOperation()); - CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); - copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch); - } + //if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) { + //ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast( + // myWorkshop->currentOperation()); + //CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); + //if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed + //copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch); + //} resetFlags(); } @@ -148,17 +161,16 @@ bool PartSet_SketcherReentrantMgr::processMouseMoved(ModuleBase_IViewWindow* the ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel(); FeaturePtr aCurrentFeature = aFOperation->feature(); - bool isLineFeature = false, isArcFeature = false; + bool isLineFeature = false, isReentrantArcFeature = false; std::string anAttributeOnStart; if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) { anAttributeOnStart = SketchPlugin_Line::START_ID(); isLineFeature = anActiveWidget->attributeID() == anAttributeOnStart; } else if (isTangentArc(aFOperation, module()->sketchMgr()->activeSketch())) { - anAttributeOnStart = SketchPlugin_MacroArc::TANGENT_POINT_ID(); - isArcFeature = anActiveWidget->attributeID() == anAttributeOnStart; + isReentrantArcFeature = true; } - bool aCanBeActivatedByMove = isLineFeature || isArcFeature; + bool aCanBeActivatedByMove = isLineFeature || isReentrantArcFeature; if (aCanBeActivatedByMove) { /// before restarting of operation we need to clear selection, as it may take part in /// new feature creation, e.g. tangent arc. But it is not necessary as it was processed @@ -170,16 +182,15 @@ bool PartSet_SketcherReentrantMgr::processMouseMoved(ModuleBase_IViewWindow* the myPreviousFeature = FeaturePtr(); anActiveWidget = module()->activeWidget(); - aCurrentFeature = anActiveWidget->feature(); aProcessed = true; - if (anActiveWidget->attributeID() == anAttributeOnStart) { + if (anActiveWidget && anActiveWidget->attributeID() == anAttributeOnStart) { // it was not deactivated by preselection processing aPanel->activateNextWidget(anActiveWidget); } } else { // processing mouse move in active widget of restarted operation - ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget(); - PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); + ModuleBase_ModelWidget* anActiveWdg = module()->activeWidget(); + PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWdg); if (aProcessor) aProcessor->mouseMoved(theWnd, theEvent); } @@ -194,8 +205,8 @@ bool PartSet_SketcherReentrantMgr::processMousePressed(ModuleBase_IViewWindow* / return isActiveMgr() && myIsInternalEditOperation; } -bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWnd, - QMouseEvent* theEvent) +bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWindow, + QMouseEvent* theEvent) { bool aProcessed = false; if (!isActiveMgr()) @@ -228,7 +239,38 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* QList aPreSelected = aSelection->getSelected(ModuleBase_ISelection::AllControls); + myClickedSketchPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, + module()->sketchMgr()->activeSketch()); + FeaturePtr anExternalCreatedFeature; + if (!aPreSelected.empty()) { + ModuleBase_ViewerPrsPtr aValue = aPreSelected.first(); + module()->getGeomSelection(aValue, mySelectedObject, mySelectedAttribute); + + PartSet_WidgetPoint2D* aPointWidget = dynamic_cast(anActiveWidget); + if (aPointWidget) { + GeomShapePtr aShape; + aPointWidget->getGeomSelection_(aValue, mySelectedObject, aShape); + ObjectPtr anExternalObject = + aPointWidget->getExternalObjectMgr()->getExternalObjectValidated(); + // if external object is during reentrant operation and is used as a parameter of feature + // it should be removed after the operation is restarted. (Circle feature, Projection) + if (anExternalObject.get()) + anExternalCreatedFeature = ModelAPI_Feature::feature(anExternalObject); + } + } + restartOperation(); + // remove created external feature + if (anExternalCreatedFeature.get()) { + QObjectPtrList anObjects; + anObjects.append(anExternalCreatedFeature); + workshop()->deleteFeatures(anObjects); + } + + myClickedSketchPoint = std::shared_ptr(); + mySelectedObject = ObjectPtr(); + mySelectedAttribute = AttributePtr(); + myPreviousFeature = FeaturePtr(); aProcessed = true; @@ -246,8 +288,14 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* std::shared_ptr aSelectedPrs; if (!aPreSelected.empty()) aSelectedPrs = aPreSelected.front(); - aMouseProcessor->setPreSelection(aSelectedPrs, theWnd, theEvent); - //aPoint2DWdg->mouseReleased(theWnd, theEvent); + if (aSelectedPrs.get() && aSelectedPrs->object().get() + && !aSelectedPrs->object()->data()->isValid()) { + // the selected object was removed diring restart, e.g. presentable macro feature + // there are created objects to replace the object depending on created feature kind + aSelectedPrs = std::shared_ptr(); + } + aMouseProcessor->setPreSelection(aSelectedPrs, theWindow, theEvent); + //aPoint2DWdg->mouseReleased(theWindow, theEvent); //if (!aPreSelected.empty()) // aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr()); } @@ -255,29 +303,51 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* ModuleBase_Tools::blockUpdateViewer(false); } } - return aProcessed; } -void PartSet_SketcherReentrantMgr::onWidgetActivated() +//****************************************************** +void PartSet_SketcherReentrantMgr::setReentrantPreSelection( + const std::shared_ptr& theMessage) { - if (!isActiveMgr()) - return; - if (!myIsInternalEditOperation) + ReentrantMessagePtr aReentrantMessage = + std::dynamic_pointer_cast(theMessage); + if (!aReentrantMessage.get()) return; - PartSet_Module* aModule = module(); - ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget(); - ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel(); - if (aFirstWidget != aPanel->activeWidget()) { - ModuleBase_WidgetSelector* aWSelector = dynamic_cast(aFirstWidget); - if (aWSelector) - aWSelector->activateSelectionAndFilters(true); - } + // if feature has already filled the selected object, we should not overwrite it + if (!aReentrantMessage->selectedObject().get()) + aReentrantMessage->setSelectedObject(mySelectedObject); + + aReentrantMessage->setSelectedAttribute(mySelectedAttribute); + aReentrantMessage->setClickedPoint(myClickedSketchPoint); } +//void PartSet_SketcherReentrantMgr::onWidgetActivated() +//{ +// if (!isActiveMgr()) +// return; +// if (!myIsInternalEditOperation) +// return; +// +// PartSet_Module* aModule = module(); +// ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget(); +// ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel(); +// if (aFirstWidget != aPanel->activeWidget()) { +// ModuleBase_WidgetSelector* aWSelector = dynamic_cast +// (aFirstWidget); +// if (aWSelector) { +// myWorkshop->selectionActivate()->updateSelectionModesAndFilters(aWSelector); +// } +// } +//} + void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID) { +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::onNoMoreWidgets" << std::endl; +#endif + if (!isActiveMgr()) return; @@ -292,19 +362,32 @@ void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviou ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); + if (module()->sketchMgr()->isDragModeCreation()) { + if (aFOperation && myIsAutoConstraints) + addConstraints(aFOperation->feature()); + return; + } if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) return; if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) { - bool isStarted = false; - if (!module()->sketchMgr()->sketchSolverError()) { - if (myRestartingMode != RM_Forbided) { - myRestartingMode = RM_LastFeatureUsed; - isStarted = startInternalEdit(thePreviousAttributeID); + if (aFOperation->isNeedToBeAborted()) { + aFOperation->abort(); + } + else { + bool isStarted = false; + if (!module()->sketchMgr()->sketchSolverError()) { + if (myRestartingMode != RM_Forbided) { + myRestartingMode = RM_LastFeatureUsed; + isStarted = startInternalEdit(thePreviousAttributeID); + } + } + if (!isStarted) { + if (myIsAutoConstraints) + addConstraints(aFOperation->feature()); + aFOperation->commit(); } } - if (!isStarted) - aFOperation->commit(); } } @@ -329,7 +412,9 @@ bool PartSet_SketcherReentrantMgr::processEnter(const std::string& thePreviousAt if (!isSketchSolverError) { myRestartingMode = RM_EmptyFeatureUsed; - isDone = startInternalEdit(thePreviousAttributeID); + // It seems that the call is obsolete for Enter key processing + // It prevent finalysing of the current operation by Enter key + //isDone = startInternalEdit(thePreviousAttributeID); } return isDone; @@ -364,14 +449,9 @@ void PartSet_SketcherReentrantMgr::onVertexSelected() void PartSet_SketcherReentrantMgr::onAfterValuesChangedInPropertyPanel() { - // blocked flag in order to avoid circling when storeValue will be applied in - // this method to cached widget - if (myIsValueChangedBlocked) - return; - if (isInternalEditActive()) { ModuleBase_ModelWidget* aWidget = (ModuleBase_ModelWidget*)sender(); - if (!aWidget->isModifiedInEdit()) + if (!aWidget->isModifiedInEdit().empty()) restartOperation(); } } @@ -389,11 +469,6 @@ bool PartSet_SketcherReentrantMgr::canBeCommittedByPreselection() return !isActiveMgr() || myRestartingMode == RM_None; } -bool PartSet_SketcherReentrantMgr::isInternalEditStarted() const -{ - return myIsInternalEditOperation; -} - bool PartSet_SketcherReentrantMgr::isActiveMgr() const { ModuleBase_Operation* aCurrentOperation = myWorkshop->currentOperation(); @@ -413,6 +488,10 @@ bool PartSet_SketcherReentrantMgr::isActiveMgr() const bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePreviousAttributeID) { +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::startInternalEdit" << std::endl; +#endif + bool isDone = false; /// this is workaround for ModuleBase_WidgetEditor, used in SALOME mode. Sometimes key enter /// event comes two times, so we should not start another internal edit operation @@ -424,6 +503,13 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi (myWorkshop->currentOperation()); if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) { + /// improvement to deselect automatically all eventual selected objects, when + // returning to the neutral point of the Sketcher or start internal edit + workshop()->selector()->clearSelection(); + + if (myIsAutoConstraints) + addConstraints(aFOperation->feature()); + aFOperation->setEditOperation(true/*, false*/); createInternalFeature(); @@ -435,7 +521,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi connect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped())); // activate selection filters of the first widget in the viewer - onWidgetActivated(); + //onWidgetActivated(); // activate the last active widget in the Property Panel if (!thePreviousAttributeID.empty()) { @@ -446,9 +532,9 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi QList aWidgets = aPanel->modelWidgets(); for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) { if (aWidgets[i]->attributeID() == thePreviousAttributeID) { - /// workaround for the same attributes used in different stacked widgets(attribute types) - if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i])) - continue; + // workaround for the same attributes used in different stacked widgets(attribute types) + if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i])) + continue; aPreviousAttributeWidget = aWidgets[i]; } } @@ -456,6 +542,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi if (aPreviousAttributeWidget) { if (!aPreviousAttributeWidget->isViewerSelector()) { aPreviousAttributeWidget->focusTo(); + aPreviousAttributeWidget->emitFocusInWidget(); aPreviousAttributeWidget->selectContent(); } else { @@ -472,7 +559,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi QToolButton* anOkBtn = dynamic_cast(aPanel)->findButton(PROP_PANEL_OK); if (anOkBtn) - anOkBtn->setFocus(Qt::TabFocusReason); + ModuleBase_Tools::setFocus(anOkBtn, "XGUI_PropertyPanel::activateNextWidget"); } } } @@ -498,32 +585,31 @@ void PartSet_SketcherReentrantMgr::beforeStopInternalEdit() void PartSet_SketcherReentrantMgr::restartOperation() { +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::restartOperation" << std::endl; +#endif + if (myIsInternalEditOperation) { ModuleBase_OperationFeature* aFOperation = dynamic_cast( myWorkshop->currentOperation()); if (aFOperation) { - // obtain widgets(attributes) which content should be applied to attributes of new feature - ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); - ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); - const QList& aWidgets = aPanel->modelWidgets(); - QList aValueWidgets; - for (int i = 0, aSize = aWidgets.size(); i < aSize; i++) { - ModuleBase_ModelWidget* aWidget = aWidgets[i]; - if (!aWidget->isModifiedInEdit()) { - aValueWidgets.append(aWidget); - // the widget is cashed to fill feature of new operation by the current widget value - // we set empty parent to the widget in order to remove it ourselves. Reason: restart - // operation will clear property panel and delete all widgets. This widget should be - // removed only after applying value of the widget to new created feature. - aWidget->setParent(0); - } - } + ModuleBase_ISelection* aSelection = myWorkshop->selection(); + QList aPreSelected = + aSelection->getSelected(ModuleBase_ISelection::AllControls); + + if (myInternalFeature.get()) + copyReetntrantAttributes(myInternalFeature, aFOperation->feature(), + module()->sketchMgr()->activeSketch()); myNoMoreWidgetsAttribute = ""; myIsFlagsBlocked = true; - module()->launchOperation(aFOperation->id()); + /// launch has 'false' parameter to do not start new operation if the previous operation + /// is not committed. It is important for Line Sketch feature as it uses the previous + /// created feature parameter(to build coincidence), but by abort the previous is removed + module()->launchOperation(aFOperation->id(), true); myIsFlagsBlocked = false; resetFlags(); + // we should avoid processing of the signal about no more widgets attributes and // do this after the restart operaion is finished if it was called // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute @@ -532,21 +618,6 @@ void PartSet_SketcherReentrantMgr::restartOperation() onNoMoreWidgets(myNoMoreWidgetsAttribute); myNoMoreWidgetsAttribute = ""; } - - // filling new feature by the previous value of active widget - // (e.g. circle_type in macro Circle) - ModuleBase_OperationFeature* aFOperation = dynamic_cast( - myWorkshop->currentOperation()); - myIsValueChangedBlocked = true; // flag to avoid onAfterValuesChangedInPropertyPanel slot - for (int i = 0, aSize = aValueWidgets.size(); i < aSize; i++) { - ModuleBase_ModelWidget* aWidget = aValueWidgets[i]; - aWidget->setEditingMode(false); - aWidget->setFeature(aFOperation->feature()); - aWidget->storeValue(); - // we must delete this widget - delete aWidget; - } - myIsValueChangedBlocked = false; } } } @@ -562,6 +633,11 @@ void PartSet_SketcherReentrantMgr::createInternalFeature() CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); myInternalFeature = aSketch->addFeature(anOperationFeature->getKind()); +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::createInternalFeature: " + << myInternalFeature->data()->name() << std::endl; +#endif + bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature, aSketch, false); XGUI_PropertyPanel* aPropertyPanel = dynamic_cast @@ -590,19 +666,17 @@ void PartSet_SketcherReentrantMgr::createInternalFeature() ModuleBase_ModelWidget* aFirstWidget = ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget (aWidgets); if (aFirstWidget) - myInternalActiveWidget = aFirstWidget; + setInternalActiveWidget(aFirstWidget); } } void PartSet_SketcherReentrantMgr::deleteInternalFeature() { - if (myInternalActiveWidget) { - ModuleBase_WidgetSelector* aWSelector = - dynamic_cast(myInternalActiveWidget); - if (aWSelector) - aWSelector->activateSelectionAndFilters(false); - myInternalActiveWidget = 0; - } +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::deleteInternalFeature: " + << myInternalFeature->data()->name() << std::endl; +#endif + setInternalActiveWidget(0); delete myInternalWidget; myInternalWidget = 0; @@ -618,21 +692,28 @@ void PartSet_SketcherReentrantMgr::resetFlags() myIsInternalEditOperation = false; updateAcceptAllAction(); myRestartingMode = RM_None; + myReentrantMessage = std::shared_ptr(); } } bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature, const FeaturePtr& theNewFeature, const CompositeFeaturePtr& theSketch, - const bool isTemporary) + const bool /*isTemporary*/) { bool aChanged = false; if (!theSourceFeature.get() || !theSourceFeature->data().get() || !theSourceFeature->data()->isValid()) return aChanged; +#ifdef DEBUG_RESTART + std::cout << "PartSet_SketcherReentrantMgr::copyReetntrantAttributes from '" + << theSourceFeature->data()->name() << "' to '" << theNewFeature->data()->name() + << "'" << std::endl; +#endif + std::string aFeatureKind = theSourceFeature->getKind(); - if (aFeatureKind == SketchPlugin_Line::ID()) { + /*if (aFeatureKind == SketchPlugin_Line::ID()) { // Initialize new line with first point equal to end of previous std::shared_ptr aSFData = theSourceFeature->data(); std::shared_ptr aSPoint = std::dynamic_pointer_cast( @@ -647,22 +728,23 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th aSFData->attribute(SketchPlugin_Line::END_ID())); aNPoint->setValue(aSPoint->x(), aSPoint->y()); } - else if (aFeatureKind == SketchPlugin_MacroCircle::ID()) { + else*/ if (aFeatureKind == SketchPlugin_MacroCircle::ID()) { // set circle type - std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE(); + /*std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE(); AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId); AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); - aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); - //ModuleBase_Tools::flushUpdated(theNewFeature); - aChanged = true; + if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes + aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); + //ModuleBase_Tools::flushUpdated(theNewFeature);*/ + //aChanged = true; } else if (aFeatureKind == SketchPlugin_MacroArc::ID()) { // set arc type - std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE(); + /*std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE(); AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId); AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); - aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); - + if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes + aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());*/ //// if the arc is tangent, set coincidence to end point of the previous arc //std::string anArcType = aSourceFeatureTypeAttr->value(); //if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) { @@ -683,7 +765,28 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th //} //ModuleBase_Tools::flushUpdated(theNewFeature); - aChanged = true; + //aChanged = true; + } + else if (aFeatureKind == SketchPlugin_Trim::ID() || + aFeatureKind == SketchPlugin_Split::ID()) { + std::string aPreviewObjectAttribute = aFeatureKind == SketchPlugin_Trim::ID() ? + SketchPlugin_Trim::PREVIEW_OBJECT(): SketchPlugin_Split::PREVIEW_OBJECT(); + std::string aPreviewPointAttribute = aFeatureKind == SketchPlugin_Trim::ID() ? + SketchPlugin_Trim::PREVIEW_POINT(): SketchPlugin_Split::PREVIEW_POINT(); + std::shared_ptr aRefPreviewAttr = + std::dynamic_pointer_cast( + theSourceFeature->data()->attribute(aPreviewObjectAttribute)); + std::shared_ptr aNRefPreviewAttr = + std::dynamic_pointer_cast( + theNewFeature->data()->attribute(aPreviewObjectAttribute)); + aNRefPreviewAttr->setValue(aRefPreviewAttr->value()); + std::shared_ptr aPointPreviewAttr = + std::dynamic_pointer_cast( + theSourceFeature->data()->attribute(aPreviewPointAttribute)); + std::shared_ptr aNPointPreviewAttr = + std::dynamic_pointer_cast( + theNewFeature->data()->attribute(aPreviewPointAttribute)); + aNPointPreviewAttr->setValue(aPointPreviewAttr->x(), aPointPreviewAttr->y()); } return aChanged; } @@ -722,3 +825,69 @@ PartSet_Module* PartSet_SketcherReentrantMgr::module() const { return dynamic_cast(myWorkshop->module()); } + +void PartSet_SketcherReentrantMgr::setInternalActiveWidget(ModuleBase_ModelWidget* theWidget) +{ + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (myWorkshop->currentOperation()); + if (aFOperation) + { + XGUI_PropertyPanel* aPropertyPanel = dynamic_cast + (aFOperation->propertyPanel()); + if (aPropertyPanel) + aPropertyPanel->setInternalActiveWidget(theWidget); + } +} + +void PartSet_SketcherReentrantMgr::onAutoConstraints(bool isOn) +{ + myIsAutoConstraints = isOn; +} + +void PartSet_SketcherReentrantMgr::addConstraints(const FeaturePtr& theFeature) +{ + if (theFeature->getKind() != SketchPlugin_Line::ID()) + return; + + static GeomDir2dPtr myHorDir(new GeomAPI_Dir2d(1, 0)); + static GeomDir2dPtr myVertDir(new GeomAPI_Dir2d(0, 1)); + + std::shared_ptr aData = theFeature->data(); + std::shared_ptr aPoint1 = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPoint2 = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::END_ID())); + if (aPoint1.get() && aPoint2.get()) { + GeomLine2dPtr aLine(new GeomAPI_Lin2d(aPoint1->pnt(), aPoint2->pnt())); + GeomDir2dPtr aDir = aLine->direction(); + double aHorAngle = fabs(myHorDir->angle(aDir)); + double aVertAngle = fabs(myVertDir->angle(aDir)); + if (aHorAngle > M_PI/2.) + aHorAngle = M_PI - aHorAngle; + if (aVertAngle > M_PI/2.) + aVertAngle = M_PI - aVertAngle; + + double aTolerance = Config_PropManager::real(SKETCH_TAB_NAME, "angular_tolerance"); + CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); + FeaturePtr aFeature; + if (aHorAngle < aTolerance) { + // Add horizontal constraint + aFeature = aSketch->addFeature(SketchPlugin_ConstraintHorizontal::ID()); + } + else if (aVertAngle < aTolerance) { + // Add vertical constraint + aFeature = aSketch->addFeature(SketchPlugin_ConstraintVertical::ID()); + } + if (aFeature.get()) { + aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->setObject( + theFeature->firstResult()); + myLastAutoConstraint = aFeature.get(); + } + } +} + + +bool PartSet_SketcherReentrantMgr::isLastAutoConstraint(const ObjectPtr& theObj) const +{ + return theObj.get() == myLastAutoConstraint; +}