From a6057974b4d248ec8c3c2d162e1ff49b8f9ceb51 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 1 Mar 2017 12:42:23 +0300 Subject: [PATCH] Issue #2027 Sketcher Trim Feature: split shapes by highlighted point is moved from GUI to Trim feature. Reasons: it is enough to have only two point attributes in trim feature(without references attributes) and a reference attribute for trimmed feature; cash of bounding boxes(later) should be placed in one place, it will be trim feature. --- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp | 83 +- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h | 10 +- src/PartSet/CMakeLists.txt | 44 +- src/PartSet/PartSet_Module.cpp | 7 + src/PartSet/PartSet_MouseProcessor.h | 8 + src/PartSet/PartSet_SketcherReetntrantMgr.cpp | 22 +- .../PartSet_WidgetFeaturePointSelector.cpp | 437 +++ .../PartSet_WidgetFeaturePointSelector.h | 155 + src/PartSet/PartSet_WidgetPoint2d.cpp | 6 +- src/PartSet/PartSet_WidgetPoint2d.h | 7 +- .../PartSet_WidgetSubShapeSelector.cpp | 32 +- src/PartSet/PartSet_WidgetSubShapeSelector.h | 4 +- src/SketchPlugin/SketchPlugin_Trim.cpp | 2670 +++++++++-------- src/SketchPlugin/SketchPlugin_Trim.h | 425 +-- src/SketchPlugin/SketchPlugin_Validators.cpp | 3 +- src/SketchPlugin/plugin-Sketch.xml | 4 +- src/XGUI/XGUI_Displayer.cpp | 2 +- 17 files changed, 2411 insertions(+), 1508 deletions(-) create mode 100644 src/PartSet/PartSet_WidgetFeaturePointSelector.cpp create mode 100644 src/PartSet/PartSet_WidgetFeaturePointSelector.h diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index 1a245cb28..5d1a2cf74 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include @@ -121,11 +123,59 @@ namespace ModelGeomAlgo_Point2D { } } + void appendPoint(const std::shared_ptr& thePoint, + const std::shared_ptr& theResult, + std::list >& thePoints, + std::map, + std::list< std::shared_ptr > >& theObjectToPoint) + { + std::list< std::shared_ptr > anObjects; + if (theObjectToPoint.find(thePoint) != theObjectToPoint.end()) + anObjects = theObjectToPoint[thePoint]; + thePoints.push_back(thePoint); + anObjects.push_back(theResult); + theObjectToPoint[thePoint].push_back(theResult); + } + + void appendShapePoints(GeomShapePtr& theShape, + const std::shared_ptr& theResult, + std::list >& thePoints, + std::map, + std::list< std::shared_ptr > >& theObjectToPoint) + { + if (!theShape.get()) + return; + + switch (theShape->shapeType()) { + case GeomAPI_Shape::VERTEX: { + std::shared_ptr aVertex = + std::shared_ptr(new GeomAPI_Vertex(theShape)); + std::shared_ptr aPnt = aVertex->point(); + appendPoint(aPnt, theResult, thePoints, theObjectToPoint); + } + break; + case GeomAPI_Shape::EDGE: { + std::shared_ptr anEdge = + std::shared_ptr(new GeomAPI_Edge(theShape)); + appendPoint(anEdge->firstPoint(), theResult, thePoints, theObjectToPoint); + appendPoint(anEdge->lastPoint(), theResult, thePoints, theObjectToPoint); + } + break; + case GeomAPI_Shape::COMPOUND: { + for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) { + appendShapePoints(anIt.current(), theResult, thePoints, theObjectToPoint); + } + } + break; + default: break; + } + } + void getPointsIntersectedShape(const std::shared_ptr& theBaseFeature, - const std::list >& theFeatures, - std::list >& thePoints, - std::map, - std::shared_ptr >& theObjectToPoint) + const std::list >& theFeatures, + std::list >& thePoints, + std::map, + std::list< std::shared_ptr > >& theObjectToPoint) { GeomShapePtr aFeatureShape; { @@ -151,30 +201,7 @@ namespace ModelGeomAlgo_Point2D { GeomShapePtr aShape = aResult->shape(); GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape); - if (!aShapeOfIntersection.get()) - continue; - switch (aShapeOfIntersection->shapeType()) { - case GeomAPI_Shape::VERTEX: { - std::shared_ptr aVertex = - std::shared_ptr(new GeomAPI_Vertex(aShapeOfIntersection)); - std::shared_ptr aPnt = aVertex->point(); - thePoints.push_back(aPnt); - theObjectToPoint[aResult] = aPnt; - } - break; - case GeomAPI_Shape::EDGE: { - /*std::shared_ptr anEdge = - std::shared_ptr(new GeomAPI_Vertex(aShapeOfIntersection)); - std::shared_ptr aPnt = aVertex->point(); - thePoints.push_back(aPnt); - theObjectToPoint[aResult] = aPnt;*/ - } - break; - case GeomAPI_Shape::COMPOUND: { - } - break; - default: break; - } + appendShapePoints(aShapeOfIntersection, aResult, thePoints, theObjectToPoint); } } } diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h index d609a3126..b5c005bd5 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h @@ -63,11 +63,11 @@ namespace ModelGeomAlgo_Point2D { /// \param thePoints a container of 3D points belong to the shape /// \param theObjectToPoint a container of object to point MODELGEOMALGO_EXPORT void getPointsIntersectedShape( - const std::shared_ptr& theBaseFeature, - const std::list >& theFeatures, - std::list >& thePoints, - std::map, - std::shared_ptr >& theObjectToPoint); + const std::shared_ptr& theBaseFeature, + const std::list >& theFeatures, + std::list >& thePoints, + std::map, + std::list< std::shared_ptr > >& theObjectToPoint); /// Removes attributes which points are out of the base shape /// \param theBaseShape a shape of check diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index ad4506730..bb1035a06 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -14,40 +14,43 @@ SET(PROJECT_HEADERS PartSet_Constants.h PartSet_CustomPrs.h PartSet_ExternalObjectsMgr.h + PartSet_FilterInfinite.h + PartSet_Filters.h + PartSet_IconFactory.h + PartSet_MenuMgr.h PartSet_Module.h PartSet_MouseProcessor.h PartSet_OperationPrs.h PartSet_OverconstraintListener.h PartSet_PreviewPlanes.h + PartSet_ResultSketchPrs.h + PartSet_SketcherMgr.h + PartSet_SketcherReetntrantMgr.h PartSet_Tools.h - PartSet_WidgetSketchLabel.h PartSet_Validators.h - PartSet_WidgetPoint2d.h + PartSet_WidgetChoice.h PartSet_WidgetEditor.h + PartSet_WidgetFeaturePointSelector.h + PartSet_WidgetFileSelector.h PartSet_WidgetMultiSelector.h + PartSet_WidgetPoint2d.h PartSet_WidgetPoint2dDistance.h PartSet_WidgetPoint2DFlyout.h PartSet_WidgetShapeSelector.h - PartSet_WidgetFileSelector.h - PartSet_Filters.h - PartSet_FilterInfinite.h - PartSet_ResultSketchPrs.h - PartSet_SketcherMgr.h - PartSet_SketcherReetntrantMgr.h - PartSet_MenuMgr.h PartSet_WidgetSketchCreator.h - PartSet_IconFactory.h - PartSet_WidgetChoice.h + PartSet_WidgetSketchLabel.h PartSet_WidgetSubShapeSelector.h ) SET(PROJECT_MOC_HEADERS + PartSet_MenuMgr.h PartSet_Module.h PartSet_SketcherMgr.h PartSet_SketcherReetntrantMgr.h PartSet_WidgetChoice.h PartSet_WidgetEditor.h + PartSet_WidgetFeaturePointSelector.h PartSet_WidgetFileSelector.h PartSet_WidgetMultiSelector.h PartSet_WidgetPoint2d.h @@ -62,28 +65,29 @@ SET(PROJECT_MOC_HEADERS SET(PROJECT_SOURCES PartSet_CustomPrs.cpp PartSet_ExternalObjectsMgr.cpp + PartSet_FilterInfinite.cpp + PartSet_Filters.cpp + PartSet_IconFactory.cpp + PartSet_MenuMgr.cpp PartSet_Module.cpp PartSet_OperationPrs.cpp PartSet_OverconstraintListener.cpp PartSet_PreviewPlanes.cpp + PartSet_ResultSketchPrs.cpp + PartSet_SketcherMgr.cpp + PartSet_SketcherReetntrantMgr.cpp PartSet_Tools.cpp - PartSet_WidgetSketchLabel.cpp PartSet_Validators.cpp PartSet_WidgetEditor.cpp + PartSet_WidgetFeaturePointSelector.cpp + PartSet_WidgetFileSelector.cpp PartSet_WidgetMultiSelector.cpp PartSet_WidgetPoint2d.cpp PartSet_WidgetPoint2dDistance.cpp PartSet_WidgetPoint2DFlyout.cpp PartSet_WidgetShapeSelector.cpp - PartSet_WidgetFileSelector.cpp - PartSet_Filters.cpp - PartSet_FilterInfinite.cpp - PartSet_ResultSketchPrs.cpp - PartSet_SketcherMgr.cpp - PartSet_SketcherReetntrantMgr.cpp - PartSet_MenuMgr.cpp PartSet_WidgetSketchCreator.cpp - PartSet_IconFactory.cpp + PartSet_WidgetSketchLabel.cpp PartSet_WidgetSubShapeSelector.cpp ) diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 4fc3b6ab0..d441445ca 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -11,6 +11,7 @@ #include "PartSet_WidgetShapeSelector.h" #include "PartSet_WidgetMultiSelector.h" #include "PartSet_WidgetSubShapeSelector.h" +#include "PartSet_WidgetFeaturePointSelector.h" #include "PartSet_WidgetEditor.h" #include "PartSet_WidgetFileSelector.h" #include "PartSet_WidgetSketchCreator.h" @@ -744,6 +745,12 @@ ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& th aSubShapeSelectorWgt->setSketcher(mySketchMgr->activeSketch()); aWgt = aSubShapeSelectorWgt; } + else if (theType == "sketch_feature_point_selector") { + PartSet_WidgetFeaturePointSelector* aPointSelectorWgt = + new PartSet_WidgetFeaturePointSelector(theParent, aWorkshop, theWidgetApi); + aPointSelectorWgt->setSketcher(mySketchMgr->activeSketch()); + aWgt = aPointSelectorWgt; + } else if (theType == WDG_DOUBLEVALUE_EDITOR) { aWgt = new PartSet_WidgetEditor(theParent, aWorkshop, theWidgetApi); } else if (theType == "export_file_selector") { diff --git a/src/PartSet/PartSet_MouseProcessor.h b/src/PartSet/PartSet_MouseProcessor.h index 6a123df60..91f40398a 100755 --- a/src/PartSet/PartSet_MouseProcessor.h +++ b/src/PartSet/PartSet_MouseProcessor.h @@ -9,7 +9,10 @@ #include "PartSet.h" +#include + class ModuleBase_IViewWindow; +class ModuleBase_ViewerPrs; class QMouseEvent; /** @@ -39,6 +42,11 @@ public: /// \param theEvent a mouse event PARTSET_EXPORT virtual void mouseDoubleClick(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent) {} + + /// Fill preselection used in mouseReleased + virtual void setPreSelection(const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent) {} }; #endif diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp index 6f8ba11fd..3cbc1cc5d 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp @@ -233,15 +233,21 @@ bool PartSet_SketcherReetntrantMgr::processMouseReleased(ModuleBase_IViewWindow* // fill the first widget by the mouse event point // if the active widget is not the first, it means that the restarted operation is filled by // the current preselection. - PartSet_WidgetPoint2D* aPoint2DWdg = - dynamic_cast(module()->activeWidget()); - ModuleBase_ModelWidget* aFirstWidget = aPanel->findFirstAcceptingValueWidget(); - if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) { + PartSet_MouseProcessor* aMouseProcessor = dynamic_cast( + module()->activeWidget()); + //PartSet_WidgetPoint2D* aPoint2DWdg = + // dynamic_cast(module()->activeWidget()); + PartSet_MouseProcessor* aFirstWidget = dynamic_cast( + aPanel->findFirstAcceptingValueWidget()); + //if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) { + if (aMouseProcessor && aMouseProcessor == aFirstWidget) { + std::shared_ptr aSelectedPrs; if (!aPreSelected.empty()) - aPoint2DWdg->setPreSelection(aPreSelected.front()); - aPoint2DWdg->mouseReleased(theWnd, theEvent); - if (!aPreSelected.empty()) - aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr()); + aSelectedPrs = aPreSelected.front(); + aMouseProcessor->setPreSelection(aSelectedPrs, theWnd, theEvent); + //aPoint2DWdg->mouseReleased(theWnd, theEvent); + //if (!aPreSelected.empty()) + // aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr()); } // unblock viewer update ModuleBase_Tools::blockUpdateViewer(false); diff --git a/src/PartSet/PartSet_WidgetFeaturePointSelector.cpp b/src/PartSet/PartSet_WidgetFeaturePointSelector.cpp new file mode 100644 index 000000000..92c522464 --- /dev/null +++ b/src/PartSet/PartSet_WidgetFeaturePointSelector.cpp @@ -0,0 +1,437 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: PartSet_WidgetFeaturePointSelector.cpp +// Created: 28 Feb 2017 +// Author: Natalia ERMOLAEVA + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "PartSet_WidgetFeaturePointSelector.h" +#include "PartSet_Tools.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define HIGHLIGHT_STAYS_PROBLEM +#ifdef HIGHLIGHT_STAYS_PROBLEM +#include +#define SKETCH_ENTITY_COLOR "225,0,0" +#endif + +PartSet_WidgetFeaturePointSelector::PartSet_WidgetFeaturePointSelector(QWidget* theParent, + ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData) +: ModuleBase_WidgetShapeSelector(theParent, theWorkshop, theData) +{ + myUseGraphicIntersection = theData->getBooleanAttribute("use_graphic_intersection", false); + //myCurrentSubShape = std::shared_ptr(new ModuleBase_ViewerPrs()); +} + +PartSet_WidgetFeaturePointSelector::~PartSet_WidgetFeaturePointSelector() +{ + //myCashedShapes.clear(); +} + +//******************************************************************** +bool PartSet_WidgetFeaturePointSelector::isValidSelection( + const std::shared_ptr& theValue) +{ + return true; +} + +//******************************************************************** +void PartSet_WidgetFeaturePointSelector::activateCustom() +{ + ModuleBase_WidgetShapeSelector::activateCustom(); + + myWorkshop->module()->activateCustomPrs(myFeature, + ModuleBase_IModule::CustomizeHighlightedObjects, true); + + Handle(AIS_InteractiveContext) aContext = + XGUI_Tools::workshop(myWorkshop)->viewer()->AISContext(); + + std::vector aColors; + aColors = Config_PropManager::color("Visualization", "sketch_entity_color", + SKETCH_ENTITY_COLOR); + Quantity_Color aColor(aColors[0] / 255., aColors[1] / 255., aColors[2] / 255., Quantity_TOC_RGB); + +#ifdef HIGHLIGHT_STAYS_PROBLEM + Handle(Graphic3d_HighlightStyle) aHStyle = aContext->HighlightStyle(); + myHighlightColor = aHStyle->Color(); + aHStyle->SetColor(aColor); + aContext->SetHighlightStyle(aHStyle); + + Handle(Graphic3d_HighlightStyle) aSStyle = aContext->SelectionStyle(); + mySelectionColor = aSStyle->Color(); + aSStyle->SetColor(aColor); + aContext->SetSelectionStyle(aSStyle); +#endif +} + +//******************************************************************** +void PartSet_WidgetFeaturePointSelector::deactivate() +{ + ModuleBase_WidgetShapeSelector::deactivate(); + + Handle(AIS_InteractiveContext) aContext = + XGUI_Tools::workshop(myWorkshop)->viewer()->AISContext(); + +#ifdef HIGHLIGHT_STAYS_PROBLEM + Handle(Graphic3d_HighlightStyle) aHStyle = aContext->HighlightStyle(); + aHStyle->SetColor(myHighlightColor); + aContext->SetHighlightStyle(aHStyle); + + Handle(Graphic3d_HighlightStyle) aSStyle = aContext->SelectionStyle(); + aSStyle->SetColor(mySelectionColor); + aContext->SetSelectionStyle(aSStyle); +#endif + //myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); +} + +//******************************************************************** +void PartSet_WidgetFeaturePointSelector::mouseMoved(ModuleBase_IViewWindow* theWindow, + QMouseEvent* theEvent) +{ + ModuleBase_ISelection* aSelect = myWorkshop->selection(); + QList aHighlighted = aSelect->getHighlighted(); + + if (!aHighlighted.empty()) { + ModuleBase_ViewerPrsPtr aPrs = aHighlighted.first(); + fillFeature(aPrs, theWindow, theEvent); + } +} + +//******************************************************************** +void PartSet_WidgetFeaturePointSelector::mouseReleased(ModuleBase_IViewWindow* theWindow, + QMouseEvent* theEvent) +{ + // the contex menu release by the right button should not be processed by this widget + if (theEvent->button() != Qt::LeftButton) + return; + + emit focusOutWidget(this); +} + +//******************************************************************** +bool PartSet_WidgetFeaturePointSelector::fillFeature( + const std::shared_ptr& theSelectedPrs, + ModuleBase_IViewWindow* theWindow, + QMouseEvent* theEvent) +{ + bool aFilled = false; + if (theSelectedPrs.get() && theSelectedPrs->object().get()) { + ObjectPtr anObject = theSelectedPrs->object(); + //if (myCashedShapes.find(anObject) == myCashedShapes.end()) + // fillObjectShapes(anObject); + //const std::set& aShapes = myCashedShapes[anObject]; + //if (!aShapes.empty()) { + gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + double aX, anY; + Handle(V3d_View) aView = theWindow->v3dView(); + PartSet_Tools::convertTo2D(aPnt, mySketch, aView, aX, anY); + //std::shared_ptr aPoint = PartSet_Tools::convertTo3D(aX, anY, mySketch); + + std::shared_ptr aRef = + std::dynamic_pointer_cast( + feature()->data()->attribute(SketchPlugin_Constraint::VALUE())); + aRef->setValue(anObject); + + std::shared_ptr anAttributePoint = + std::dynamic_pointer_cast( + feature()->data()->attribute(SketchPlugin_Trim::ENTITY_POINT())); + //std::shared_ptr aPoint2D = anAttributePoint->pnt(); + anAttributePoint->setValue(aX, anY); + // redisplay AIS presentation in viewer +#ifndef HIGHLIGHT_STAYS_PROBLEM + // an attempt to clear highlighted item in the viewer: but of OCCT + XGUI_Tools::workshop(myWorkshop)->displayer()->clearSelected(true); +#endif + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED); + ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent); + Events_Loop::loop()->flush(anEvent); + + aFilled = true; + + /* + std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); + for (; anIt != aLast; anIt++) { + GeomShapePtr aBaseShape = *anIt; + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, aPoint, aProjectedPoint)) { + XGUI_Tools::workshop(myWorkshop)->displayer()->clearSelected(false); + if (myCurrentSubShape->object() != anObject || + myCurrentSubShape->shape() != aBaseShape) { + myCurrentSubShape->setObject(anObject); + myCurrentSubShape->setShape(aBaseShape); + + ModuleBase_IModule* aModule = myWorkshop->module(); + + + if (!aModule->isCustomPrsActivated(ModuleBase_IModule::CustomizeHighlightedObjects)) + aModule->activateCustomPrs(myFeature, + ModuleBase_IModule::CustomizeHighlightedObjects, true); + aModule->customizeObject(myFeature, + ModuleBase_IModule::CustomizeHighlightedObjects, true); + } + else + XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); + break; + } + }*/ + //} + //} + } + return aFilled; +} + +//******************************************************************** +/*void PartSet_WidgetFeaturePointSelector::getGeomSelection(const ModuleBase_ViewerPrsPtr& thePrs, + ObjectPtr& theObject, + GeomShapePtr& theShape) +{ + ModuleBase_ISelection* aSelection = myWorkshop->selection(); + theObject = aSelection->getResult(thePrs); + if (!theObject.get() && myCurrentSubShape->object()) + theObject = myCurrentSubShape->object(); +}*/ + +//******************************************************************** +QList PartSet_WidgetFeaturePointSelector::getAttributeSelection() const +{ + return QList(); +} + + +//******************************************************************** +bool PartSet_WidgetFeaturePointSelector::setSelection( + QList>& theValues, + const bool theToValidate) +{ + return false; + //return !theValues.empty(); + + /*ObjectPtr aBaseObject = myCurrentSubShape->object(); + GeomShapePtr aBaseShape = myCurrentSubShape->shape(); + bool aResult = aBaseObject.get() && aBaseShape.get(); + // firstly set the selection to the attribute + if (aResult) { + QList aValues; + aValues.append(myCurrentSubShape); + aResult = ModuleBase_WidgetShapeSelector::setSelection(aValues, theToValidate); + } + // secondly fill additional attributes + if (aResult) { + aResult = false; + if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) { + std::shared_ptr anEdge(new GeomAPI_Edge(aBaseShape)); + + std::shared_ptr aFirstPnt = anEdge->firstPoint(); + std::shared_ptr aLastPnt = anEdge->lastPoint(); + + std::shared_ptr aFirstPointAttr, aLastPointAttr; + /// find the points in base feature attributes + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject); + std::list a2DPointAttributes = aBaseFeature->data()->attributes( + GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = a2DPointAttributes.begin(), + aLast = a2DPointAttributes.end(); + for (; anIt != aLast; anIt++) { + std::shared_ptr anAttributePoint = + std::dynamic_pointer_cast(*anIt); + std::shared_ptr aPoint2D = anAttributePoint->pnt(); + std::shared_ptr aPoint3D = PartSet_Tools::convertTo3D(aPoint2D->x(), + aPoint2D->y(), mySketch); + if (aFirstPnt->isEqual(aPoint3D)) + aFirstPointAttr = anAttributePoint; + else if (aLastPnt->isEqual(aPoint3D)) + aLastPointAttr = anAttributePoint; + } + + /// find the points in coincident features + PntToAttributesMap aRefAttributes = myCashedReferences[aBaseObject]; + PntToAttributesMap::const_iterator + aRIt = aRefAttributes.begin(), aRLast = aRefAttributes.end(); + for (PntToAttributesMap::const_iterator aRIt = aRefAttributes.begin(), + aRLast = aRefAttributes.end(); aRIt != aRLast; aRIt++) { + std::shared_ptr anAttribute = aRIt->first; + std::shared_ptr aPoint = aRIt->second; + if (!aFirstPointAttr.get() && aFirstPnt->isEqual(aPoint)) + aFirstPointAttr = anAttribute; + if (!aLastPointAttr.get() && aLastPnt->isEqual(aPoint)) + aLastPointAttr = anAttribute; + if (aFirstPointAttr.get() && aLastPointAttr.get()) + break; + } + + /// find the points in objects that intersect the base feature + ObjectPtr aFirstPointObject, aLastPointObject; + if (myUseGraphicIntersection && (!aFirstPointAttr.get() || !aLastPointAttr.get())) { + PntToObjectsMap aRefObjects = myCashedObjects[aBaseObject]; + PntToObjectsMap::const_iterator + anObjectIt = aRefObjects.begin(), anObjectLast = aRefObjects.end(); + for (; anObjectIt != anObjectLast; anObjectIt++) { + std::list< std::shared_ptr > anObjects = anObjectIt->second; + if (anObjects.empty()) + continue; + std::shared_ptr anObject = anObjects.front(); + std::shared_ptr aPoint = anObjectIt->first; + if (!aFirstPointAttr.get() && !aFirstPointObject.get() && aFirstPnt->isEqual(aPoint)) + aFirstPointObject = anObject; + if (!aLastPointAttr.get() && !aLastPointObject.get() && aLastPnt->isEqual(aPoint)) + aLastPointObject = anObject; + if (aFirstPointAttr.get() && aLastPointAttr.get()) + break; + } + } + + if ((!aFirstPointAttr.get() && !aFirstPointObject.get()) || + (!aLastPointAttr.get() && !aLastPointObject.get())) + return false; + + FeaturePtr aFeature = feature(); + AttributeRefAttrPtr anAPointAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributeRefAttrPtr aBPointAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (aFirstPointAttr.get()) + anAPointAttr->setAttr(aFirstPointAttr); + else + anAPointAttr->setObject(aFirstPointObject); + + if (aLastPointAttr.get()) + aBPointAttr->setAttr(aLastPointAttr); + else + aBPointAttr->setObject(aLastPointObject); + + if (myUseGraphicIntersection) { + // fill geometrical points + AttributePtr anAPointAttr = aFeature->attribute(SketchPlugin_Trim::ENTITY_A_POINT()); + AttributePtr aBPointAttr = aFeature->attribute(SketchPlugin_Trim::ENTITY_B_POINT()); + if (anAPointAttr.get() && aBPointAttr.get()) { + std::shared_ptr aPlane = PartSet_Tools::sketchPlane(sketch()); + + std::shared_ptr anAPoint = + std::dynamic_pointer_cast(anAPointAttr); + anAPoint->setValue(aFirstPnt->to2D(aPlane)); + + std::shared_ptr aBPoint = + std::dynamic_pointer_cast(aBPointAttr); + aBPoint->setValue(aLastPnt->to2D(aPlane)); + } + } + aResult = true; + } + } + return aResult;*/ + return false; +} + +void PartSet_WidgetFeaturePointSelector::setPreSelection( + const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent) +{ + if (fillFeature(thePreSelected, theWnd, theEvent)) + mouseReleased(theWnd, theEvent); +} + +//******************************************************************** +/*bool PartSet_WidgetFeaturePointSelector::isValidSelectionCustom( + const std::shared_ptr& thePrs) +{ + // as we are modfying the attribute in move, we should not check validity here, by highlight + return false; +}*/ + +//******************************************************************** +/*void PartSet_WidgetFeaturePointSelector::getHighlighted( + QList>& theValues) +{ + if (myCurrentSubShape.get() && myCurrentSubShape->object().get()) + theValues.append(myCurrentSubShape); +}*/ + +//******************************************************************** +/*void PartSet_WidgetFeaturePointSelector::fillObjectShapes(const ObjectPtr& theObject) +{ + std::set > aShapes; + std::map, std::shared_ptr > aPointToAttributes; + std::map, + std::list< std::shared_ptr > > aPointToObjects; + + std::set > aRefAttributes; + // current feature + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + std::set anEdgeShapes; + // edges on feature + ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (!anEdgeShapes.empty()) { + GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape(); + + // coincidences to the feature + std::list > aPoints; + + ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(), + aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); + // layed on feature coincidences to divide it on several shapes + CompositeFeaturePtr aSketch = sketch(); + std::shared_ptr aData = aSketch->data(); + std::shared_ptr aC = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aX = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); + ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(), + aX->dir(), aY, aPoints, aPointToAttributes); + + // intersection points + if (myUseGraphicIntersection) { + std::list aFeatures; + for (int i = 0; i < aSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = aSketch->subFeature(i); + if (aFeature.get()) + aFeatures.push_back(aFeature); + } + ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints, + aPointToObjects); + } + GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes); + } + myCashedShapes[theObject] = aShapes; + myCashedReferences[theObject] = aPointToAttributes; + if (myUseGraphicIntersection) + myCashedObjects[theObject] = aPointToObjects; +} +*/ diff --git a/src/PartSet/PartSet_WidgetFeaturePointSelector.h b/src/PartSet/PartSet_WidgetFeaturePointSelector.h new file mode 100644 index 000000000..503c0bc8b --- /dev/null +++ b/src/PartSet/PartSet_WidgetFeaturePointSelector.h @@ -0,0 +1,155 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: PartSet_WidgetFeaturePointSelector.h +// Created: 28 Feb 2017 +// Author: Natalia ERMOLAEVA + + +#ifndef PartSet_WidgetFeaturePointSelector_H +#define PartSet_WidgetFeaturePointSelector_H + +#include +#include + +#include "PartSet.h" +#include "PartSet_MouseProcessor.h" + +#include + +#include + +#include +#include + +class ModuleBase_IWorkshop; +class Config_WidgetAPI; +class ModuleBase_IViewWindow; +class ModuleBase_ViewerPrs; + +class GeomAPI_Pnt; +class GeomDataAPI_Point2D; + +class QWidget; +class QMouseEvent; + +/** +* \ingroup Modules +* Customosation of PartSet_WidgetFeaturePointSelector in order to visualize sub-shape +* by mouse move over shape in the viewer. Split of the object is performed by +* coincident points to the object. Segment between nearest coincidence is highlighted +*/ +class PARTSET_EXPORT PartSet_WidgetFeaturePointSelector: public ModuleBase_WidgetShapeSelector, + public PartSet_MouseProcessor +{ +Q_OBJECT + public: + /// Constructor + /// \param theParent the parent object + /// \param theWorkshop instance of workshop interface + /// \param theData the widget configuation. The attribute of the model widget is obtained from + PartSet_WidgetFeaturePointSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData); + + virtual ~PartSet_WidgetFeaturePointSelector(); + + /// Checks all widget validator if the owner is valid. Firstly it checks custom widget validating, + /// next, the attribute's validating. It trying on the give selection to current attribute by + /// setting the value inside and calling validators. After this, the previous attribute value is + /// restored.The valid/invalid value is cashed. + /// \param theValue a selected presentation in the view + /// \return a boolean value + virtual bool isValidSelection(const std::shared_ptr& theValue); + + /// Set sketcher + /// \param theSketch a sketcher object + void setSketcher(CompositeFeaturePtr theSketch) { mySketch = theSketch; } + + /// Retrurns installed sketcher + CompositeFeaturePtr sketch() const { return mySketch; } + + /// The methiod called when widget is deactivated + virtual void deactivate(); + + /// Processing the mouse move event in the viewer + /// \param theWindow a view window + /// \param theEvent a mouse event + virtual void mouseMoved(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent); + + /// Processing the mouse release event in the viewer + /// \param theWindow a view window + /// \param theEvent a mouse event + virtual void mouseReleased(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent); + + /// Returns values which should be highlighted when the whidget is active + /// \param theValues a list of presentations + //virtual void getHighlighted(QList>& theValues); + + /// Set the given wrapped value to the current widget + /// This value should be processed in the widget according to the needs + /// The method is called by the current operation to process the operation preselection. + /// It is redefined to fill attributes responsible for the sub selection + /// \param theValues the wrapped selection values + /// \param theToValidate a flag on validation of the values + virtual bool setSelection(QList>& theValues, + const bool theToValidate); + + /// Fill preselection used in mouseReleased + //virtual void setPreSelection(const std::shared_ptr& thePreSelected); + virtual void setPreSelection(const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent); +protected: + /// Checks the widget validity. By default, it returns true. + /// \param thePrs a selected presentation in the view + /// \return a boolean value + //virtual bool isValidSelectionCustom(const std::shared_ptr& thePrs); + + /// Return an object and geom shape by the viewer presentation + /// \param thePrs a selection + /// \param theObject an output object + /// \param theShape a shape of the selection + //virtual void getGeomSelection(const std::shared_ptr& thePrs, + // ObjectPtr& theObject, + // GeomShapePtr& theShape); + //void fillObjectShapes(const ObjectPtr& theObject); + + /// Return an object and geom shape by the viewer presentation + /// \param thePrs a selection + /// \param theObject an output object + /// \param theShape a shape of the selection + //virtual void getGeomSelection(const std::shared_ptr& thePrs, + // ObjectPtr& theObject, + // GeomShapePtr& theShape); + + /// Return the attribute values wrapped in a list of viewer presentations + /// \return a list of viewer presentations, which contains an attribute result and + /// a shape. If the attribute do not uses the shape, it is empty + virtual QList> getAttributeSelection() const; + +protected: + /// The methiod called when widget is activated + virtual void activateCustom(); + +protected: + bool fillFeature(const std::shared_ptr& theSelectedPrs, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent); + //std::shared_ptr myCurrentSubShape; + //std::map > myCashedShapes; + + //typedef std::map, + // std::shared_ptr > PntToAttributesMap; + //std::map myCashedReferences; + + //typedef std::map, + // std::list< std::shared_ptr > > PntToObjectsMap; + //std::map myCashedObjects; + + /// Pointer to a sketch + CompositeFeaturePtr mySketch; + bool myUseGraphicIntersection; + Quantity_Color myHighlightColor; + Quantity_Color mySelectionColor; +}; + +#endif \ No newline at end of file diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index e6c1cf1d3..2a7ef76fa 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -582,9 +582,13 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo } void PartSet_WidgetPoint2D::setPreSelection( - const std::shared_ptr& thePreSelected) + const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent) { myPreSelected = thePreSelected; + mouseReleased(theWnd, theEvent); + myPreSelected = ModuleBase_ViewerPrsPtr(); } void PartSet_WidgetPoint2D::mouseMoved(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent) diff --git a/src/PartSet/PartSet_WidgetPoint2d.h b/src/PartSet/PartSet_WidgetPoint2d.h index ab56c058b..3de0dc147 100755 --- a/src/PartSet/PartSet_WidgetPoint2d.h +++ b/src/PartSet/PartSet_WidgetPoint2d.h @@ -111,7 +111,10 @@ Q_OBJECT virtual void mouseReleased(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent); /// Fill preselection used in mouseReleased - void setPreSelection(const std::shared_ptr& thePreSelected); + //virtual void setPreSelection(const std::shared_ptr& thePreSelected); + virtual void setPreSelection(const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent); signals: /// Signal about selection of an existing vertex from an object @@ -206,7 +209,7 @@ private: ModuleBase_LabelValue* myXSpin; ///< the label for the X coordinate ModuleBase_LabelValue* myYSpin; ///< the label for the Y coordinate - /// value used as selection in mouse release method + /// value used as selection in mouse release method std::shared_ptr myPreSelected; /// it is important during restart operation diff --git a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp index 2235b4e6d..0e0a41a2e 100755 --- a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -186,7 +187,8 @@ bool PartSet_WidgetSubShapeSelector::setSelection( PntToAttributesMap aRefAttributes = myCashedReferences[aBaseObject]; PntToAttributesMap::const_iterator aRIt = aRefAttributes.begin(), aRLast = aRefAttributes.end(); - for (; aRIt != aRLast; aRIt++) { + for (PntToAttributesMap::const_iterator aRIt = aRefAttributes.begin(), + aRLast = aRefAttributes.end(); aRIt != aRLast; aRIt++) { std::shared_ptr anAttribute = aRIt->first; std::shared_ptr aPoint = aRIt->second; if (!aFirstPointAttr.get() && aFirstPnt->isEqual(aPoint)) @@ -204,8 +206,11 @@ bool PartSet_WidgetSubShapeSelector::setSelection( PntToObjectsMap::const_iterator anObjectIt = aRefObjects.begin(), anObjectLast = aRefObjects.end(); for (; anObjectIt != anObjectLast; anObjectIt++) { - std::shared_ptr anObject = anObjectIt->first; - std::shared_ptr aPoint = aRIt->second; + std::list< std::shared_ptr > anObjects = anObjectIt->second; + if (anObjects.empty()) + continue; + std::shared_ptr anObject = anObjects.front(); + std::shared_ptr aPoint = anObjectIt->first; if (!aFirstPointAttr.get() && !aFirstPointObject.get() && aFirstPnt->isEqual(aPoint)) aFirstPointObject = anObject; if (!aLastPointAttr.get() && !aLastPointObject.get() && aLastPnt->isEqual(aPoint)) @@ -229,11 +234,27 @@ bool PartSet_WidgetSubShapeSelector::setSelection( else anAPointAttr->setObject(aFirstPointObject); - if (aFirstPointAttr.get()) + if (aLastPointAttr.get()) aBPointAttr->setAttr(aLastPointAttr); else aBPointAttr->setObject(aLastPointObject); + /*if (myUseGraphicIntersection) { + // fill geometrical points + AttributePtr anAPointAttr = aFeature->attribute(SketchPlugin_Trim::ENTITY_A_POINT()); + AttributePtr aBPointAttr = aFeature->attribute(SketchPlugin_Trim::ENTITY_B_POINT()); + if (anAPointAttr.get() && aBPointAttr.get()) { + std::shared_ptr aPlane = PartSet_Tools::sketchPlane(sketch()); + + std::shared_ptr anAPoint = + std::dynamic_pointer_cast(anAPointAttr); + anAPoint->setValue(aFirstPnt->to2D(aPlane)); + + std::shared_ptr aBPoint = + std::dynamic_pointer_cast(aBPointAttr); + aBPoint->setValue(aLastPnt->to2D(aPlane)); + } + }*/ aResult = true; } } @@ -254,7 +275,8 @@ void PartSet_WidgetSubShapeSelector::fillObjectShapes(const ObjectPtr& theObject { std::set > aShapes; std::map, std::shared_ptr > aPointToAttributes; - std::map, std::shared_ptr > aPointToObjects; + std::map, + std::list< std::shared_ptr > > aPointToObjects; std::set > aRefAttributes; // current feature diff --git a/src/PartSet/PartSet_WidgetSubShapeSelector.h b/src/PartSet/PartSet_WidgetSubShapeSelector.h index a4c47fde7..4b86b46af 100644 --- a/src/PartSet/PartSet_WidgetSubShapeSelector.h +++ b/src/PartSet/PartSet_WidgetSubShapeSelector.h @@ -119,8 +119,8 @@ protected: std::shared_ptr > PntToAttributesMap; std::map myCashedReferences; - typedef std::map, - std::shared_ptr > PntToObjectsMap; + typedef std::map, + std::list< std::shared_ptr > > PntToObjectsMap; std::map myCashedObjects; /// Pointer to a sketch diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index 6f8b36d47..0dfe4a88a 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.cpp +++ b/src/SketchPlugin/SketchPlugin_Trim.cpp @@ -50,7 +50,7 @@ #include #endif -static const double PI = 3.141592653589793238463; +//static const double PI = 3.141592653589793238463; SketchPlugin_Trim::SketchPlugin_Trim() { @@ -59,10 +59,23 @@ SketchPlugin_Trim::SketchPlugin_Trim() void SketchPlugin_Trim::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeReference::typeId()); - data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); - data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + //data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + //data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + data()->addAttribute(ENTITY_POINT(), GeomDataAPI_Point2D::typeId()); + //data()->addAttribute(ENTITY_B_POINT(), GeomDataAPI_Point2D::typeId()); } +//FeaturePtr SketchPlugin_Trim::createCoincidenceConstraint(const AttributePtr& theFirstAttribute, +// const AttributePtr& theSecondAttribute) +//{ +// FeaturePtr aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID()); +// +// fillAttribute(aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()), theFirstAttribute); +// fillAttribute(aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()), theSecondAttribute); +// +// return aConstraint; +//} + void SketchPlugin_Trim::execute() { std::shared_ptr aData = data(); @@ -74,255 +87,298 @@ void SketchPlugin_Trim::execute() setError("Error: Base object is not initialized."); return; } - AttributePoint2DPtr aFirstPointAttrOfSplit = - getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributePoint2DPtr aSecondPointAttrOfSplit = - getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); - if (!aFirstPointAttrOfSplit.get() || !aFirstPointAttrOfSplit->isInitialized() || - !aSecondPointAttrOfSplit.get() || !aSecondPointAttrOfSplit->isInitialized()) { - setError("Error: Sub-shape is not initialized."); - return; - } - // Wait all constraints being created, then send update events - static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); - bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent); - if (isUpdateFlushed) - Events_Loop::loop()->setFlushed(anUpdateEvent, false); + /*std::shared_ptr anAPoint = std::dynamic_pointer_cast( + aData->attribute(ENTITY_A_POINT())); + std::shared_ptr anAttributeStartPnt2d = anAPoint->pnt(); + std::shared_ptr aBPoint = std::dynamic_pointer_cast( + aData->attribute(ENTITY_B_POINT())); + std::shared_ptr anAttributeEndPnt2d = aBPoint->pnt(); - // Find feature constraints - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); - std::set aFeaturesToDelete, aFeaturesToUpdate; - std::map aTangentFeatures; - std::map aCoincidenceToFeature; - getConstraints(aFeaturesToDelete, aFeaturesToUpdate, aTangentFeatures, aCoincidenceToFeature); + AttributeRefAttrPtr anARefAttr = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributeRefAttrPtr aBRefAttr = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::ENTITY_B()));*/ - std::map > aBaseRefAttributes; - std::list aRefsToFeature; - getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); + //AttributePoint2DPtr aFirstPointAttrOfSplit = + // getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); + //AttributePoint2DPtr aSecondPointAttrOfSplit = + // getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); + //if (!aFirstPointAttrOfSplit.get() || !aFirstPointAttrOfSplit->isInitialized() || + // !aSecondPointAttrOfSplit.get() || !aSecondPointAttrOfSplit->isInitialized()) { + // setError("Error: Sub-shape is not initialized."); + // return; + //} - std::map aBasePointModifiedAttributes; - -#ifdef DEBUG_SPLIT - std::cout << std::endl; - std::cout << "SketchPlugin_Trim::execute()" << std::endl; - std::cout << std::endl; - - SketchPlugin_Sketch* aSketch = sketch(); - std::cout << "SKETCH FEATURES (before split) [" << aSketch->numberOfSubs() << "]:" << std::endl; - for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { - std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; - } - - std::cout << std::endl; - std::cout << "---- IN PARAMETERS ----" << std::endl; - std::cout << "Base feature:" << getFeatureInfo(aBaseFeature) << std::endl; - std::cout << std::endl; - - if (!aCoincidenceToFeature.empty()) { - std::cout << "Coincidences to base feature[" << - aCoincidenceToFeature.size() << "]: " << std::endl; - std::map::const_iterator anIt = aCoincidenceToFeature.begin(), - aLast = aCoincidenceToFeature.end(); - for (int i = 1; anIt != aLast; anIt++, i++) { - FeaturePtr aFeature = (*anIt).first; - std::string anAttributeId = (*anIt).second.first; - std::shared_ptr aPointAttr = (*anIt).second.second; - - std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; - std::cout << " -Attribute to correct:" << anAttributeId << std::endl; - std::cout << " -Point attribute:" << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; - } - } + // Wait all constraints being created, then send update events + static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent); + if (isUpdateFlushed) + Events_Loop::loop()->setFlushed(anUpdateEvent, false); - if (!aTangentFeatures.empty()) { - std::cout << std::endl; - std::cout << "Tangencies to base feature[" << aTangentFeatures.size() << "]: " << std::endl; - std::map::const_iterator anIt = aTangentFeatures.begin(), - aLast = aTangentFeatures.end(); - for (int i = 1; anIt != aLast; anIt++, i++) { - FeaturePtr aFeature = (*anIt).first; - std::string anAttributeId = (*anIt).second.first; - std::shared_ptr aPointAttr = (*anIt).second.second; - std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; - std::cout << " -Attribute to correct:" << anAttributeId << std::endl; - std::cout << " -Point attribute:" << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; - } - } +// // Find feature constraints + /*FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::map >::const_iterator - aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end(); - std::cout << std::endl << "References to attributes of base feature [" << - aBaseRefAttributes.size() << "]" << std::endl; - for (; aRefIt != aRefLast; aRefIt++) { - AttributePtr aBaseAttr = aRefIt->first; - std::list aRefAttributes = aRefIt->second; - std::string aRefsInfo; - std::list::const_iterator aRefAttrIt = aRefAttributes.begin(), - aRefAttrLast = aRefAttributes.end(); - for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { - if (!aRefsInfo.empty()) - aRefsInfo.append(","); - AttributePtr aRAttr = *aRefAttrIt; - aRefsInfo.append(aRAttr->id()); - FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); - aRefsInfo.append("(" + aRFeature->name() + ") "); + std::set > aNewCoincidencesToSplitFeature; + AttributePoint2DPtr aFeatureStartPointAttr, aFeatureEndPointAttr; + getFeaturePoints(aBaseFeature, aFeatureStartPointAttr, aFeatureEndPointAttr); + + if (aFeatureStartPointAttr.get() && aFeatureStartPointAttr.get()) { // line or arc + std::shared_ptr aStartPointAttribute = + std::dynamic_pointer_cast( + aFeatureStartPointAttr); + std::shared_ptr aFeatureStartPnt2d = aStartPointAttribute->pnt(); + std::shared_ptr anEndPointAttribute = + std::dynamic_pointer_cast( + aFeatureEndPointAttr); + std::shared_ptr aFeatureEndPnt2d = anEndPointAttribute->pnt(); + if (anAttributeStartPnt2d->isEqual(aFeatureStartPnt2d)) { + double anX = aFeatureStartPnt2d->x(); + double anY = aFeatureStartPnt2d->y(); + double anEndX = anAttributeEndPnt2d->x(); + double anEndY = anAttributeEndPnt2d->y(); + aStartPointAttribute->setValue(anAttributeEndPnt2d->x(), anAttributeEndPnt2d->y()); + + createCoincidenceConstraint(aStartPointAttribute, aBRefAttr); } - std::shared_ptr aPointAttr = - std::dynamic_pointer_cast(aBaseAttr); - std::cout << aPointAttr->id().c_str() << - ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl; - } - std::cout << std::endl; - std::cout << std::endl << "References to base feature [" << - aRefsToFeature.size() << "]" << std::endl; - std::list::const_iterator aRefAttrIt = aRefsToFeature.begin(), - aRefAttrLast = aRefsToFeature.end(); - std::string aRefsInfo; - for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { - if (!aRefsInfo.empty()) - aRefsInfo.append(","); - AttributePtr aRAttr = *aRefAttrIt; - aRefsInfo.append(aRAttr->id()); - FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); - aRefsInfo.append("(" + aRFeature->name() + ") "); } - std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl; - - - std::cout << std::endl; - std::cout << "---- SPLIT ----" << std::endl; - std::cout << std::endl; -#endif - - std::string aFeatureKind = aBaseFeature->getKind(); - FeaturePtr aSplitFeature, anAfterFeature; - std::set aFurtherCoincidences; - std::set aCreatedFeatures; - std::set> aModifiedAttributes; - if (aFeatureKind == SketchPlugin_Line::ID()) - splitLine(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, - aModifiedAttributes); - else if (aFeatureKind == SketchPlugin_Arc::ID()) - splitArc(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, - aModifiedAttributes); - if (aFeatureKind == SketchPlugin_Circle::ID()) { - FeaturePtr aCircleFeature = aBaseFeature; - splitCircle(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, - aCreatedFeatures, aModifiedAttributes); - - updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature); - - AttributePtr aCenterAttr = aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()); - aFeaturesToDelete.insert(aCircleFeature); - // as circle is removed, temporary fill this attribute*/ - aBaseObjectAttr->setObject(ResultPtr()); - } - -#ifdef DEBUG_SPLIT - std::cout << "---- OUT PARAMETERS ----" << std::endl; - std::cout << "Base modified feature:" << getFeatureInfo(aBaseFeature) << std::endl; - std::cout << "Split feature:" << getFeatureInfo(aSplitFeature) << std::endl; - std::cout << "After feature:" << getFeatureInfo(anAfterFeature) << std::endl; - std::cout << std::endl; - - std::cout << "Created features by split:[" << aCreatedFeatures.size() << "]" << std::endl; - std::set::const_iterator aFIt = aCreatedFeatures.begin(), - aFLast = aCreatedFeatures.end(); - for (; aFIt != aFLast; aFIt++) { - std::cout << getFeatureInfo(*aFIt) << std::endl; - } - std::cout << std::endl; - - std::cout << "Attributes for further Coincidences:" << std::endl; - std::set::const_iterator anIt = aFurtherCoincidences.begin(), - aLast = aFurtherCoincidences.end(); - for (; anIt != aLast; anIt++) { - AttributePtr anAttribute = *anIt; - FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); - std::cout << ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) - << " [" << getFeatureInfo(aFeature, false) << "]" << std::endl; - } - - std::cout << "Modifed attributes (constraints to attributes are moved here):" << std::endl; - std::set >::const_iterator - aPIt = aModifiedAttributes.begin(), aPLast = aModifiedAttributes.end(); - std::string aResInfo; - for (; aPIt != aPLast; aPIt++) { - if (!aResInfo.empty()) - aResInfo += "\n"; - - std::pair aPair = *aPIt; - - AttributePtr anAttr = aPair.first; - aResInfo.append(anAttr->id()); - FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->owner()); - aResInfo.append("(" + aFeature->name() + ") "); - - aResInfo.append(" - is modified to - "); - - anAttr = aPair.second; - aResInfo.append(anAttr->id()); - aFeature = ModelAPI_Feature::feature(anAttr->owner()); - aResInfo.append("(" + aFeature->name() + ") "); - } - std::cout << aResInfo << std::endl; -#endif - - std::set aFeatureResults; - aFeatureResults.insert(getFeatureResult(aBaseFeature)); - if (anAfterFeature.get() && anAfterFeature != aBaseFeature) - aFeatureResults.insert(getFeatureResult(anAfterFeature)); - - // coincidence to feature - updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences, - aFeatureResults, aSplitFeature); - // tangency - updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences); - - updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); - - // delete constraints -#ifdef DEBUG_SPLIT - std::cout << "remove features and references:" << std::endl; - std::set::const_iterator aDIt = aFeaturesToDelete.begin(), - aDLast = aFeaturesToDelete.end(); - for (; aDIt != aDLast; aDIt++) { - std::cout << getFeatureInfo(*aDIt, false) << std::endl; - std::cout << std::endl; - } -#endif - ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); - -#ifdef DEBUG_SPLIT - std::cout << "update features after split:" << std::endl; - std::set::const_iterator anUIt = aFeaturesToUpdate.begin(), - anULast = aFeaturesToUpdate.end(); - for (; anUIt != anULast; anUIt++) { - std::cout << getFeatureInfo(*anUIt, false) << std::endl; - std::cout << std::endl; - } -#endif - updateFeaturesAfterSplit(aFeaturesToUpdate); + else { // circle + + }*/ + + // ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); +// std::set aFeaturesToDelete, aFeaturesToUpdate; +// +// std::map aTangentFeatures; +// std::map aCoincidenceToFeature; +// getConstraints(aFeaturesToDelete, aFeaturesToUpdate, aTangentFeatures, aCoincidenceToFeature); +// +// std::map > aBaseRefAttributes; +// std::list aRefsToFeature; +// getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); +// +// std::map aBasePointModifiedAttributes; +// +//#ifdef DEBUG_SPLIT +// std::cout << std::endl; +// std::cout << "SketchPlugin_Trim::execute()" << std::endl; +// std::cout << std::endl; +// +// SketchPlugin_Sketch* aSketch = sketch(); +// std::cout << "SKETCH FEATURES (before split) [" << aSketch->numberOfSubs() << "]:" << std::endl; +// for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { +// std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; +// } +// +// std::cout << std::endl; +// std::cout << "---- IN PARAMETERS ----" << std::endl; +// std::cout << "Base feature:" << getFeatureInfo(aBaseFeature) << std::endl; +// std::cout << std::endl; +// +// if (!aCoincidenceToFeature.empty()) { +// std::cout << "Coincidences to base feature[" << +// aCoincidenceToFeature.size() << "]: " << std::endl; +// std::map::const_iterator anIt = aCoincidenceToFeature.begin(), +// aLast = aCoincidenceToFeature.end(); +// for (int i = 1; anIt != aLast; anIt++, i++) { +// FeaturePtr aFeature = (*anIt).first; +// std::string anAttributeId = (*anIt).second.first; +// std::shared_ptr aPointAttr = (*anIt).second.second; +// +// std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; +// std::cout << " -Attribute to correct:" << anAttributeId << std::endl; +// std::cout << " -Point attribute:" << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; +// } +// } +// +// if (!aTangentFeatures.empty()) { +// std::cout << std::endl; +// std::cout << "Tangencies to base feature[" << aTangentFeatures.size() << "]: " << std::endl; +// std::map::const_iterator anIt = aTangentFeatures.begin(), +// aLast = aTangentFeatures.end(); +// for (int i = 1; anIt != aLast; anIt++, i++) { +// FeaturePtr aFeature = (*anIt).first; +// std::string anAttributeId = (*anIt).second.first; +// std::shared_ptr aPointAttr = (*anIt).second.second; +// +// std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; +// std::cout << " -Attribute to correct:" << anAttributeId << std::endl; +// std::cout << " -Point attribute:" << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; +// } +// } +// +// std::map >::const_iterator +// aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end(); +// std::cout << std::endl << "References to attributes of base feature [" << +// aBaseRefAttributes.size() << "]" << std::endl; +// for (; aRefIt != aRefLast; aRefIt++) { +// AttributePtr aBaseAttr = aRefIt->first; +// std::list aRefAttributes = aRefIt->second; +// std::string aRefsInfo; +// std::list::const_iterator aRefAttrIt = aRefAttributes.begin(), +// aRefAttrLast = aRefAttributes.end(); +// for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { +// if (!aRefsInfo.empty()) +// aRefsInfo.append(","); +// AttributePtr aRAttr = *aRefAttrIt; +// aRefsInfo.append(aRAttr->id()); +// FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); +// aRefsInfo.append("(" + aRFeature->name() + ") "); +// } +// std::shared_ptr aPointAttr = +// std::dynamic_pointer_cast(aBaseAttr); +// std::cout << aPointAttr->id().c_str() << +// ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl; +// } +// std::cout << std::endl; +// std::cout << std::endl << "References to base feature [" << +// aRefsToFeature.size() << "]" << std::endl; +// std::list::const_iterator aRefAttrIt = aRefsToFeature.begin(), +// aRefAttrLast = aRefsToFeature.end(); +// std::string aRefsInfo; +// for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { +// if (!aRefsInfo.empty()) +// aRefsInfo.append(","); +// AttributePtr aRAttr = *aRefAttrIt; +// aRefsInfo.append(aRAttr->id()); +// FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); +// aRefsInfo.append("(" + aRFeature->name() + ") "); +// } +// std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl; +// +// +// std::cout << std::endl; +// std::cout << "---- SPLIT ----" << std::endl; +// std::cout << std::endl; +//#endif +// +// std::string aFeatureKind = aBaseFeature->getKind(); +// FeaturePtr aSplitFeature, anAfterFeature; +// std::set aFurtherCoincidences; +// std::set aCreatedFeatures; +// std::set> aModifiedAttributes; +// if (aFeatureKind == SketchPlugin_Line::ID()) +// splitLine(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, +// aModifiedAttributes); +// else if (aFeatureKind == SketchPlugin_Arc::ID()) +// splitArc(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, +// aModifiedAttributes); +// if (aFeatureKind == SketchPlugin_Circle::ID()) { +// FeaturePtr aCircleFeature = aBaseFeature; +// splitCircle(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, +// aCreatedFeatures, aModifiedAttributes); +// +// updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature); +// +// AttributePtr aCenterAttr = aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()); +// aFeaturesToDelete.insert(aCircleFeature); +// // as circle is removed, temporary fill this attribute +// aBaseObjectAttr->setObject(ResultPtr()); +// } +// +//#ifdef DEBUG_SPLIT +// std::cout << "---- OUT PARAMETERS ----" << std::endl; +// std::cout << "Base modified feature:" << getFeatureInfo(aBaseFeature) << std::endl; +// std::cout << "Split feature:" << getFeatureInfo(aSplitFeature) << std::endl; +// std::cout << "After feature:" << getFeatureInfo(anAfterFeature) << std::endl; +// std::cout << std::endl; +// +// std::cout << "Created features by split:[" << aCreatedFeatures.size() << "]" << std::endl; +// std::set::const_iterator aFIt = aCreatedFeatures.begin(), +// aFLast = aCreatedFeatures.end(); +// for (; aFIt != aFLast; aFIt++) { +// std::cout << getFeatureInfo(*aFIt) << std::endl; +// } +// std::cout << std::endl; +// +// std::cout << "Attributes for further Coincidences:" << std::endl; +// std::set::const_iterator anIt = aFurtherCoincidences.begin(), +// aLast = aFurtherCoincidences.end(); +// for (; anIt != aLast; anIt++) { +// AttributePtr anAttribute = *anIt; +// FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); +// std::cout << ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) +// << " [" << getFeatureInfo(aFeature, false) << "]" << std::endl; +// } +// +// std::cout << "Modifed attributes (constraints to attributes are moved here):" << std::endl; +// std::set >::const_iterator +// aPIt = aModifiedAttributes.begin(), aPLast = aModifiedAttributes.end(); +// std::string aResInfo; +// for (; aPIt != aPLast; aPIt++) { +// if (!aResInfo.empty()) +// aResInfo += "\n"; +// +// std::pair aPair = *aPIt; +// +// AttributePtr anAttr = aPair.first; +// aResInfo.append(anAttr->id()); +// FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->owner()); +// aResInfo.append("(" + aFeature->name() + ") "); +// +// aResInfo.append(" - is modified to - "); +// +// anAttr = aPair.second; +// aResInfo.append(anAttr->id()); +// aFeature = ModelAPI_Feature::feature(anAttr->owner()); +// aResInfo.append("(" + aFeature->name() + ") "); +// } +// std::cout << aResInfo << std::endl; +//#endif +// +// std::set aFeatureResults; +// aFeatureResults.insert(getFeatureResult(aBaseFeature)); +// if (anAfterFeature.get() && anAfterFeature != aBaseFeature) +// aFeatureResults.insert(getFeatureResult(anAfterFeature)); +// +// // coincidence to feature +// updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences, +// aFeatureResults, aSplitFeature); +// // tangency +// updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences); +// +// updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); +// +// // delete constraints +//#ifdef DEBUG_SPLIT +// std::cout << "remove features and references:" << std::endl; +// std::set::const_iterator aDIt = aFeaturesToDelete.begin(), +// aDLast = aFeaturesToDelete.end(); +// for (; aDIt != aDLast; aDIt++) { +// std::cout << getFeatureInfo(*aDIt, false) << std::endl; +// std::cout << std::endl; +// } +//#endif +// ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); +// Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); +// +//#ifdef DEBUG_SPLIT +// std::cout << "update features after split:" << std::endl; +// std::set::const_iterator anUIt = aFeaturesToUpdate.begin(), +// anULast = aFeaturesToUpdate.end(); +// for (; anUIt != anULast; anUIt++) { +// std::cout << getFeatureInfo(*anUIt, false) << std::endl; +// std::cout << std::endl; +// } +//#endif +// updateFeaturesAfterSplit(aFeaturesToUpdate); // Send events to update the sub-features by the solver. if(isUpdateFlushed) { Events_Loop::loop()->setFlushed(anUpdateEvent, true); } -#ifdef DEBUG_SPLIT - std::cout << "SKETCH FEATURES (after split) [" << aSketch->numberOfSubs() << "]:" << std::endl; - for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { - std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; - } -#endif +//#ifdef DEBUG_SPLIT +// std::cout << "SKETCH FEATURES (after split) [" << aSketch->numberOfSubs() << "]:" << std::endl; +// for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { +// std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; +// } +//#endif } bool SketchPlugin_Trim::isMacro() const @@ -330,12 +386,76 @@ bool SketchPlugin_Trim::isMacro() const return true; } +static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; } AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) { + AISObjectPtr anAIS = thePrevious; + // feature for trim AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Constraint::VALUE())); + ObjectPtr aBaseObject = aBaseObjectAttr->value(); + if (!aBaseObject.get()) + return anAIS; + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + // point on feature + std::shared_ptr aPoint = std::dynamic_pointer_cast( + data()->attribute(ENTITY_POINT())); + std::shared_ptr anAttributePnt2d = aPoint->pnt(); + std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y()); + + if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) + fillObjectShapes(aBaseObject); + + const std::set& aShapes = myCashedShapes[aBaseObject]; + if (!aShapes.empty()) { + std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); + for (; anIt != aLast; anIt++) { + GeomShapePtr aBaseShape = *anIt; + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) { + if (aBaseShape) { + if (!anAIS) + anAIS = AISObjectPtr(new GeomAPI_AISObject); + anAIS->createShape(aBaseShape); + + std::shared_ptr anAuxiliaryAttr = + aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID()); + + bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value(); + + std::vector aColor; + aColor = Config_PropManager::color("Visualization", "operation_highlight_color", + OPERATION_HIGHLIGHT_COLOR()); + double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH(); + int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE(); + if (isConstruction) { + //aColor = Config_PropManager::color("Visualization", "sketch_auxiliary_color", + // SKETCH_AUXILIARY_COLOR); + aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY(); + aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY(); + } + //else { + // aColor = Config_PropManager::color("Visualization", "sketch_entity_color", + // SKETCH_ENTITY_COLOR); + //} + anAIS->setColor(aColor[0], aColor[1], aColor[2]); + anAIS->setWidth(aWidth + 2);//1); + anAIS->setLineStyle(aLineStyle); + break; + } + //XGUI_Tools::workshop(myWorkshop)->displayer()->clearSelected(false); + //if (myCurrentSubShape->object() != anObject || + // myCurrentSubShape->shape() != aBaseShape) { + // myCurrentSubShape->setObject(anObject); + // myCurrentSubShape->setShape(aBaseShape); + //} + } + } + } + + /* AttributePoint2DPtr aFirstPointAttrOfSplit = getPointOfRefAttr( data()->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributePoint2DPtr aSecondPointAttrOfSplit = getPointOfRefAttr( @@ -392,1016 +512,1092 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) anAIS->setLineStyle(aLineStyle); } return anAIS; - } - return AISObjectPtr(); -} - -std::shared_ptr SketchPlugin_Trim::getPointOfRefAttr( - const AttributePtr& theAttribute) -{ - AttributePoint2DPtr aPointAttribute; - - if (theAttribute->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr aRefAttr = - std::dynamic_pointer_cast(theAttribute); - if (aRefAttr.get() && aRefAttr->isInitialized()) { - AttributePtr anAttribute = aRefAttr->attr(); - if (anAttribute.get() && anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) - aPointAttribute = std::dynamic_pointer_cast(anAttribute); - } - } - return aPointAttribute; -} - -void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature, - AttributePoint2DPtr& theStartPointAttr, - AttributePoint2DPtr& theEndPointAttr) -{ - std::string aFeatureKind = theFeature->getKind(); - std::string aStartAttributeName, anEndAttributeName; - if (aFeatureKind == SketchPlugin_Line::ID()) { - aStartAttributeName = SketchPlugin_Line::START_ID(); - anEndAttributeName = SketchPlugin_Line::END_ID(); - } - else if (aFeatureKind == SketchPlugin_Arc::ID()) { - aStartAttributeName = SketchPlugin_Arc::START_ID(); - anEndAttributeName = SketchPlugin_Arc::END_ID(); - } - if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) { - theStartPointAttr = std::dynamic_pointer_cast( - theFeature->attribute(aStartAttributeName)); - theEndPointAttr = std::dynamic_pointer_cast( - theFeature->attribute(anEndAttributeName)); - } + }*/ + return anAIS; } -void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete, - std::set& theFeaturesToUpdate, - std::map& theTangentFeatures, - std::map& theCoincidenceToFeature) +//std::shared_ptr SketchPlugin_Trim::getPointOfRefAttr( +// const AttributePtr& theAttribute) +//{ +// AttributePoint2DPtr aPointAttribute; +// +// if (theAttribute->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { +// AttributeRefAttrPtr aRefAttr = +// std::dynamic_pointer_cast(theAttribute); +// if (aRefAttr.get() && aRefAttr->isInitialized()) { +// AttributePtr anAttribute = aRefAttr->attr(); +// if (anAttribute.get() && anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) +// aPointAttribute = std::dynamic_pointer_cast(anAttribute); +// } +// } +// return aPointAttribute; +//} +// +//void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature, +// AttributePoint2DPtr& theStartPointAttr, +// AttributePoint2DPtr& theEndPointAttr) +//{ +// std::string aFeatureKind = theFeature->getKind(); +// std::string aStartAttributeName, anEndAttributeName; +// if (aFeatureKind == SketchPlugin_Line::ID()) { +// aStartAttributeName = SketchPlugin_Line::START_ID(); +// anEndAttributeName = SketchPlugin_Line::END_ID(); +// } +// else if (aFeatureKind == SketchPlugin_Arc::ID()) { +// aStartAttributeName = SketchPlugin_Arc::START_ID(); +// anEndAttributeName = SketchPlugin_Arc::END_ID(); +// } +// if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) { +// theStartPointAttr = std::dynamic_pointer_cast( +// theFeature->attribute(aStartAttributeName)); +// theEndPointAttr = std::dynamic_pointer_cast( +// theFeature->attribute(anEndAttributeName)); +// } +//} +// +//void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete, +// std::set& theFeaturesToUpdate, +// std::map& theTangentFeatures, +// std::map& theCoincidenceToFeature) +//{ +// std::shared_ptr aData = data(); +// +// // Check the base objects are initialized. +// AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( +// aData->attribute(SketchPlugin_Constraint::VALUE())); +// FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); +// ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); +// +// std::set aRefsList = aBaseFeatureResult->data()->refsToMe(); +// std::set aFRefsList = aBaseFeature->data()->refsToMe(); +// aRefsList.insert(aFRefsList.begin(), aFRefsList.end()); +// +// std::set::const_iterator aIt; +// for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { +// std::shared_ptr aAttr = (*aIt); +// FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); +// std::string aRefFeatureKind = aRefFeature->getKind(); +// if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() || +// aRefFeatureKind == SketchPlugin_MultiRotation::ID() || +// aRefFeatureKind == SketchPlugin_MultiTranslation::ID() || +// aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID()) +// theFeaturesToDelete.insert(aRefFeature); +// else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) +// theFeaturesToUpdate.insert(aRefFeature); +// else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) { +// if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion +// /// until tangency between arc and line is implemented +// theFeaturesToDelete.insert(aRefFeature); +// else { +// std::string anAttributeToBeModified; +// AttributePoint2DPtr aTangentPoint; +// ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object(); +// ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object(); +// if (aResult1.get() && aResult2.get()) { +// FeaturePtr aCoincidenceFeature = +// SketchPlugin_ConstraintCoincidence::findCoincidenceFeature +// (ModelAPI_Feature::feature(aResult1), +// ModelAPI_Feature::feature(aResult2)); +// // get the point not lying on the splitting feature +// for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { +// AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(ATTRIBUTE(i)); +// if (!aRefAttr || aRefAttr->isObject()) +// continue; +// AttributePoint2DPtr aPoint = +// std::dynamic_pointer_cast(aRefAttr->attr()); +// if (!aPoint) +// continue; +// if (aPoint->owner() != aBaseFeature) { +// aTangentPoint = aPoint; +// break; +// } +// } +// } +// if (aTangentPoint.get()) { +// FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1); +// std::string anAttributeToBeModified = aFeature1 == aBaseFeature +// ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B(); +// theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint); +// } +// else /// there is not coincident point between tangent constraint +// theFeaturesToDelete.insert(aRefFeature); +// } +// } +// else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) { +// std::string anAttributeToBeModified; +// AttributePoint2DPtr aCoincidentPoint; +// AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A()); +// AttributeRefAttrPtr anAttrB = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B()); +// bool isToFeature = false; +// if (anAttrA->isObject() || anAttrB->isObject()) { /// coincidence to base feature +// FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object()) +// : FeaturePtr(); +// isToFeature = aFeature.get() && aFeature == aBaseFeature; +// anAttributeToBeModified = anAttrA->id(); +// if (!isToFeature) { +// aFeature = anAttrB->isObject() ? ModelAPI_Feature::feature(anAttrB->object()) +// : FeaturePtr(); +// isToFeature = aFeature.get() && aFeature == aBaseFeature; +// anAttributeToBeModified = anAttrB->id(); +// } +// if (isToFeature) +// aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature); +// } +// if (!isToFeature) { /// coincidence to point on base feature +// AttributePtr anAttribute; +// +// if (!anAttrA->isObject()) { +// AttributePtr aCurAttribute = anAttrA->attr(); +// if (aCurAttribute.get()) { +// FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); +// if (aCurFeature.get() && aCurFeature == aBaseFeature) { +// anAttribute = anAttrB->attr(); +// anAttributeToBeModified = anAttrA->id(); +// } +// } +// } +// if (!anAttribute.get() && !anAttrB->isObject()) { +// AttributePtr aCurAttribute = anAttrB->attr(); +// if (aCurAttribute.get()) { +// FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); +// if (aCurFeature.get() && aCurFeature == aBaseFeature) { +// anAttribute = anAttrA->attr(); +// anAttributeToBeModified = anAttrB->id(); +// } +// } +// } +// if (anAttribute.get()) +// aCoincidentPoint = std::dynamic_pointer_cast(anAttribute); +// } +// if (aCoincidentPoint.get() && isToFeature) +// theCoincidenceToFeature[aRefFeature] = std::make_pair(anAttributeToBeModified, +// aCoincidentPoint); +// } +// } +//} +// +//void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature, +// std::map >& theRefs, +// std::list& theRefsToFeature) +//{ +// theRefs.clear(); +// +// std::list aPointAttributes = +// theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); +// std::set aPointAttributesSet; +// +// std::list::const_iterator aPIt = +// aPointAttributes.begin(), aPLast = aPointAttributes.end(); +// for (; aPIt != aPLast; aPIt++) +// aPointAttributesSet.insert(*aPIt); +// +// std::set aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe(); +// std::set aFRefsList = theFeature->data()->refsToMe(); +// aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end()); +// +// std::set::const_iterator aIt; +// for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) { +// AttributePtr anAttr = (*aIt); +// FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner()); +// if (anAttrFeature.get() != this && +// anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { +// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttr); +// if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes +// AttributePtr anAttrInRef = aRefAttr->attr(); +// if (anAttrInRef.get() && +// aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) { +// if (theRefs.find(anAttrInRef) != theRefs.end()) +// theRefs[anAttrInRef].push_back(aRefAttr); +// else { +// std::list anAttrList; +// anAttrList.push_back(aRefAttr); +// theRefs[anAttrInRef] = anAttrList; +// } +// } +// } +// else { /// find attributes referenced to feature itself +// theRefsToFeature.push_back(anAttr); +// } +// } +// } +//} +// +//void SketchPlugin_Trim::updateCoincidenceConstraintsToFeature( +// const std::map, IdToPointPair>& theCoincidenceToFeature, +// const std::set >& theFurtherCoincidences, +// const std::set& theFeatureResults, +// const FeaturePtr& theSplitFeature) +//{ +// if (theCoincidenceToFeature.empty()) +// return; +// +// // we should build coincidence constraints to end of the split feature +// std::set > aNewCoincidencesToSplitFeature; +// AttributePoint2DPtr aStartPointAttr, anEndPointAttr; +// getFeaturePoints(theSplitFeature, aStartPointAttr, anEndPointAttr); +// if (theFurtherCoincidences.find(aStartPointAttr) == theFurtherCoincidences.end()) +// aNewCoincidencesToSplitFeature.insert(aStartPointAttr); +// if (theFurtherCoincidences.find(anEndPointAttr) == theFurtherCoincidences.end()) +// aNewCoincidencesToSplitFeature.insert(anEndPointAttr); +// +// std::map::const_iterator aCIt = theCoincidenceToFeature.begin(), +// aCLast = theCoincidenceToFeature.end(); +//#ifdef DEBUG_SPLIT +// std::cout << std::endl; +// std::cout << "Coincidences to feature(modified):"<< std::endl; +//#endif +// for (; aCIt != aCLast; aCIt++) { +// FeaturePtr aCoincFeature = aCIt->first; +// std::string anAttributeId = aCIt->second.first; +// AttributePoint2DPtr aCoincPoint = aCIt->second.second; +// std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), +// aFCLast = theFurtherCoincidences.end(); +// std::shared_ptr aCoincPnt = aCoincPoint->pnt(); +// AttributePoint2DPtr aFeaturePointAttribute; +// for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { +// AttributePoint2DPtr aFCAttribute = *aFCIt; +// if (aCoincPnt->isEqual(aFCAttribute->pnt())) +// aFeaturePointAttribute = aFCAttribute; +// } +// if (aFeaturePointAttribute.get()) { +// aCoincFeature->refattr(anAttributeId)->setObject(ResultPtr()); +// aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute); +// // create new coincidences to split feature points +// std::set::const_iterator aSFIt = aNewCoincidencesToSplitFeature.begin(), +// aSFLast = aNewCoincidencesToSplitFeature.end(); +// for (; aSFIt != aSFLast; aSFIt++) { +// AttributePoint2DPtr aSFAttribute = *aSFIt; +// if (aCoincPnt->isEqual(aSFAttribute->pnt())) { +// std::string aSecondAttribute = SketchPlugin_Constraint::ENTITY_A(); +// if (anAttributeId == SketchPlugin_Constraint::ENTITY_A()) +// aSecondAttribute = SketchPlugin_Constraint::ENTITY_B(); +// createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// aSFAttribute, aCoincFeature->refattr(aSecondAttribute)->attr()); +// } +// } +// } +// else { +// /// find feature by shape intersected the point +// ResultPtr aResultForCoincidence = *(theFeatureResults.begin()); +// +// if (theFeatureResults.size() > 1) { // try to find point on additional feature +// ResultPtr anAddtionalResult = *(theFeatureResults.begin()++); +// GeomShapePtr aShape = anAddtionalResult->shape(); +// +// std::shared_ptr aPnt2d = aCoincPoint->pnt(); +// std::shared_ptr aPoint = sketch()->to3D(aPnt2d->x(), aPnt2d->y()); +// +// std::shared_ptr aProjectedPoint; +// if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPoint, aProjectedPoint)) +// aResultForCoincidence = anAddtionalResult; +// } +// aCoincFeature->refattr(anAttributeId)->setObject(aResultForCoincidence); +// } +//#ifdef DEBUG_SPLIT +// std::cout << " -" << getFeatureInfo(aCoincFeature) << std::endl; +//#endif +// } +//} +// +//void SketchPlugin_Trim::updateTangentConstraintsToFeature( +// const std::map, IdToPointPair>& theTangentFeatures, +// const std::set >& theFurtherCoincidences) +//{ +// if (theTangentFeatures.empty()) +// return; +// +// std::map::const_iterator aTIt = theTangentFeatures.begin(), +// aTLast = theTangentFeatures.end(); +//#ifdef DEBUG_SPLIT +// std::cout << std::endl; +// std::cout << "Tangencies to feature(modified):"<< std::endl; +//#endif +// for (; aTIt != aTLast; aTIt++) { +// FeaturePtr aTangentFeature = aTIt->first; +// std::string anAttributeId = aTIt->second.first; +// AttributePoint2DPtr aTangentPoint = aTIt->second.second; +// std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), +// aFCLast = theFurtherCoincidences.end(); +// std::shared_ptr aCoincPnt = aTangentPoint->pnt(); +// AttributePoint2DPtr aFeaturePointAttribute; +// /// here we rely on created coincidence between further coincidence point and tangent result +// for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { +// AttributePoint2DPtr aFCAttribute = *aFCIt; +// if (aCoincPnt->isEqual(aFCAttribute->pnt())) +// aFeaturePointAttribute = aFCAttribute; +// } +// if (aFeaturePointAttribute.get()) { +// FeaturePtr aFeature = +// std::dynamic_pointer_cast(aFeaturePointAttribute->owner()); +// aTangentFeature->refattr(anAttributeId)->setObject(getFeatureResult(aFeature)); +// } +//#ifdef DEBUG_SPLIT +// std::cout << " -" << getFeatureInfo(aTangentFeature) << std::endl; +//#endif +// } +//} +// +//void SketchPlugin_Trim::updateRefFeatureConstraints( +// const ResultPtr& theFeatureBaseResult, +// const std::list& theRefsToFeature) +//{ +// std::list::const_iterator anIt = theRefsToFeature.begin(), +// aLast = theRefsToFeature.end(); +// for (; anIt != aLast; anIt++) { +// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anIt); +// if (aRefAttr.get()) +// aRefAttr->setObject(theFeatureBaseResult); +// } +//} +// +//void SketchPlugin_Trim::updateRefAttConstraints( +// const std::map >& theBaseRefAttributes, +// const std::set >& theModifiedAttributes) +//{ +//#ifdef DEBUG_SPLIT +// std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl; +//#endif +// +// std::set >::const_iterator +// anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end(); +// for (; anIt != aLast; anIt++) { +// AttributePtr anAttribute = anIt->first; +// +// /// not found in references +// if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end()) +// continue; +// std::list aRefAttributes = theBaseRefAttributes.at(anAttribute); +// std::list::const_iterator aRefIt = aRefAttributes.begin(), +// aRLast = aRefAttributes.end(); +// +// AttributePtr aNewAttribute = anIt->second; +// for (; aRefIt != aRLast; aRefIt++) { +// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); +// if (aRefAttr.get()) { +// aRefAttr->setAttr(aNewAttribute); +//#ifdef DEBUG_SPLIT +// FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner()); +// std::cout << " -" << getFeatureInfo(aFeature) << std::endl; +//#endif +// } +// } +// } +//} +// +//void SketchPlugin_Trim::splitLine(FeaturePtr& theSplitFeature, +// FeaturePtr& theBaseFeatureModified, +// FeaturePtr& theAfterFeature, +// std::set& thePoints, +// std::set& theCreatedFeatures, +// std::set>& theModifiedAttributes) +//{ +// std::set aCreatedFeatures; +// FeaturePtr aConstraintFeature; +// theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature +// +// SketchPlugin_Sketch* aSketch = sketch(); +// if (!aSketch) +// return; +// +// AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( +// data()->attribute(SketchPlugin_Constraint::VALUE())); +// FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); +// std::string aFeatureKind = aBaseFeature->getKind(); +// if (aFeatureKind != SketchPlugin_Line::ID()) +// return; +// +// AttributePoint2DPtr aFirstPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); +// AttributePoint2DPtr aSecondPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); +// AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; +// +// getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); +// if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { +// setError("Error: Feature has no start and end points."); +// return; +// } +// +// arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase, +// aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +// +//#ifdef DEBUG_SPLIT +// std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; +// std::cout << "Start point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl; +// std::cout << "1st point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl; +// std::cout << "2nd point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl; +// std::cout << "End point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; +//#endif +// +// /// create a split feature +// theSplitFeature = +// createLineFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +// theCreatedFeatures.insert(theSplitFeature); +// +// // before split feature +// if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { +// theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase, +// theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); +// } +// else { +// theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here +// /// move end arc point to start of split +// } +// +// // after split feature +// if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { +// FeaturePtr aFeature; +// if (!theBaseFeatureModified.get()) { +// aFeature = aBaseFeature; ///< use base feature to store all constraints here +// fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), aSecondPointAttrOfSplit); +// aFeature->execute(); // to update result +// } +// else { +// aFeature = createLineFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); +// theCreatedFeatures.insert(aFeature); +// theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, +// aFeature->attribute(SketchPlugin_Line::END_ID()))); +// } +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theSplitFeature->attribute(SketchPlugin_Line::END_ID()), +// aFeature->attribute(SketchPlugin_Line::START_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// +// thePoints.insert(std::dynamic_pointer_cast +// (aFeature->attribute(SketchPlugin_Line::START_ID()))); +// thePoints.insert(std::dynamic_pointer_cast +// (aFeature->attribute(SketchPlugin_Line::END_ID()))); +// +// if (!theBaseFeatureModified.get()) +// theBaseFeatureModified = aFeature; +// else +// theAfterFeature = aFeature; +// } +// else { +// thePoints.insert(std::dynamic_pointer_cast +// (theSplitFeature->attribute(SketchPlugin_Line::END_ID()))); +// theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, +// theSplitFeature->attribute(SketchPlugin_Line::END_ID()))); +// } +// // base split, that is defined before split feature should be changed at end +// // (after the after feature creation). Otherwise modified value will be used in after feature +// // before split feature +// if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { +// /// move end arc point to start of split +// fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), +// aFirstPointAttrOfSplit); +// theBaseFeatureModified->execute(); // to update result +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), +// theSplitFeature->attribute(SketchPlugin_Line::START_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Line::START_ID()))); +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()))); +// } +// else +// thePoints.insert(std::dynamic_pointer_cast +// (theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); +// +// // additional constraints between split and base features +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), +// getFeatureResult(aBaseFeature), +// getFeatureResult(theSplitFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// if (theAfterFeature.get()) { +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), +// getFeatureResult(aBaseFeature), +// getFeatureResult(theAfterFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// } +//} +// +//void SketchPlugin_Trim::splitArc(FeaturePtr& theSplitFeature, +// FeaturePtr& theBaseFeatureModified, +// FeaturePtr& theAfterFeature, +// std::set& thePoints, +// std::set& theCreatedFeatures, +// std::set>& theModifiedAttributes) +//{ +// std::set aCreatedFeatures; +// FeaturePtr aConstraintFeature; +// theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature +// +// SketchPlugin_Sketch* aSketch = sketch(); +// if (!aSketch) +// return; +// +// AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( +// data()->attribute(SketchPlugin_Constraint::VALUE())); +// FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); +// std::string aFeatureKind = aBaseFeature->getKind(); +// if (aFeatureKind != SketchPlugin_Arc::ID()) +// return; +// +// AttributePoint2DPtr aFirstPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); +// AttributePoint2DPtr aSecondPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); +// AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; +// getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); +// if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { +// setError("Error: Feature has no start and end points."); +// return; +// } +// +// // manually change type of arc to avoid incorrect self-constrainting of the tangent arc +// aBaseFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( +// SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); +// +// arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase, +// aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +//#ifdef DEBUG_SPLIT +// std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; +// std::cout << "Start point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl; +// std::cout << "1st point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl; +// std::cout << "2nd point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl; +// std::cout << "End point: " << +// ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; +//#endif +// +// /// split feature +// theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +// theCreatedFeatures.insert(theSplitFeature); +// +// // before split feature +// if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { +// theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase, +// theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); +// } +// else { +// theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here +// /// move end arc point to start of split +// } +// +// // after split feature +// if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { +// FeaturePtr aFeature; +// if (!theBaseFeatureModified.get()) { +// aFeature = aBaseFeature; ///< use base feature to store all constraints here +// fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttrOfSplit); +// aFeature->execute(); // to update result +// } +// else { +// aFeature = createArcFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); +// theCreatedFeatures.insert(aFeature); +// theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, +// aFeature->attribute(SketchPlugin_Arc::END_ID()))); +// } +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theSplitFeature->attribute(SketchPlugin_Arc::END_ID()), +// aFeature->attribute(SketchPlugin_Arc::START_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// +// thePoints.insert(std::dynamic_pointer_cast +// (aFeature->attribute(SketchPlugin_Arc::START_ID()))); +// thePoints.insert(std::dynamic_pointer_cast +// (aFeature->attribute(SketchPlugin_Arc::END_ID()))); +// +// if (!theBaseFeatureModified.get()) +// theBaseFeatureModified = aFeature; +// else +// theAfterFeature = aFeature; +// } +// else { +// thePoints.insert(std::dynamic_pointer_cast +// (theSplitFeature->attribute(SketchPlugin_Arc::END_ID()))); +// theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, +// theSplitFeature->attribute(SketchPlugin_Arc::END_ID()))); +// } +// // base split, that is defined before split feature should be changed at end +// // (after the after feature creation). Otherwise modified value will be used in after feature +// // before split feature +// if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { +// /// move end arc point to start of split +// fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), +// aFirstPointAttrOfSplit); +// theBaseFeatureModified->execute(); // to update result +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), +// theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); +// } +// else +// thePoints.insert(std::dynamic_pointer_cast +// (theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); +// +// // additional constraints between split and base features +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), +// getFeatureResult(aBaseFeature), +// getFeatureResult(theSplitFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), +// getFeatureResult(theSplitFeature), +// getFeatureResult(aBaseFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// if (theAfterFeature.get()) { +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), +// getFeatureResult(aBaseFeature), +// getFeatureResult(theAfterFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), +// getFeatureResult(theSplitFeature), +// getFeatureResult(theAfterFeature)); +// theCreatedFeatures.insert(aConstraintFeature); +// } +//} +// +//void SketchPlugin_Trim::splitCircle(FeaturePtr& theSplitFeature, +// FeaturePtr& theBaseFeatureModified, +// FeaturePtr& theAfterFeature, +// std::set& thePoints, +// std::set& theCreatedFeatures, +// std::set>& theModifiedAttributes) +//{ +// std::set aCreatedFeatures; +// FeaturePtr aConstraintFeature; +// theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature +// +// SketchPlugin_Sketch* aSketch = sketch(); +// if (!aSketch) +// return; +// +// AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( +// data()->attribute(SketchPlugin_Constraint::VALUE())); +// FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); +// std::string aFeatureKind = aBaseFeature->getKind(); +// if (aFeatureKind != SketchPlugin_Circle::ID()) +// return; +// +// AttributePoint2DPtr aFirstPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); +// AttributePoint2DPtr aSecondPointAttrOfSplit = +// getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); +// +// /// split feature +// theSplitFeature = +// createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +// bool aSplitReversed = std::dynamic_pointer_cast(theSplitFeature)->isReversed(); +// theCreatedFeatures.insert(theSplitFeature); +// +// /// base feature is a left part of the circle +// theBaseFeatureModified = createArcFeature(aBaseFeature, +// aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +// std::dynamic_pointer_cast( +// theBaseFeatureModified)->setReversed(!aSplitReversed); +// theBaseFeatureModified->execute(); +// +// theModifiedAttributes.insert( +// std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), +// theBaseFeatureModified->attribute(SketchPlugin_Arc::CENTER_ID()))); +// +// theCreatedFeatures.insert(theBaseFeatureModified); +// +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); +// thePoints.insert(std::dynamic_pointer_cast +// (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); +// +// // additional constraints between split and base features +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), +// theSplitFeature->attribute(SketchPlugin_Arc::END_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), +// theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()), +// theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); +// theCreatedFeatures.insert(aConstraintFeature); +// +// aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), +// getFeatureResult(theSplitFeature), +// getFeatureResult(theBaseFeatureModified)); +// theCreatedFeatures.insert(aConstraintFeature); +//} +// +//void SketchPlugin_Trim::arrangePointsOnLine( +// const AttributePoint2DPtr& theStartPointAttr, +// const AttributePoint2DPtr& theEndPointAttr, +// AttributePoint2DPtr& theFirstPointAttr, +// AttributePoint2DPtr& theLastPointAttr) const +//{ +// // if first point is closer to last point, swap first and last values +// if (theStartPointAttr->pnt()->distance(theFirstPointAttr->pnt()) > +// theStartPointAttr->pnt()->distance(theLastPointAttr->pnt())) { +// AttributePoint2DPtr aTmpPoint = theFirstPointAttr; +// theFirstPointAttr = theLastPointAttr; +// theLastPointAttr = aTmpPoint; +// } +//} +// +//void SketchPlugin_Trim::arrangePointsOnArc( +// const FeaturePtr& theArc, +// const std::shared_ptr& theStartPointAttr, +// const std::shared_ptr& theEndPointAttr, +// std::shared_ptr& theFirstPointAttr, +// std::shared_ptr& theSecondPointAttr) const +//{ +// static const double anAngleTol = 1.e-12; +// +// std::shared_ptr aCenter = std::dynamic_pointer_cast( +// theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); +// bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value(); +// +// // collect directions to each point +// std::shared_ptr aStartDir( +// new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy()))); +// std::shared_ptr aFirstPtDir( +// new GeomAPI_Dir2d(theFirstPointAttr->pnt()->xy()->decreased(aCenter->xy()))); +// std::shared_ptr aSecondPtDir( +// new GeomAPI_Dir2d(theSecondPointAttr->pnt()->xy()->decreased(aCenter->xy()))); +// +// // sort points by their angular values +// double aFirstPtAngle = aStartDir->angle(aFirstPtDir); +// double aSecondPtAngle = aStartDir->angle(aSecondPtDir); +// double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI; +// if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.)) +// aFirstPtAngle += aPeriod; +// if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.)) +// aSecondPtAngle += aPeriod; +// +// if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) { +// AttributePoint2DPtr aTmpPoint = theFirstPointAttr; +// theFirstPointAttr = theSecondPointAttr; +// theSecondPointAttr = aTmpPoint; +// } +//} +// +//void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute, +// const AttributePtr& theSourceAttribute) +//{ +// std::string anAttributeType = theModifiedAttribute->attributeType(); +// if (anAttributeType == GeomDataAPI_Point2D::typeId()) { +// AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast( +// theModifiedAttribute); +// AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast( +// theSourceAttribute); +// +// if (aModifiedAttribute.get() && aSourceAttribute.get()) +// aModifiedAttribute->setValue(aSourceAttribute->pnt()); +// } +// else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) { +// AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast( +// theModifiedAttribute); +// AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast( +// theSourceAttribute); +// +// if (aModifiedAttribute.get() && aSourceAttribute.get()) +// aModifiedAttribute->setValue(aSourceAttribute->value()); +// } +// else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) { +// AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast( +// theModifiedAttribute); +// AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast( +// theSourceAttribute); +// if (!aSourceRefAttr.get()) +// aRefAttributeToFill->setAttr(theSourceAttribute); +// else { +// if (aSourceRefAttr->isObject()) +// aRefAttributeToFill->setObject(aSourceRefAttr->object()); +// else +// aRefAttributeToFill->setAttr(aSourceRefAttr->attr()); +// } +// } +//} +// +//FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature, +// const AttributePtr& theFirstPointAttr, +// const AttributePtr& theSecondPointAttr) +//{ +// FeaturePtr aFeature; +// SketchPlugin_Sketch* aSketch = sketch(); +// if (!aSketch || !theBaseFeature.get()) +// return aFeature; +// +// aFeature = aSketch->addFeature(SketchPlugin_Line::ID()); +// +// fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr); +// fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr); +// +// fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), +// theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); +// +// aFeature->execute(); // to obtain result +// +// return aFeature; +//} +// +//FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, +// const AttributePtr& theFirstPointAttr, +// const AttributePtr& theSecondPointAttr) +//{ +// FeaturePtr aFeature; +// SketchPlugin_Sketch* aSketch = sketch(); +// if (!aSketch || !theBaseFeature.get()) +// return aFeature; +// +// std::string aCenterAttributeId; +// if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) +// aCenterAttributeId = SketchPlugin_Arc::CENTER_ID(); +// else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID()) +// aCenterAttributeId = SketchPlugin_Circle::CENTER_ID(); +// +// if (aCenterAttributeId.empty()) +// return aFeature; +// +// aFeature = aSketch->addFeature(SketchPlugin_Arc::ID()); +// // update fillet arc: make the arc correct for sure, so, it is not needed to process +// // the "attribute updated" +// // by arc; moreover, it may cause cyclicity in hte mechanism of updater +// bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true); +// +// aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( +// SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); +// +// fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()), +// theBaseFeature->attribute(aCenterAttributeId)); +// fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr); +// fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr); +// +// fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), +// theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); +// +// /// fill referersed state of created arc as it is on the base arc +// if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) { +// bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value(); +// aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed); +// } +// aFeature->data()->blockSendAttributeUpdated(aWasBlocked); +// aFeature->execute(); // to obtain result +// +// return aFeature; +//} +// +//FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId, +// const AttributePtr& theFirstAttribute, +// const AttributePtr& theSecondAttribute) +//{ +// FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); +// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( +// aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); +// aRefAttr->setAttr(theFirstAttribute); +// +// aRefAttr = std::dynamic_pointer_cast( +// aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); +// aRefAttr->setAttr(theSecondAttribute); +// +// return aConstraint; +//} +// +//FeaturePtr SketchPlugin_Trim::createConstraintForObjects( +// const std::string& theConstraintId, +// const ObjectPtr& theFirstObject, +// const ObjectPtr& theSecondObject) +//{ +// FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); +// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( +// aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); +// aRefAttr->setObject(theFirstObject); +// +// aRefAttr = std::dynamic_pointer_cast( +// aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); +// aRefAttr->setObject(theSecondObject); +// +// return aConstraint; +//} +// +//void SketchPlugin_Trim::updateFeaturesAfterSplit( +// const std::set& theFeaturesToUpdate) +//{ +// std::set::const_iterator anIt = theFeaturesToUpdate.begin(), +// aLast = theFeaturesToUpdate.end(); +// for (; anIt != aLast; anIt++) { +// FeaturePtr aRefFeature = std::dynamic_pointer_cast(*anIt); +// std::string aRefFeatureKind = aRefFeature->getKind(); +// if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) { +// std::shared_ptr aLenghtFeature = +// std::dynamic_pointer_cast(*anIt); +// if (aLenghtFeature.get()) { +// std::shared_ptr aValueAttr = std::dynamic_pointer_cast< +// ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Constraint::VALUE())); +// double aValue; +// if (aLenghtFeature->computeLenghtValue(aValue) && aValueAttr.get()) +// aValueAttr->setValue(aValue); +// } +// } +// } +//} +// +//std::shared_ptr SketchPlugin_Trim::getFeatureResult( +// const std::shared_ptr& theFeature) +//{ +// std::shared_ptr aResult; +// +// std::string aFeatureKind = theFeature->getKind(); +// if (aFeatureKind == SketchPlugin_Line::ID()) +// aResult = theFeature->firstResult(); +// else if (aFeatureKind == SketchPlugin_Arc::ID()) +// aResult = theFeature->lastResult(); +// else if (aFeatureKind == SketchPlugin_Circle::ID()) +// aResult = theFeature->lastResult(); +// +// return aResult; +//} +// +//std::set > SketchPlugin_Trim::getEdgeAttributes( +// const std::shared_ptr& theFeature) +//{ +// std::set > anAttributes; +// +// std::string aFeatureKind = theFeature->getKind(); +// if (aFeatureKind == SketchPlugin_Line::ID()) { +// anAttributes.insert(theFeature->attribute(SketchPlugin_Line::START_ID())); +// anAttributes.insert(theFeature->attribute(SketchPlugin_Line::END_ID())); +// } +// else if (aFeatureKind == SketchPlugin_Arc::ID()) { +// anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::START_ID())); +// anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::END_ID())); +// } +// else if (aFeatureKind == SketchPlugin_Circle::ID()) { +// } +// +// return anAttributes; +//} +// +//#ifdef _DEBUG +//std::string SketchPlugin_Trim::getFeatureInfo( +// const std::shared_ptr& theFeature, +// const bool isUseAttributesInfo) +//{ +// std::string anInfo; +// if (!theFeature.get()) { +// return "none"; +// } +// +// if (theFeature->data()->isValid()) +// anInfo.append(theFeature->data()->name().c_str()); +// +// if (isUseAttributesInfo) { +// std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(theFeature, +// getEdgeAttributes(theFeature)); +// /// processing of feature with point 2d attributes, like line, arc, circle +// if (!aPointsInfo.empty()) { +// anInfo += ": "; +// anInfo += "\n"; +// anInfo += aPointsInfo; +// } +// else { /// process constraint coincidence, find points in ref attr attributes +// std::list anAttrs = theFeature->data()->attributes( +// ModelAPI_AttributeRefAttr::typeId()); +// std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); +// std::string anAttributesInfo; +// for(; anIt != aLast; anIt++) { +// if (!anAttributesInfo.empty()) { +// anAttributesInfo.append(", "); +// anAttributesInfo += "\n"; +// } +// AttributePtr anAttr = *anIt; +// std::string aValue = "not defined"; +// std::string aType = anAttr->attributeType(); +// if (aType == ModelAPI_AttributeRefAttr::typeId()) { +// std::shared_ptr aRefAttr = +// std::dynamic_pointer_cast(anAttr); +// if (aRefAttr.get()) { +// if (aRefAttr->isObject()) { +// FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); +// aValue = "" + getFeatureInfo(aFeature, false); +// } +// else { +// AttributePtr anAttribute = aRefAttr->attr(); +// if (anAttribute.get()) { +// FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); +// aValue = "" + ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) + +// " [" + getFeatureInfo(aFeature, false) + "]"; +// } +// } +// } +// } +// anAttributesInfo.append(" " + anAttr->id() + ": " + aValue); +// } +// if (!anAttributesInfo.empty()) +// anInfo = anInfo + "\n" + anAttributesInfo; +// } +// } +// return anInfo; +//} +//#endif + +//******************************************************************** +bool SketchPlugin_Trim::useGraphicIntersection() const { - std::shared_ptr aData = data(); - - // Check the base objects are initialized. - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); - - std::set aRefsList = aBaseFeatureResult->data()->refsToMe(); - std::set aFRefsList = aBaseFeature->data()->refsToMe(); - aRefsList.insert(aFRefsList.begin(), aFRefsList.end()); - - std::set::const_iterator aIt; - for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { - std::shared_ptr aAttr = (*aIt); - FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); - std::string aRefFeatureKind = aRefFeature->getKind(); - if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() || - aRefFeatureKind == SketchPlugin_MultiRotation::ID() || - aRefFeatureKind == SketchPlugin_MultiTranslation::ID() || - aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID()) - theFeaturesToDelete.insert(aRefFeature); - else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) - theFeaturesToUpdate.insert(aRefFeature); - else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) { - if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion - /// until tangency between arc and line is implemented - theFeaturesToDelete.insert(aRefFeature); - else { - std::string anAttributeToBeModified; - AttributePoint2DPtr aTangentPoint; - ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object(); - ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object(); - if (aResult1.get() && aResult2.get()) { - FeaturePtr aCoincidenceFeature = - SketchPlugin_ConstraintCoincidence::findCoincidenceFeature - (ModelAPI_Feature::feature(aResult1), - ModelAPI_Feature::feature(aResult2)); - // get the point not lying on the splitting feature - for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { - AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(ATTRIBUTE(i)); - if (!aRefAttr || aRefAttr->isObject()) - continue; - AttributePoint2DPtr aPoint = - std::dynamic_pointer_cast(aRefAttr->attr()); - if (!aPoint) - continue; - if (aPoint->owner() != aBaseFeature) { - aTangentPoint = aPoint; - break; - } - } - } - if (aTangentPoint.get()) { - FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1); - std::string anAttributeToBeModified = aFeature1 == aBaseFeature - ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B(); - theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint); - } - else /// there is not coincident point between tangent constraint - theFeaturesToDelete.insert(aRefFeature); - } - } - else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) { - std::string anAttributeToBeModified; - AttributePoint2DPtr aCoincidentPoint; - AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A()); - AttributeRefAttrPtr anAttrB = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B()); - bool isToFeature = false; - if (anAttrA->isObject() || anAttrB->isObject()) { /// coincidence to base feature - FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object()) - : FeaturePtr(); - isToFeature = aFeature.get() && aFeature == aBaseFeature; - anAttributeToBeModified = anAttrA->id(); - if (!isToFeature) { - aFeature = anAttrB->isObject() ? ModelAPI_Feature::feature(anAttrB->object()) - : FeaturePtr(); - isToFeature = aFeature.get() && aFeature == aBaseFeature; - anAttributeToBeModified = anAttrB->id(); - } - if (isToFeature) - aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature); - } - if (!isToFeature) { /// coincidence to point on base feature - AttributePtr anAttribute; - - if (!anAttrA->isObject()) { - AttributePtr aCurAttribute = anAttrA->attr(); - if (aCurAttribute.get()) { - FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); - if (aCurFeature.get() && aCurFeature == aBaseFeature) { - anAttribute = anAttrB->attr(); - anAttributeToBeModified = anAttrA->id(); - } - } - } - if (!anAttribute.get() && !anAttrB->isObject()) { - AttributePtr aCurAttribute = anAttrB->attr(); - if (aCurAttribute.get()) { - FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); - if (aCurFeature.get() && aCurFeature == aBaseFeature) { - anAttribute = anAttrA->attr(); - anAttributeToBeModified = anAttrB->id(); - } - } - } - if (anAttribute.get()) - aCoincidentPoint = std::dynamic_pointer_cast(anAttribute); - } - if (aCoincidentPoint.get() && isToFeature) - theCoincidenceToFeature[aRefFeature] = std::make_pair(anAttributeToBeModified, - aCoincidentPoint); - } - } -} - -void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature, - std::map >& theRefs, - std::list& theRefsToFeature) -{ - theRefs.clear(); - - std::list aPointAttributes = - theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::set aPointAttributesSet; - - std::list::const_iterator aPIt = - aPointAttributes.begin(), aPLast = aPointAttributes.end(); - for (; aPIt != aPLast; aPIt++) - aPointAttributesSet.insert(*aPIt); - - std::set aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe(); - std::set aFRefsList = theFeature->data()->refsToMe(); - aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end()); - - std::set::const_iterator aIt; - for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) { - AttributePtr anAttr = (*aIt); - FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner()); - if (anAttrFeature.get() != this && - anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttr); - if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes - AttributePtr anAttrInRef = aRefAttr->attr(); - if (anAttrInRef.get() && - aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) { - if (theRefs.find(anAttrInRef) != theRefs.end()) - theRefs[anAttrInRef].push_back(aRefAttr); - else { - std::list anAttrList; - anAttrList.push_back(aRefAttr); - theRefs[anAttrInRef] = anAttrList; - } - } - } - else { /// find attributes referenced to feature itself - theRefsToFeature.push_back(anAttr); - } - } - } -} - -void SketchPlugin_Trim::updateCoincidenceConstraintsToFeature( - const std::map, IdToPointPair>& theCoincidenceToFeature, - const std::set >& theFurtherCoincidences, - const std::set& theFeatureResults, - const FeaturePtr& theSplitFeature) -{ - if (theCoincidenceToFeature.empty()) - return; - - // we should build coincidence constraints to end of the split feature - std::set > aNewCoincidencesToSplitFeature; - AttributePoint2DPtr aStartPointAttr, anEndPointAttr; - getFeaturePoints(theSplitFeature, aStartPointAttr, anEndPointAttr); - if (theFurtherCoincidences.find(aStartPointAttr) == theFurtherCoincidences.end()) - aNewCoincidencesToSplitFeature.insert(aStartPointAttr); - if (theFurtherCoincidences.find(anEndPointAttr) == theFurtherCoincidences.end()) - aNewCoincidencesToSplitFeature.insert(anEndPointAttr); - - std::map::const_iterator aCIt = theCoincidenceToFeature.begin(), - aCLast = theCoincidenceToFeature.end(); -#ifdef DEBUG_SPLIT - std::cout << std::endl; - std::cout << "Coincidences to feature(modified):"<< std::endl; -#endif - for (; aCIt != aCLast; aCIt++) { - FeaturePtr aCoincFeature = aCIt->first; - std::string anAttributeId = aCIt->second.first; - AttributePoint2DPtr aCoincPoint = aCIt->second.second; - std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), - aFCLast = theFurtherCoincidences.end(); - std::shared_ptr aCoincPnt = aCoincPoint->pnt(); - AttributePoint2DPtr aFeaturePointAttribute; - for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { - AttributePoint2DPtr aFCAttribute = *aFCIt; - if (aCoincPnt->isEqual(aFCAttribute->pnt())) - aFeaturePointAttribute = aFCAttribute; - } - if (aFeaturePointAttribute.get()) { - aCoincFeature->refattr(anAttributeId)->setObject(ResultPtr()); - aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute); - // create new coincidences to split feature points - std::set::const_iterator aSFIt = aNewCoincidencesToSplitFeature.begin(), - aSFLast = aNewCoincidencesToSplitFeature.end(); - for (; aSFIt != aSFLast; aSFIt++) { - AttributePoint2DPtr aSFAttribute = *aSFIt; - if (aCoincPnt->isEqual(aSFAttribute->pnt())) { - std::string aSecondAttribute = SketchPlugin_Constraint::ENTITY_A(); - if (anAttributeId == SketchPlugin_Constraint::ENTITY_A()) - aSecondAttribute = SketchPlugin_Constraint::ENTITY_B(); - createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - aSFAttribute, aCoincFeature->refattr(aSecondAttribute)->attr()); - } - } - } - else { - /// find feature by shape intersected the point - ResultPtr aResultForCoincidence = *(theFeatureResults.begin()); - - if (theFeatureResults.size() > 1) { // try to find point on additional feature - ResultPtr anAddtionalResult = *(theFeatureResults.begin()++); - GeomShapePtr aShape = anAddtionalResult->shape(); - - std::shared_ptr aPnt2d = aCoincPoint->pnt(); - std::shared_ptr aPoint = sketch()->to3D(aPnt2d->x(), aPnt2d->y()); - - std::shared_ptr aProjectedPoint; - if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPoint, aProjectedPoint)) - aResultForCoincidence = anAddtionalResult; - } - aCoincFeature->refattr(anAttributeId)->setObject(aResultForCoincidence); - } -#ifdef DEBUG_SPLIT - std::cout << " -" << getFeatureInfo(aCoincFeature) << std::endl; -#endif - } -} - -void SketchPlugin_Trim::updateTangentConstraintsToFeature( - const std::map, IdToPointPair>& theTangentFeatures, - const std::set >& theFurtherCoincidences) -{ - if (theTangentFeatures.empty()) - return; - - std::map::const_iterator aTIt = theTangentFeatures.begin(), - aTLast = theTangentFeatures.end(); -#ifdef DEBUG_SPLIT - std::cout << std::endl; - std::cout << "Tangencies to feature(modified):"<< std::endl; -#endif - for (; aTIt != aTLast; aTIt++) { - FeaturePtr aTangentFeature = aTIt->first; - std::string anAttributeId = aTIt->second.first; - AttributePoint2DPtr aTangentPoint = aTIt->second.second; - std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), - aFCLast = theFurtherCoincidences.end(); - std::shared_ptr aCoincPnt = aTangentPoint->pnt(); - AttributePoint2DPtr aFeaturePointAttribute; - /// here we rely on created coincidence between further coincidence point and tangent result - for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { - AttributePoint2DPtr aFCAttribute = *aFCIt; - if (aCoincPnt->isEqual(aFCAttribute->pnt())) - aFeaturePointAttribute = aFCAttribute; - } - if (aFeaturePointAttribute.get()) { - FeaturePtr aFeature = - std::dynamic_pointer_cast(aFeaturePointAttribute->owner()); - aTangentFeature->refattr(anAttributeId)->setObject(getFeatureResult(aFeature)); - } -#ifdef DEBUG_SPLIT - std::cout << " -" << getFeatureInfo(aTangentFeature) << std::endl; -#endif - } -} - -void SketchPlugin_Trim::updateRefFeatureConstraints( - const ResultPtr& theFeatureBaseResult, - const std::list& theRefsToFeature) -{ - std::list::const_iterator anIt = theRefsToFeature.begin(), - aLast = theRefsToFeature.end(); - for (; anIt != aLast; anIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anIt); - if (aRefAttr.get()) - aRefAttr->setObject(theFeatureBaseResult); - } -} - -void SketchPlugin_Trim::updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes) -{ -#ifdef DEBUG_SPLIT - std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl; -#endif - - std::set >::const_iterator - anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end(); - for (; anIt != aLast; anIt++) { - AttributePtr anAttribute = anIt->first; - - /// not found in references - if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end()) - continue; - std::list aRefAttributes = theBaseRefAttributes.at(anAttribute); - std::list::const_iterator aRefIt = aRefAttributes.begin(), - aRLast = aRefAttributes.end(); - - AttributePtr aNewAttribute = anIt->second; - for (; aRefIt != aRLast; aRefIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); - if (aRefAttr.get()) { - aRefAttr->setAttr(aNewAttribute); -#ifdef DEBUG_SPLIT - FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - std::cout << " -" << getFeatureInfo(aFeature) << std::endl; -#endif - } - } - } -} - -void SketchPlugin_Trim::splitLine(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeatureModified, - FeaturePtr& theAfterFeature, - std::set& thePoints, - std::set& theCreatedFeatures, - std::set>& theModifiedAttributes) -{ - std::set aCreatedFeatures; - FeaturePtr aConstraintFeature; - theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return; - - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::string aFeatureKind = aBaseFeature->getKind(); - if (aFeatureKind != SketchPlugin_Line::ID()) - return; - - AttributePoint2DPtr aFirstPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributePoint2DPtr aSecondPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); - if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { - setError("Error: Feature has no start and end points."); - return; - } - - arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase, - aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - -#ifdef DEBUG_SPLIT - std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; - std::cout << "Start point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl; - std::cout << "1st point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl; - std::cout << "2nd point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl; - std::cout << "End point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; -#endif - - /// create a split feature - theSplitFeature = - createLineFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - theCreatedFeatures.insert(theSplitFeature); - - // before split feature - if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase, - theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); - } - else { - theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here - /// move end arc point to start of split - } - - // after split feature - if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { - FeaturePtr aFeature; - if (!theBaseFeatureModified.get()) { - aFeature = aBaseFeature; ///< use base feature to store all constraints here - fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), aSecondPointAttrOfSplit); - aFeature->execute(); // to update result - } - else { - aFeature = createLineFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); - theCreatedFeatures.insert(aFeature); - theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, - aFeature->attribute(SketchPlugin_Line::END_ID()))); - } - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theSplitFeature->attribute(SketchPlugin_Line::END_ID()), - aFeature->attribute(SketchPlugin_Line::START_ID())); - theCreatedFeatures.insert(aConstraintFeature); - - thePoints.insert(std::dynamic_pointer_cast - (aFeature->attribute(SketchPlugin_Line::START_ID()))); - thePoints.insert(std::dynamic_pointer_cast - (aFeature->attribute(SketchPlugin_Line::END_ID()))); - - if (!theBaseFeatureModified.get()) - theBaseFeatureModified = aFeature; - else - theAfterFeature = aFeature; - } - else { - thePoints.insert(std::dynamic_pointer_cast - (theSplitFeature->attribute(SketchPlugin_Line::END_ID()))); - theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, - theSplitFeature->attribute(SketchPlugin_Line::END_ID()))); - } - // base split, that is defined before split feature should be changed at end - // (after the after feature creation). Otherwise modified value will be used in after feature - // before split feature - if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - /// move end arc point to start of split - fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), - aFirstPointAttrOfSplit); - theBaseFeatureModified->execute(); // to update result - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), - theSplitFeature->attribute(SketchPlugin_Line::START_ID())); - theCreatedFeatures.insert(aConstraintFeature); - - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Line::START_ID()))); - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()))); - } - else - thePoints.insert(std::dynamic_pointer_cast - (theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); - - // additional constraints between split and base features - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); - theCreatedFeatures.insert(aConstraintFeature); - if (theAfterFeature.get()) { - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); - theCreatedFeatures.insert(aConstraintFeature); - } -} - -void SketchPlugin_Trim::splitArc(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeatureModified, - FeaturePtr& theAfterFeature, - std::set& thePoints, - std::set& theCreatedFeatures, - std::set>& theModifiedAttributes) -{ - std::set aCreatedFeatures; - FeaturePtr aConstraintFeature; - theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return; - - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::string aFeatureKind = aBaseFeature->getKind(); - if (aFeatureKind != SketchPlugin_Arc::ID()) - return; - - AttributePoint2DPtr aFirstPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributePoint2DPtr aSecondPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); - if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { - setError("Error: Feature has no start and end points."); - return; - } - - // manually change type of arc to avoid incorrect self-constrainting of the tangent arc - aBaseFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( - SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); - - arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase, - aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); -#ifdef DEBUG_SPLIT - std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; - std::cout << "Start point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl; - std::cout << "1st point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl; - std::cout << "2nd point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl; - std::cout << "End point: " << - ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; -#endif - - /// split feature - theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - theCreatedFeatures.insert(theSplitFeature); - - // before split feature - if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase, - theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); - } - else { - theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here - /// move end arc point to start of split - } - - // after split feature - if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { - FeaturePtr aFeature; - if (!theBaseFeatureModified.get()) { - aFeature = aBaseFeature; ///< use base feature to store all constraints here - fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttrOfSplit); - aFeature->execute(); // to update result - } - else { - aFeature = createArcFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); - theCreatedFeatures.insert(aFeature); - theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, - aFeature->attribute(SketchPlugin_Arc::END_ID()))); - } - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theSplitFeature->attribute(SketchPlugin_Arc::END_ID()), - aFeature->attribute(SketchPlugin_Arc::START_ID())); - theCreatedFeatures.insert(aConstraintFeature); - - thePoints.insert(std::dynamic_pointer_cast - (aFeature->attribute(SketchPlugin_Arc::START_ID()))); - thePoints.insert(std::dynamic_pointer_cast - (aFeature->attribute(SketchPlugin_Arc::END_ID()))); - - if (!theBaseFeatureModified.get()) - theBaseFeatureModified = aFeature; - else - theAfterFeature = aFeature; - } - else { - thePoints.insert(std::dynamic_pointer_cast - (theSplitFeature->attribute(SketchPlugin_Arc::END_ID()))); - theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, - theSplitFeature->attribute(SketchPlugin_Arc::END_ID()))); - } - // base split, that is defined before split feature should be changed at end - // (after the after feature creation). Otherwise modified value will be used in after feature - // before split feature - if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - /// move end arc point to start of split - fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), - aFirstPointAttrOfSplit); - theBaseFeatureModified->execute(); // to update result - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), - theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); - theCreatedFeatures.insert(aConstraintFeature); - - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); - } - else - thePoints.insert(std::dynamic_pointer_cast - (theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); - - // additional constraints between split and base features - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); - theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(aBaseFeature)); - theCreatedFeatures.insert(aConstraintFeature); - if (theAfterFeature.get()) { - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); - theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theAfterFeature)); - theCreatedFeatures.insert(aConstraintFeature); - } -} - -void SketchPlugin_Trim::splitCircle(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeatureModified, - FeaturePtr& theAfterFeature, - std::set& thePoints, - std::set& theCreatedFeatures, - std::set>& theModifiedAttributes) -{ - std::set aCreatedFeatures; - FeaturePtr aConstraintFeature; - theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return; - - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::string aFeatureKind = aBaseFeature->getKind(); - if (aFeatureKind != SketchPlugin_Circle::ID()) - return; - - AttributePoint2DPtr aFirstPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributePoint2DPtr aSecondPointAttrOfSplit = - getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - - /// split feature - theSplitFeature = - createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - bool aSplitReversed = std::dynamic_pointer_cast(theSplitFeature)->isReversed(); - theCreatedFeatures.insert(theSplitFeature); - - /// base feature is a left part of the circle - theBaseFeatureModified = createArcFeature(aBaseFeature, - aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - std::dynamic_pointer_cast( - theBaseFeatureModified)->setReversed(!aSplitReversed); - theBaseFeatureModified->execute(); - - theModifiedAttributes.insert( - std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), - theBaseFeatureModified->attribute(SketchPlugin_Arc::CENTER_ID()))); - - theCreatedFeatures.insert(theBaseFeatureModified); - - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); - thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); - - // additional constraints between split and base features - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), - theSplitFeature->attribute(SketchPlugin_Arc::END_ID())); - theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()), - theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); - theCreatedFeatures.insert(aConstraintFeature); - - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theBaseFeatureModified)); - theCreatedFeatures.insert(aConstraintFeature); -} - -void SketchPlugin_Trim::arrangePointsOnLine( - const AttributePoint2DPtr& theStartPointAttr, - const AttributePoint2DPtr& theEndPointAttr, - AttributePoint2DPtr& theFirstPointAttr, - AttributePoint2DPtr& theLastPointAttr) const -{ - // if first point is closer to last point, swap first and last values - if (theStartPointAttr->pnt()->distance(theFirstPointAttr->pnt()) > - theStartPointAttr->pnt()->distance(theLastPointAttr->pnt())) { - AttributePoint2DPtr aTmpPoint = theFirstPointAttr; - theFirstPointAttr = theLastPointAttr; - theLastPointAttr = aTmpPoint; - } -} - -void SketchPlugin_Trim::arrangePointsOnArc( - const FeaturePtr& theArc, - const std::shared_ptr& theStartPointAttr, - const std::shared_ptr& theEndPointAttr, - std::shared_ptr& theFirstPointAttr, - std::shared_ptr& theSecondPointAttr) const -{ - static const double anAngleTol = 1.e-12; - - std::shared_ptr aCenter = std::dynamic_pointer_cast( - theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); - bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value(); - - // collect directions to each point - std::shared_ptr aStartDir( - new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy()))); - std::shared_ptr aFirstPtDir( - new GeomAPI_Dir2d(theFirstPointAttr->pnt()->xy()->decreased(aCenter->xy()))); - std::shared_ptr aSecondPtDir( - new GeomAPI_Dir2d(theSecondPointAttr->pnt()->xy()->decreased(aCenter->xy()))); - - // sort points by their angular values - double aFirstPtAngle = aStartDir->angle(aFirstPtDir); - double aSecondPtAngle = aStartDir->angle(aSecondPtDir); - double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI; - if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.)) - aFirstPtAngle += aPeriod; - if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.)) - aSecondPtAngle += aPeriod; - - if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) { - AttributePoint2DPtr aTmpPoint = theFirstPointAttr; - theFirstPointAttr = theSecondPointAttr; - theSecondPointAttr = aTmpPoint; - } -} - -void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute, - const AttributePtr& theSourceAttribute) -{ - std::string anAttributeType = theModifiedAttribute->attributeType(); - if (anAttributeType == GeomDataAPI_Point2D::typeId()) { - AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast( - theModifiedAttribute); - AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast( - theSourceAttribute); - - if (aModifiedAttribute.get() && aSourceAttribute.get()) - aModifiedAttribute->setValue(aSourceAttribute->pnt()); - } - else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) { - AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast( - theModifiedAttribute); - AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast( - theSourceAttribute); - - if (aModifiedAttribute.get() && aSourceAttribute.get()) - aModifiedAttribute->setValue(aSourceAttribute->value()); - } -} - -FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr) -{ - FeaturePtr aFeature; - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch || !theBaseFeature.get()) - return aFeature; - - aFeature = aSketch->addFeature(SketchPlugin_Line::ID()); - - fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr); - fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr); - - fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), - theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); - - aFeature->execute(); // to obtain result - - return aFeature; -} - -FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr) -{ - FeaturePtr aFeature; - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch || !theBaseFeature.get()) - return aFeature; - - std::string aCenterAttributeId; - if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) - aCenterAttributeId = SketchPlugin_Arc::CENTER_ID(); - else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID()) - aCenterAttributeId = SketchPlugin_Circle::CENTER_ID(); - - if (aCenterAttributeId.empty()) - return aFeature; - - aFeature = aSketch->addFeature(SketchPlugin_Arc::ID()); - // update fillet arc: make the arc correct for sure, so, it is not needed to process - // the "attribute updated" - // by arc; moreover, it may cause cyclicity in hte mechanism of updater - bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true); - - aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( - SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); - - fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()), - theBaseFeature->attribute(aCenterAttributeId)); - fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr); - fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr); - - fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), - theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); - - /// fill referersed state of created arc as it is on the base arc - if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) { - bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value(); - aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed); - } - aFeature->data()->blockSendAttributeUpdated(aWasBlocked); - aFeature->execute(); // to obtain result - - return aFeature; -} - -FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId, - const AttributePtr& theFirstAttribute, - const AttributePtr& theSecondAttribute) -{ - FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - aRefAttr->setAttr(theFirstAttribute); - - aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - aRefAttr->setAttr(theSecondAttribute); - - return aConstraint; -} - -FeaturePtr SketchPlugin_Trim::createConstraintForObjects( - const std::string& theConstraintId, - const ObjectPtr& theFirstObject, - const ObjectPtr& theSecondObject) -{ - FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - aRefAttr->setObject(theFirstObject); - - aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - aRefAttr->setObject(theSecondObject); - - return aConstraint; -} - -void SketchPlugin_Trim::updateFeaturesAfterSplit( - const std::set& theFeaturesToUpdate) -{ - std::set::const_iterator anIt = theFeaturesToUpdate.begin(), - aLast = theFeaturesToUpdate.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aRefFeature = std::dynamic_pointer_cast(*anIt); - std::string aRefFeatureKind = aRefFeature->getKind(); - if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) { - std::shared_ptr aLenghtFeature = - std::dynamic_pointer_cast(*anIt); - if (aLenghtFeature.get()) { - std::shared_ptr aValueAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Constraint::VALUE())); - double aValue; - if (aLenghtFeature->computeLenghtValue(aValue) && aValueAttr.get()) - aValueAttr->setValue(aValue); - } - } - } -} - -std::shared_ptr SketchPlugin_Trim::getFeatureResult( - const std::shared_ptr& theFeature) -{ - std::shared_ptr aResult; - - std::string aFeatureKind = theFeature->getKind(); - if (aFeatureKind == SketchPlugin_Line::ID()) - aResult = theFeature->firstResult(); - else if (aFeatureKind == SketchPlugin_Arc::ID()) - aResult = theFeature->lastResult(); - else if (aFeatureKind == SketchPlugin_Circle::ID()) - aResult = theFeature->lastResult(); - - return aResult; -} - -std::set > SketchPlugin_Trim::getEdgeAttributes( - const std::shared_ptr& theFeature) -{ - std::set > anAttributes; - - std::string aFeatureKind = theFeature->getKind(); - if (aFeatureKind == SketchPlugin_Line::ID()) { - anAttributes.insert(theFeature->attribute(SketchPlugin_Line::START_ID())); - anAttributes.insert(theFeature->attribute(SketchPlugin_Line::END_ID())); - } - else if (aFeatureKind == SketchPlugin_Arc::ID()) { - anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::START_ID())); - anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::END_ID())); - } - else if (aFeatureKind == SketchPlugin_Circle::ID()) { - } - - return anAttributes; + return true; } -#ifdef _DEBUG -std::string SketchPlugin_Trim::getFeatureInfo( - const std::shared_ptr& theFeature, - const bool isUseAttributesInfo) +//******************************************************************** +#include +void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject) { - std::string anInfo; - if (!theFeature.get()) { - return "none"; - } - - if (theFeature->data()->isValid()) - anInfo.append(theFeature->data()->name().c_str()); + std::set > aShapes; + std::map, std::shared_ptr > aPointToAttributes; + std::map, + std::list< std::shared_ptr > > aPointToObjects; + + std::set > aRefAttributes; + // current feature + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + std::set anEdgeShapes; + // edges on feature + ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (!anEdgeShapes.empty()) { + GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape(); + + // coincidences to the feature + std::list > aPoints; - if (isUseAttributesInfo) { - std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(theFeature, - getEdgeAttributes(theFeature)); - /// processing of feature with point 2d attributes, like line, arc, circle - if (!aPointsInfo.empty()) { - anInfo += ": "; - anInfo += "\n"; - anInfo += aPointsInfo; - } - else { /// process constraint coincidence, find points in ref attr attributes - std::list anAttrs = theFeature->data()->attributes( - ModelAPI_AttributeRefAttr::typeId()); - std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); - std::string anAttributesInfo; - for(; anIt != aLast; anIt++) { - if (!anAttributesInfo.empty()) { - anAttributesInfo.append(", "); - anAttributesInfo += "\n"; - } - AttributePtr anAttr = *anIt; - std::string aValue = "not defined"; - std::string aType = anAttr->attributeType(); - if (aType == ModelAPI_AttributeRefAttr::typeId()) { - std::shared_ptr aRefAttr = - std::dynamic_pointer_cast(anAttr); - if (aRefAttr.get()) { - if (aRefAttr->isObject()) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); - aValue = "" + getFeatureInfo(aFeature, false); - } - else { - AttributePtr anAttribute = aRefAttr->attr(); - if (anAttribute.get()) { - FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); - aValue = "" + ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) + - " [" + getFeatureInfo(aFeature, false) + "]"; - } - } - } - } - anAttributesInfo.append(" " + anAttr->id() + ": " + aValue); + ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(), + aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); + // layed on feature coincidences to divide it on several shapes + //CompositeFeaturePtr aSketch = sketch(); + SketchPlugin_Sketch* aSketch = sketch(); + std::shared_ptr aData = aSketch->data(); + std::shared_ptr aC = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aX = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); + ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(), + aX->dir(), aY, aPoints, aPointToAttributes); + + // intersection points + if (useGraphicIntersection()) { + std::list aFeatures; + for (int i = 0; i < aSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = aSketch->subFeature(i); + if (aFeature.get()) + aFeatures.push_back(aFeature); } - if (!anAttributesInfo.empty()) - anInfo = anInfo + "\n" + anAttributesInfo; + ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints, + aPointToObjects); } + GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes); } - return anInfo; + myCashedShapes[theObject] = aShapes; + myCashedReferences[theObject] = aPointToAttributes; + if (useGraphicIntersection()) + myCashedObjects[theObject] = aPointToObjects; } -#endif diff --git a/src/SketchPlugin/SketchPlugin_Trim.h b/src/SketchPlugin/SketchPlugin_Trim.h index 21aa60f0f..bebc8b8c2 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.h +++ b/src/SketchPlugin/SketchPlugin_Trim.h @@ -63,6 +63,19 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase return MY_KIND; } + /// Start 2D point of the split segment + inline static const std::string& ENTITY_POINT() + { + static const std::string MY_ENTITY_POINT("ConstraintEntityPoint"); + return MY_ENTITY_POINT; + } + /// End 2D point of the split segment + /*inline static const std::string& ENTITY_B_POINT() + { + static const std::string MY_ENTITY_B_POINT("ConstraintEntityBPoint"); + return MY_ENTITY_B_POINT; + }*/ + /// \brief Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); @@ -88,207 +101,227 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase /// Returns the AIS preview SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); -private: - /// Returns geom point attribute of the feature bounds. It processes line or arc. - /// For circle feature, the result attributes are null - /// \param theFeature a source feature - /// \param theStartPointAttr an out attribute to start point - /// \param theStartPointAttr an out attribute to end point - void getFeaturePoints(const FeaturePtr& theFeature, - std::shared_ptr& theStartPointAttr, - std::shared_ptr& theEndPointAttr); - - /// Returns cast of attribute to geometrical point if the attribute is a ref attr attribute - /// \param theAttribute an attribute - /// \param geom point 2D or NULL - std::shared_ptr getPointOfRefAttr(const AttributePtr& theAttribute); - - /// Obtains those constraints of the feature that should be modified. output maps contain - /// point of coincidence and attribute id to be modified after split - /// \param theFeaturesToDelete [out] constrains that will be deleted after split - /// \param theFeaturesToUpdate [out] constrains that will be updated after split - /// \param theTangentFeatures [out] tangent feature to be connected to new feature - /// \param theCoincidenceToFeature [out] coincidence to feature to be connected to new feature - /// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature - void getConstraints(std::set>& theFeaturesToDelete, - std::set>& theFeaturesToUpdate, - std::map, IdToPointPair>& theTangentFeatures, - std::map, IdToPointPair>& theCoincidenceToFeature/*, - std::map, IdToPointPair>& theCoincidenceToPoint*/); - - /// Obtains references to feature point attributes and to feature, - /// e.g. for feature line: 1st container is - /// <1st line point, list > - /// <2nd line point, list<> > - /// for feature circle 2nd container is - /// \param theFeature an investigated feature - /// \param theRefs a container of list of referenced attributes - void getRefAttributes(const FeaturePtr& theFeature, - std::map >& theRefs, - std::list& theRefsToFeature); - - /// Move coincidence constraint from feature to point if it is found - /// \param theCoincidenceToFeature coincidence to feature to be connected to new feature - /// \param theFurtherCoincidences a list of points where coincidences will be build - /// \param theFeatureResults created results after split where constaint might be connected - /// \param theSplitFeature feature created by split, new coincidences to points should be created - /// if theCoincidenceToFeature contains equal points - void updateCoincidenceConstraintsToFeature( - const std::map, IdToPointPair>& theCoincidenceToFeature, - const std::set >& theFurtherCoincidences, - const std::set& theFeatureResults, - const FeaturePtr& theSplitFeature); - - /// Move tangency constraint to the nearest split feature that has a coincidence to the tangent - /// \param theTangentFeatures tangencies to feature to be connected to nearest feature - /// \param theFurtherCoincidences a list of points where coincidences is built - void updateTangentConstraintsToFeature( - const std::map, IdToPointPair>& theTangentFeatures, - const std::set >& theFurtherCoincidences); - - - /// Move constraints from base feature to given feature - /// \param theFeature a base feature - /// \param theRefsToFeature list of attributes referenced to base feature - void updateRefFeatureConstraints(const std::shared_ptr& theFeatureBaseResult, - const std::list& theRefsToFeature); - - /// Move constraints from attribute of base feature to attribute after modification - /// \param theBaseRefAttributes container of references to the attributes of base feature - /// \param theModifiedAttributes container of attributes placed instead of base attributes - /// at the same place - void updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes); +//private: +// /// Returns geom point attribute of the feature bounds. It processes line or arc. +// /// For circle feature, the result attributes are null +// /// \param theFeature a source feature +// /// \param theStartPointAttr an out attribute to start point +// /// \param theStartPointAttr an out attribute to end point +// void getFeaturePoints(const FeaturePtr& theFeature, +// std::shared_ptr& theStartPointAttr, +// std::shared_ptr& theEndPointAttr); +// +// FeaturePtr createCoincidenceConstraint(const AttributePtr& theFirstAttribute, +// const AttributePtr& theSecondAttribute); +// +// /// Returns cast of attribute to geometrical point if the attribute is a ref attr attribute +// /// \param theAttribute an attribute +// /// \param geom point 2D or NULL +// std::shared_ptr getPointOfRefAttr(const AttributePtr& theAttribute); +// +// /// Obtains those constraints of the feature that should be modified. output maps contain +// /// point of coincidence and attribute id to be modified after split +// /// \param theFeaturesToDelete [out] constrains that will be deleted after split +// /// \param theFeaturesToUpdate [out] constrains that will be updated after split +// /// \param theTangentFeatures [out] tangent feature to be connected to new feature +// /// \param theCoincidenceToFeature [out] coincidence to feature to be connected to new feature +// /// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature +// void getConstraints(std::set>& theFeaturesToDelete, +// std::set>& theFeaturesToUpdate, +// std::map, IdToPointPair>& theTangentFeatures, +// std::map, IdToPointPair>& theCoincidenceToFeature/*, +// std::map, IdToPointPair>& theCoincidenceToPoint*/); +// +// /// Obtains references to feature point attributes and to feature, +// /// e.g. for feature line: 1st container is +// /// <1st line point, list > +// /// <2nd line point, list<> > +// /// for feature circle 2nd container is +// /// \param theFeature an investigated feature +// /// \param theRefs a container of list of referenced attributes +// void getRefAttributes(const FeaturePtr& theFeature, +// std::map >& theRefs, +// std::list& theRefsToFeature); +// +// /// Move coincidence constraint from feature to point if it is found +// /// \param theCoincidenceToFeature coincidence to feature to be connected to new feature +// /// \param theFurtherCoincidences a list of points where coincidences will be build +// /// \param theFeatureResults created results after split where constaint might be connected +// /// \param theSplitFeature feature created by split, new coincidences to points should be created +// /// if theCoincidenceToFeature contains equal points +// void updateCoincidenceConstraintsToFeature( +// const std::map, IdToPointPair>& theCoincidenceToFeature, +// const std::set >& theFurtherCoincidences, +// const std::set& theFeatureResults, +// const FeaturePtr& theSplitFeature); +// +// /// Move tangency constraint to the nearest split feature that has a coincidence to the tangent +// /// \param theTangentFeatures tangencies to feature to be connected to nearest feature +// /// \param theFurtherCoincidences a list of points where coincidences is built +// void updateTangentConstraintsToFeature( +// const std::map, IdToPointPair>& theTangentFeatures, +// const std::set >& theFurtherCoincidences); +// +// +// /// Move constraints from base feature to given feature +// /// \param theFeature a base feature +// /// \param theRefsToFeature list of attributes referenced to base feature +// void updateRefFeatureConstraints(const std::shared_ptr& theFeatureBaseResult, +// const std::list& theRefsToFeature); +// +// /// Move constraints from attribute of base feature to attribute after modification +// /// \param theBaseRefAttributes container of references to the attributes of base feature +// /// \param theModifiedAttributes container of attributes placed instead of base attributes +// /// at the same place +// void updateRefAttConstraints( +// const std::map >& theBaseRefAttributes, +// const std::set >& theModifiedAttributes); +// +// /// Make the base object is splitted by the point attributes +// /// \param theSplitFeature a result split feature +// /// \param theBeforeFeature a feature between start point and the 1st point of split feature +// /// \param theAfterFeature a feature between last point of split feature and the end point +// /// \param thePoints a list of points where coincidences will be build +// /// \param theCreatedFeatures a container of created features +// /// \param theModifiedAttributes a container of attribute on base +// /// feature to attribute on new feature +// void splitLine(std::shared_ptr& theSplitFeature, +// std::shared_ptr& theBeforeFeature, +// std::shared_ptr& theAfterFeature, +// std::set >& thePoints, +// std::set>& theCreatedFeatures, +// std::set>& theModifiedAttributes); +// +// /// Make the base object is splitted by the point attributes +// /// \param theSplitFeature a result split feature +// /// \param theBeforeFeature a feature between start point and the 1st point of split feature +// /// \param theAfterFeature a feature between last point of split feature and the end point +// /// \param thePoints a list of points where coincidences will be build +// /// \param theCreatedFeatures a container of created features +// void splitArc(std::shared_ptr& theSplitFeature, +// std::shared_ptr& theBeforeFeature, +// std::shared_ptr& theAfterFeature, +// std::set >& thePoints, +// std::set>& theCreatedFeatures, +// std::set>& theModifiedAttributes); +// +// /// Make the base object is splitted by the point attributes +// /// \param theSplitFeature a result split feature +// /// \param theBeforeFeature a feature between start point and the 1st point of split feature +// /// \param theAfterFeature a feature between last point of split feature and the end point +// /// \param thePoints a list of points where coincidences will be build +// /// \param theCreatedFeatures a container of created features +// void splitCircle(std::shared_ptr& theSplitFeature, +// std::shared_ptr& theBeforeFeature, +// std::shared_ptr& theAfterFeature, +// std::set >& thePoints, +// std::set>& theCreatedFeatures, +// std::set>& theModifiedAttributes); +// +// /// Correct the first and the second point to provide condition that the first is closer to +// /// the start point and the second point - to the last end of current segment. To rearrange +// /// them if this condition is not satisfied. +// /// \param theStartPointAttr a start point of a segment +// /// \param theEndPointAttr an end point of a segment +// /// \param theFirstPointAttr a start point of a segment +// /// \param theSecondPointAttr an end point of a segment +// void arrangePointsOnLine(const std::shared_ptr& theStartPointAttr, +// const std::shared_ptr& theEndPointAttr, +// std::shared_ptr& theFirstPointAttr, +// std::shared_ptr& theSecondPointAttr) const; +// +// /// Correct the first and the second point to provide condition that the first is closer to +// /// the start point and the second point - to the last end of current segment. To rearrange +// /// them if this condition is not satisfied. +// /// \param theArc an arc to be split +// /// \param theStartPointAttr a start point of a segment +// /// \param theEndPointAttr an end point of a segment +// /// \param theFirstPointAttr a start point of a segment +// /// \param theSecondPointAttr an end point of a segment +// void arrangePointsOnArc(const FeaturePtr& theArc, +// const std::shared_ptr& theStartPointAttr, +// const std::shared_ptr& theEndPointAttr, +// std::shared_ptr& theFirstPointAttr, +// std::shared_ptr& theSecondPointAttr) const; +// +// /// Fill attribute by value of another attribute. It processes only Point 2D attributes. +// /// \param theModifiedAttribute an attribute of GeomDataAPI_Point2D on feature to be modified +// /// \param theSourceAttribute an attribute of GeomDataAPI_Point2D to obtain data +// void fillAttribute(const AttributePtr& theModifiedAttribute, +// const AttributePtr& theSourceAttribute); +// +// /// Creates a line feature filled by center of base feature and given points +// /// \param theBaseFeature another arc feature +// /// \param theFirstAttribute an attribute with coordinates for the start point +// /// \param theSecondAttribute an attribute with coordinates for the end point +// FeaturePtr createLineFeature(const FeaturePtr& theBaseFeature, +// const AttributePtr& theFirstPointAttr, +// const AttributePtr& theSecondPointAttr); +// +// /// Creates an arc feature filled by center of base feature and given points +// /// \param theBaseFeature another arc feature +// /// \param theFirstAttribute an attribute with coordinates for the start point +// /// \param theSecondAttribute an attribute with coordinates for the end point +// FeaturePtr createArcFeature(const FeaturePtr& theBaseFeature, +// const AttributePtr& theFirstPointAttr, +// const AttributePtr& theSecondPointAttr); +// +// /// Add feature coincidence constraint between given attributes +// /// \param theConstraintId a constraint index +// /// \param theFirstAttribute an attribute of further coincidence +// /// \param theSecondAttribute an attribute of further coincidence +// std::shared_ptr createConstraint(const std::string& theConstraintId, +// const std::shared_ptr& theFirstAttribute, +// const std::shared_ptr& theSecondAttribute); +// +// /// Add feature coincidence constraint between given attributes +// /// \param theConstraintId a constraint index +// /// \param theFirstAttribute an attribute of further coincidence +// /// \param theFirstAttribute an attribute of further coincidence +// std::shared_ptr createConstraintForObjects(const std::string& theConstraintId, +// const std::shared_ptr& theFirstObject, +// const std::shared_ptr& theSecondObject); +// +// /// Add feature coincidence constraint between given attributes +// /// \param theFeaturesToUpdate a constraint index +// void updateFeaturesAfterSplit(const std::set& theFeaturesToUpdate); +// +// /// Result result of the feature to build constraint with. For arc, circle it is an edge result. +// /// \param theFeature a feature +// /// \return result object +// std::shared_ptr getFeatureResult( +// const std::shared_ptr& theFeature); +// +// /// Returns attributes of the feature, used in edge build, for arc it is end and start points +// /// \param theFeature a feature +// /// \return container of attributes +// std::set > getEdgeAttributes( +// const std::shared_ptr& theFeature); +// +//#ifdef _DEBUG +// /// Return feature name, kind, point attribute values united in a string +// /// \param theFeature an investigated feature +// /// \return string value +// std::string getFeatureInfo(const std::shared_ptr& theFeature, +// const bool isUseAttributesInfo = true); +//#endif - /// Make the base object is splitted by the point attributes - /// \param theSplitFeature a result split feature - /// \param theBeforeFeature a feature between start point and the 1st point of split feature - /// \param theAfterFeature a feature between last point of split feature and the end point - /// \param thePoints a list of points where coincidences will be build - /// \param theCreatedFeatures a container of created features - /// \param theModifiedAttributes a container of attribute on base - /// feature to attribute on new feature - void splitLine(std::shared_ptr& theSplitFeature, - std::shared_ptr& theBeforeFeature, - std::shared_ptr& theAfterFeature, - std::set >& thePoints, - std::set>& theCreatedFeatures, - std::set>& theModifiedAttributes); - - /// Make the base object is splitted by the point attributes - /// \param theSplitFeature a result split feature - /// \param theBeforeFeature a feature between start point and the 1st point of split feature - /// \param theAfterFeature a feature between last point of split feature and the end point - /// \param thePoints a list of points where coincidences will be build - /// \param theCreatedFeatures a container of created features - void splitArc(std::shared_ptr& theSplitFeature, - std::shared_ptr& theBeforeFeature, - std::shared_ptr& theAfterFeature, - std::set >& thePoints, - std::set>& theCreatedFeatures, - std::set>& theModifiedAttributes); - - /// Make the base object is splitted by the point attributes - /// \param theSplitFeature a result split feature - /// \param theBeforeFeature a feature between start point and the 1st point of split feature - /// \param theAfterFeature a feature between last point of split feature and the end point - /// \param thePoints a list of points where coincidences will be build - /// \param theCreatedFeatures a container of created features - void splitCircle(std::shared_ptr& theSplitFeature, - std::shared_ptr& theBeforeFeature, - std::shared_ptr& theAfterFeature, - std::set >& thePoints, - std::set>& theCreatedFeatures, - std::set>& theModifiedAttributes); - - /// Correct the first and the second point to provide condition that the first is closer to - /// the start point and the second point - to the last end of current segment. To rearrange - /// them if this condition is not satisfied. - /// \param theStartPointAttr a start point of a segment - /// \param theEndPointAttr an end point of a segment - /// \param theFirstPointAttr a start point of a segment - /// \param theSecondPointAttr an end point of a segment - void arrangePointsOnLine(const std::shared_ptr& theStartPointAttr, - const std::shared_ptr& theEndPointAttr, - std::shared_ptr& theFirstPointAttr, - std::shared_ptr& theSecondPointAttr) const; - - /// Correct the first and the second point to provide condition that the first is closer to - /// the start point and the second point - to the last end of current segment. To rearrange - /// them if this condition is not satisfied. - /// \param theArc an arc to be split - /// \param theStartPointAttr a start point of a segment - /// \param theEndPointAttr an end point of a segment - /// \param theFirstPointAttr a start point of a segment - /// \param theSecondPointAttr an end point of a segment - void arrangePointsOnArc(const FeaturePtr& theArc, - const std::shared_ptr& theStartPointAttr, - const std::shared_ptr& theEndPointAttr, - std::shared_ptr& theFirstPointAttr, - std::shared_ptr& theSecondPointAttr) const; - - /// Fill attribute by value of another attribute. It processes only Point 2D attributes. - /// \param theModifiedAttribute an attribute of GeomDataAPI_Point2D on feature to be modified - /// \param theSourceAttribute an attribute of GeomDataAPI_Point2D to obtain data - void fillAttribute(const AttributePtr& theModifiedAttribute, - const AttributePtr& theSourceAttribute); - - /// Creates a line feature filled by center of base feature and given points - /// \param theBaseFeature another arc feature - /// \param theFirstAttribute an attribute with coordinates for the start point - /// \param theSecondAttribute an attribute with coordinates for the end point - FeaturePtr createLineFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr); - - /// Creates an arc feature filled by center of base feature and given points - /// \param theBaseFeature another arc feature - /// \param theFirstAttribute an attribute with coordinates for the start point - /// \param theSecondAttribute an attribute with coordinates for the end point - FeaturePtr createArcFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr); - - /// Add feature coincidence constraint between given attributes - /// \param theConstraintId a constraint index - /// \param theFirstAttribute an attribute of further coincidence - /// \param theSecondAttribute an attribute of further coincidence - std::shared_ptr createConstraint(const std::string& theConstraintId, - const std::shared_ptr& theFirstAttribute, - const std::shared_ptr& theSecondAttribute); - - /// Add feature coincidence constraint between given attributes - /// \param theConstraintId a constraint index - /// \param theFirstAttribute an attribute of further coincidence - /// \param theFirstAttribute an attribute of further coincidence - std::shared_ptr createConstraintForObjects(const std::string& theConstraintId, - const std::shared_ptr& theFirstObject, - const std::shared_ptr& theSecondObject); +private: + bool useGraphicIntersection() const; - /// Add feature coincidence constraint between given attributes - /// \param theFeaturesToUpdate a constraint index - void updateFeaturesAfterSplit(const std::set& theFeaturesToUpdate); + void fillObjectShapes(const ObjectPtr& theObject); - /// Result result of the feature to build constraint with. For arc, circle it is an edge result. - /// \param theFeature a feature - /// \return result object - std::shared_ptr getFeatureResult( - const std::shared_ptr& theFeature); +private: + //std::shared_ptr myCurrentSubShape; + std::map > myCashedShapes; - /// Returns attributes of the feature, used in edge build, for arc it is end and start points - /// \param theFeature a feature - /// \return container of attributes - std::set > getEdgeAttributes( - const std::shared_ptr& theFeature); + typedef std::map, + std::shared_ptr > PntToAttributesMap; + std::map myCashedReferences; -#ifdef _DEBUG - /// Return feature name, kind, point attribute values united in a string - /// \param theFeature an investigated feature - /// \return string value - std::string getFeatureInfo(const std::shared_ptr& theFeature, - const bool isUseAttributesInfo = true); -#endif + typedef std::map, + std::list< std::shared_ptr > > PntToObjectsMap; + std::map myCashedObjects; }; #endif diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 9918d08e2..5884fa6bb 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -949,7 +949,8 @@ bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute, if (theArguments.size() > 0) { // use graphic intersection // intersection points //std::shared_ptr aCompositeFeature(aSketch); - std::map, std::shared_ptr > aPointToObjects; + std::map, + std::list< std::shared_ptr > > aPointToObjects; std::list aFeatures; for (int i = 0; i < aSketch->numberOfSubs(); i++) { FeaturePtr aFeature = aSketch->subFeature(i); diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 8f081145b..265d61aa6 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -158,7 +158,7 @@ - - + diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index e38dc3dc3..f51ac398f 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -702,7 +702,7 @@ void XGUI_Displayer::clearSelected(const bool theUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { - aContext->UnhilightCurrents(false); + aContext->UnhilightSelected(false);//UnhilightCurrents(false); aContext->ClearSelected(theUpdateViewer); #ifdef VINSPECTOR if (getCallBack()) getCallBack()->ClearSelected(); -- 2.39.2