X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=4c77d6c16993bb4fd95b4cb1696a2fe57a4fd3be;hb=490a2d118559ea9dfbb22eedb8075038743eb8ea;hp=892f610a0d36e43ebc4511f884184f9c97cc98bb;hpb=add875fff5ce228a4914fcc323fdb911a1042b21;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp old mode 100644 new mode 100755 index 892f610a0..4c77d6c16 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -1,13 +1,50 @@ -// File: PartSet_Tools.h -// Created: 28 Apr 2014 -// Author: Natalia ERMOLAEVA +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include +#include +#include #include #include #include #include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include #include #include @@ -15,6 +52,8 @@ #include #include #include +#include +#include #include #include @@ -27,21 +66,47 @@ #include #include #include - +#include +#include +#include +#include +#include +#include + +#include #include +#include #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #ifdef _DEBUG #include #endif const double PRECISION_TOLERANCE = 0.000001; +const int AIS_DEFAULT_WIDTH = 2; +const bool SKETCH_PROJECTION_INCLUDE_INTO_RESULT = false; // by default, it is not presented + +int PartSet_Tools::getAISDefaultWidth() +{ + return AIS_DEFAULT_WIDTH; +} gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theView) { @@ -77,15 +142,16 @@ Handle(V3d_View) theView, return; AttributeDoublePtr anAttr; - boost::shared_ptr aData = theSketch->data(); + std::shared_ptr aData = theSketch->data(); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( + std::shared_ptr anOrigin = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( + std::shared_ptr aX = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr anY = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::DIRY_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr anY = aNorm->xyz()->cross(aX->xyz()); gp_Pnt anOriginPnt(anOrigin->x(), anOrigin->y(), anOrigin->z()); gp_Vec aVec(anOriginPnt, thePoint); @@ -101,7 +167,7 @@ Handle(V3d_View) theView, gp_Vec anEyeVec(EyePoint, AtPoint); anEyeVec.Normalize(); - boost::shared_ptr aNormal = boost::dynamic_pointer_cast( + std::shared_ptr aNormal = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::NORM_ID())); gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z()); @@ -115,85 +181,54 @@ Handle(V3d_View) theView, theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z(); } -void PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr theSketch, - gp_Pnt& thePoint) +std::shared_ptr PartSet_Tools::convertTo2D(FeaturePtr theSketch, + const std::shared_ptr& thePnt) { - if (!theSketch) - return; + std::shared_ptr aRes; + if (theSketch->getKind() != SketchPlugin_Sketch::ID()) + return aRes; + std::shared_ptr aC = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aX = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); + return thePnt->to2D(aC->pnt(), aX->dir(), aY); +} - boost::shared_ptr aData = theSketch->data(); - boost::shared_ptr aC = boost::dynamic_pointer_cast( +std::shared_ptr PartSet_Tools::convertTo3D(const double theX, const double theY, + FeaturePtr theSketch) +{ + std::shared_ptr aData = theSketch->data(); + + std::shared_ptr aC = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( + std::shared_ptr aX = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aY = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::DIRY_ID())); - - boost::shared_ptr aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX)) - ->added(aY->dir()->xyz()->multiplied(theY)); - - boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt(aSum)); - thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z()); -} - -FeaturePtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, - FeaturePtr theSketch, - const std::list& theFeatures) -{ - double aX, anY; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView); - PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY); + 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()))); - FeaturePtr aFeature; - std::list::const_iterator anIt = theFeatures.begin(), aLast = theFeatures - .end(); + std::shared_ptr aPnt2d = + std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); - FeaturePtr aDeltaFeature; - double aMinDelta = -1; - ModuleBase_ViewerPrs aPrs; - for (; anIt != aLast; anIt++) { - aPrs = *anIt; - if (!aPrs.object()) - continue; - boost::shared_ptr aSketchFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(aPrs.object()); - if (!aSketchFeature) - continue; - double aDelta = aSketchFeature->distanceToPoint( - boost::shared_ptr(new GeomAPI_Pnt2d(aX, anY))); - if (aMinDelta < 0 || aMinDelta > aDelta) { - aMinDelta = aDelta; - // TODO aDeltaFeature = aPrs.result(); - } - } - return aDeltaFeature; + return aPnt2d->to3D(aC->pnt(), aX->dir(), aY); } -boost::shared_ptr PartSet_Tools::document() +std::shared_ptr PartSet_Tools::document() { return ModelAPI_Session::get()->moduleDocument(); } -void PartSet_Tools::setFeaturePoint(FeaturePtr theFeature, double theX, double theY, - const std::string& theAttribute) -{ - if (!theFeature) - return; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr aPoint = boost::dynamic_pointer_cast( - aData->attribute(theAttribute)); - if (aPoint) - aPoint->setValue(theX, theY); -} - void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, const std::string& theAttribute) { if (!theFeature) return; - boost::shared_ptr aData = theFeature->data(); - AttributeDoublePtr anAttribute = boost::dynamic_pointer_cast( + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( aData->attribute(theAttribute)); if (anAttribute) anAttribute->setValue(theValue); @@ -203,10 +238,10 @@ double PartSet_Tools::featureValue(FeaturePtr theFeature, const std::string& the bool& isValid) { isValid = false; - double aValue; + double aValue = 0; if (theFeature) { - boost::shared_ptr aData = theFeature->data(); - AttributeDoublePtr anAttribute = boost::dynamic_pointer_cast( + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( aData->attribute(theAttribute)); if (anAttribute) { aValue = anAttribute->value(); @@ -223,11 +258,11 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA if (!theFeature) return aFeature; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr anAttr = boost::dynamic_pointer_cast< + std::shared_ptr aData = theFeature->data(); + std::shared_ptr anAttr = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(theAttribute)); if (anAttr) { - aFeature = boost::dynamic_pointer_cast(anAttr->object()); + aFeature = std::dynamic_pointer_cast(anAttr->object()); if (!theKind.empty() && aFeature && aFeature->getKind() != theKind) { aFeature = FeaturePtr(); } @@ -236,111 +271,484 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA } void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, - boost::shared_ptr thePoint1, - boost::shared_ptr thePoint2) + std::shared_ptr thePoint1, + std::shared_ptr thePoint2) { FeaturePtr aFeature; if (theSketch) { aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } else { - boost::shared_ptr aDoc = document(); + std::shared_ptr aDoc = document(); aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } - boost::shared_ptr aData = aFeature->data(); + std::shared_ptr aData = aFeature->data(); - boost::shared_ptr aRef1 = boost::dynamic_pointer_cast< + std::shared_ptr aRef1 = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); aRef1->setAttr(thePoint1); - boost::shared_ptr aRef2 = boost::dynamic_pointer_cast< + std::shared_ptr aRef2 = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); aRef2->setAttr(thePoint2); - if (aFeature) // TODO: generate an error if feature was not created - aFeature->execute(); + // we need to flush created signal in order to coincidence is processed by solver + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); } -void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, - const std::string& theAttribute, double theClickedX, - double theClickedY) +std::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { - // find a feature point by the selection mode - //boost::shared_ptr aPoint = featurePoint(theMode); - boost::shared_ptr aFeaturePoint = boost::dynamic_pointer_cast< - GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute)); - if (!aFeaturePoint) - return; + std::shared_ptr aPlane; + + std::shared_ptr anOrigin = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aNormal = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); + + if (aNormal.get() && aNormal->isInitialized() && + anOrigin.get() && anOrigin->isInitialized()) + aPlane = std::shared_ptr(new GeomAPI_Pln(anOrigin->pnt(), aNormal->dir())); + + return aPlane; +} + +std::shared_ptr PartSet_Tools::point3D(std::shared_ptr thePoint2D, + CompositeFeaturePtr theSketch) +{ + std::shared_ptr aPoint; + if (!theSketch || !thePoint2D) + return aPoint; + + DataPtr aData = theSketch->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()))); + + return thePoint2D->to3D(aC->pnt(), aX->dir(), aY); +} + +ResultPtr PartSet_Tools::findFixedObjectByExternal(const TopoDS_Shape& theShape, + const ObjectPtr& theObject, + CompositeFeaturePtr theSketch) +{ + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (!aResult.get()) + return ResultPtr(); + + for (int i = 0, aNbSubs = theSketch->numberOfSubs(); i < aNbSubs; i++) { + FeaturePtr aFeature = theSketch->subFeature(i); + if (aFeature->getKind() != SketchPlugin_Projection::PROJECTED_FEATURE_ID()) + continue; + if (aFeature->lastResult() == aResult) + return aResult; + } + return ResultPtr(); +} + +ResultPtr PartSet_Tools::createFixedObjectByExternal( + const std::shared_ptr& theShape, + const ObjectPtr& theObject, + CompositeFeaturePtr theSketch, + const bool theTemporary, + FeaturePtr& theCreatedFeature) +{ + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (!aResult.get()) + return ResultPtr(); + + FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID()); + theCreatedFeature = aProjectionFeature; + AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast( + aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID())); + anExternalAttr->setValue(aResult, theShape); + + AttributeBooleanPtr anIntoResult = std::dynamic_pointer_cast + (aProjectionFeature->data()->attribute(SketchPlugin_Projection::INCLUDE_INTO_RESULT())); + anIntoResult->setValue(SKETCH_PROJECTION_INCLUDE_INTO_RESULT); + aProjectionFeature->execute(); + + // if projection feature has not been created, exit + AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr( + SketchPlugin_Projection::PROJECTED_FEATURE_ID()); + if (!aRefAttr || !aRefAttr->isInitialized()) + { + // remove external feature if the attribute is not filled + std::set aFeatures; + aFeatures.insert(aProjectionFeature); + ModelAPI_Tools::removeFeaturesAndReferences(aFeatures); + return ResultPtr(); + } + + FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object()); + if (aProjection.get() && aProjection->lastResult().get()) + return aProjection->lastResult(); + + return ResultPtr(); +} + +bool PartSet_Tools::isContainPresentation(const QList& theSelected, + const ModuleBase_ViewerPrsPtr& thePrs) +{ + foreach (ModuleBase_ViewerPrsPtr aPrs, theSelected) { + if (aPrs->object() == thePrs->object()) + return true; + } + return false; +} - // get all sketch features. If the point with the given coordinates belong to any sketch feature, - // the constraint is created between the feature point and the found sketch point - boost::shared_ptr aData = theSketch->data(); - boost::shared_ptr aRefList = boost::dynamic_pointer_cast< - ModelAPI_AttributeRefList>(aData->attribute(SketchPlugin_Sketch::FEATURES_ID())); - - std::list aFeatures = aRefList->list(); - std::list::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end(); - std::list > anAttiributes; - boost::shared_ptr aClickedPoint = boost::shared_ptr( - new GeomAPI_Pnt2d(theClickedX, theClickedY)); +GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, + ModuleBase_IWorkshop* theWorkshop) +{ + GeomShapePtr aShape; + XGUI_ModuleConnector* aConnector = dynamic_cast(theWorkshop); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + + // 2. find visualized vertices of the attribute and if the attribute of the vertex is + // the same, return it + FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(theAttribute->owner()); + // 2.1 get visualized results of the feature + const std::list& aResList = anAttributeFeature->results(); + std::list::const_iterator anIt = aResList.begin(), aLast = aResList.end(); for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = boost::dynamic_pointer_cast(*anIt); - // find the given point in the feature attributes - anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type()); - std::list >::const_iterator anIt = anAttiributes.begin(), - aLast = anAttiributes.end(); - boost::shared_ptr aFPoint; - for (; anIt != aLast && !aFPoint; anIt++) { - boost::shared_ptr aCurPoint = boost::dynamic_pointer_cast< - GeomDataAPI_Point2D>(*anIt); - if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion()) - aFPoint = aCurPoint; + AISObjectPtr aAISObj = aDisplayer->getAISObject(*anIt); + if (aAISObj.get() != NULL) { + Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); + // 2.2 find selected owners of a visualizedd object + SelectMgr_IndexedMapOfOwner aSelectedOwners; + aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners); + for (Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++) { + Handle(SelectMgr_EntityOwner) anOwner = aSelectedOwners(i); + if (!anOwner.IsNull()) { + Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner); + if (!aBRepOwner.IsNull() && aBRepOwner->HasShape()) { + const TopoDS_Shape& aBRepShape = aBRepOwner->Shape(); + if (aBRepShape.ShapeType() == TopAbs_VERTEX) { + // 2.3 if the owner is vertex and an attribute of the vertex is equal to the initial + // attribute, returns the shape + PartSet_Module* aModule = dynamic_cast(theWorkshop->module()); + PartSet_SketcherMgr* aSketchMgr = aModule->sketchMgr(); + AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(anAttributeFeature, + aBRepShape, aSketchMgr->activeSketch()); + if (aPntAttr.get() != NULL && aPntAttr == theAttribute) { + aShape = std::shared_ptr(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(aBRepShape)); + break; + } + } + } + } + } } - if (aFPoint) - PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint); } + return aShape; } -boost::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) +std::shared_ptr PartSet_Tools::getPoint( + std::shared_ptr& theFeature, + const std::string& theAttribute) { - boost::shared_ptr aPlane; - double aA, aB, aC, aD; + std::shared_ptr aPointAttr = ModelGeomAlgo_Point2D::getPointOfRefAttr( + theFeature.get(), theAttribute, SketchPlugin_Point::ID(), + SketchPlugin_Point::COORD_ID()); + if (aPointAttr.get() != NULL) + return aPointAttr->pnt(); + return std::shared_ptr(); +} - boost::shared_ptr aData = theSketch->data(); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aNormal = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::NORM_ID())); - aA = aNormal->x(); - aB = aNormal->y(); - aC = aNormal->z(); - aD = 0; +std::shared_ptr PartSet_Tools::getPnt2d(QMouseEvent* theEvent, + ModuleBase_IViewWindow* theWindow, + const FeaturePtr& theSketch) +{ + gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + double aX, anY; + Handle(V3d_View) aView = theWindow->v3dView(); + PartSet_Tools::convertTo2D(aPnt, theSketch, aView, aX, anY); - aPlane = boost::shared_ptr(new GeomAPI_Pln(aA, aB, aC, aD)); - return aPlane; + return std::shared_ptr(new GeomAPI_Pnt2d(aX, anY)); } -boost::shared_ptr PartSet_Tools::point3D(boost::shared_ptr thePoint2D, - CompositeFeaturePtr theSketch) +FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, + std::shared_ptr thePoint) { - boost::shared_ptr aPoint; - if (!theSketch || !thePoint2D) - return aPoint; + FeaturePtr aCoincident; + + const std::set& aRefsList = theData->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + std::shared_ptr a2dPnt = + PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } else { + a2dPnt = PartSet_Tools::getPoint(aConstrFeature, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } + } + } + } + return aCoincident; +} - boost::shared_ptr aC = boost::dynamic_pointer_cast( - theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( - theSketch->data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aY = boost::dynamic_pointer_cast( - theSketch->data()->attribute(SketchPlugin_Sketch::DIRY_ID())); +FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, + std::shared_ptr thePoint) +{ + FeaturePtr aCoincident; + if (theFeature.get() == NULL) + return aCoincident; + + const std::set& aRefsList = theFeature->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature && aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + std::shared_ptr a2dPnt = + PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } else { + a2dPnt = PartSet_Tools::getPoint(aConstrFeature, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } + } + } + } + /// Find by result + if (!aCoincident.get()) { + std::list aResults = theFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { + ResultPtr aResult = *aIt; + aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint); + if (aCoincident.get()) + break; + } + } + return aCoincident; +} + +void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& theList, + QList& theCoincidencies, + std::string theAttr, QList& theIsAttributes) +{ + std::shared_ptr aOrig = getCoincedencePoint(theStartCoin); + if (aOrig.get() == NULL) + return; - return thePoint2D->to3D(aC->pnt(), aX->dir(), aY->dir()); + AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr); + if (!aPnt) + return; + ObjectPtr aObj = aPnt->object(); + FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); + if (aFeature.get()) { + if (!theList.contains(aFeature)) { + theList.append(aFeature); + theCoincidencies.append(theStartCoin); + theIsAttributes.append(true); // point attribute on a feature + const std::set& aRefsList = aFeature->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + if (!theCoincidencies.contains(aConstrFeature)) { + std::shared_ptr aPnt = getCoincedencePoint(aConstrFeature); + if (aPnt.get() && aOrig->isEqual(aPnt)) { + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes); + } + } + } + } + } + } else { + // Find by Results + ResultConstructionPtr aResult = std::dynamic_pointer_cast(aObj); + if (aResult.get()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aPnt->object()); + if (!theList.contains(aFeature)) + theList.append(aFeature); + theCoincidencies.append(theStartCoin); + theIsAttributes.append(false); // point attribute on a feature + + const std::set& aRefsList = aResult->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + if (!theCoincidencies.contains(aConstrFeature)) { + std::shared_ptr aPnt = getCoincedencePoint(aConstrFeature); + if (aPnt.get() && aOrig->isEqual(aPnt)) { + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes); + } + } + } + } + } + } +} + +std::shared_ptr PartSet_Tools::getCoincedencePoint(FeaturePtr theStartCoin) +{ + std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), + SketchPlugin_Constraint::ENTITY_A()); + if (aPnt.get() == NULL) + aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B()); + return aPnt; +} + +AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch) +{ + + AttributePtr anAttribute; + FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); + if (aFeature) { + if (theShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(theShape); + if (!aVertex.IsNull()) { + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + std::shared_ptr aValue = std::shared_ptr( + new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z())); + + // find the given point in the feature attributes + std::list anAttiributes = + aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = anAttiributes.begin(), + aLast = anAttiributes.end(); + for (; anIt != aLast && !anAttribute; anIt++) { + std::shared_ptr aCurPoint = + std::dynamic_pointer_cast(*anIt); + if (!aCurPoint->isInitialized()) + continue; + + std::shared_ptr aPnt = + convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch); + if (aPnt && (aPnt->distance(aValue) < Precision::Confusion())) { + anAttribute = aCurPoint; + break; + } + } + } + } + } + return anAttribute; +} + +void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite, + const Events_ID theEventId) +{ + if (!theComposite.get()) + return; + + static Events_Loop* aLoop = Events_Loop::loop(); + for (int i = 0; i < theComposite->numberOfSubs(); i++) { + FeaturePtr aSubFeature = theComposite->subFeature(i); + static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + aECreator->sendUpdated(aSubFeature, theEventId); + } + Events_Loop::loop()->flush(theEventId); +} + +bool PartSet_Tools::isAuxiliarySketchEntity(const ObjectPtr& theObject) +{ + bool isAuxiliaryFeature = false; + + FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject); + std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID(); + AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast( + anObjectFeature->data()->attribute(anAuxiliaryAttribute)); + if (anAuxiliaryAttr.get()) + isAuxiliaryFeature = anAuxiliaryAttr->value(); + + + return isAuxiliaryFeature; +} + +bool PartSet_Tools::isIncludeIntoSketchResult(const ObjectPtr& theObject) +{ + // check the feature is neither Projection nor IntersectionPoint feature + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature->getKind() == SketchPlugin_Projection::ID() || + aFeature->getKind() == SketchPlugin_IntersectionPoint::ID()) + return false; + + // go through the references to the feature to check + // if it was created by Projection or Intersection + const std::set& aRefs = theObject->data()->refsToMe(); + for (std::set::const_iterator aRefIt = aRefs.begin(); + aRefIt != aRefs.end(); ++aRefIt) { + AttributePtr anAttr = *aRefIt; + std::string anIncludeToResultAttrName; + if (anAttr->id() == SketchPlugin_Projection::PROJECTED_FEATURE_ID()) + anIncludeToResultAttrName = SketchPlugin_Projection::INCLUDE_INTO_RESULT(); + else if (anAttr->id() == SketchPlugin_IntersectionPoint::INTERSECTION_POINTS_ID()) + anIncludeToResultAttrName = SketchPlugin_IntersectionPoint::INCLUDE_INTO_RESULT(); + + if (!anIncludeToResultAttrName.empty()) { + // check "include into result" flag + FeaturePtr aParent = ModelAPI_Feature::feature(anAttr->owner()); + return aParent->boolean(anIncludeToResultAttrName)->value(); + } + } + return true; } -bool PartSet_Tools::isConstraintFeature(const std::string& theKind) + +ResultPtr PartSet_Tools::createFixedByExternalCenter( + const ObjectPtr& theObject, + const std::shared_ptr& theEdge, + ModelAPI_AttributeSelection::CenterType theType, + const CompositeFeaturePtr& theSketch, + bool theTemporary, + FeaturePtr& theCreatedFeature) { - return theKind == SketchPlugin_ConstraintDistance::ID() - || theKind == SketchPlugin_ConstraintLength::ID() - || theKind == SketchPlugin_ConstraintRadius::ID() - || theKind == SketchPlugin_ConstraintRigid::ID(); + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (!aResult.get()) + return ResultPtr(); + + FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID()); + theCreatedFeature = aProjectionFeature; + AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast( + aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID())); + anExternalAttr->setValueCenter(aResult, theEdge, theType, theTemporary); + + AttributeBooleanPtr anIntoResult = std::dynamic_pointer_cast + (aProjectionFeature->data()->attribute(SketchPlugin_Projection::INCLUDE_INTO_RESULT())); + anIntoResult->setValue(SKETCH_PROJECTION_INCLUDE_INTO_RESULT); + aProjectionFeature->execute(); + + // if projection feature has not been created, exit + AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr( + SketchPlugin_Projection::PROJECTED_FEATURE_ID()); + if (!aRefAttr || !aRefAttr->isInitialized()) + return ResultPtr(); + + FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object()); + if (aProjection.get() && aProjection->lastResult().get()) + return aProjection->lastResult(); + + return ResultPtr(); }