X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=0d91654e57e91d2ebc2bfbff1bdc5115b4a96510;hb=4a056c17b0d629e17c0825c38014255dedec5c3c;hp=6495c3ce9da85724a5727a442234f72e4c889b46;hpb=2d377b25bd785a251e6a57064a4bfd88c60d2468;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 6495c3ce9..0d91654e5 100755 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_Tools.cpp -// 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 @@ -16,6 +30,11 @@ #include #include #include +#include + +#include + +#include #include @@ -51,6 +70,8 @@ #include #include #include +#include +#include #include #include @@ -70,6 +91,9 @@ #include #include #include +#include + +#include #ifdef _DEBUG #include @@ -77,6 +101,7 @@ 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() { @@ -156,7 +181,7 @@ Handle(V3d_View) theView, theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z(); } -std::shared_ptr PartSet_Tools::convertTo2D(FeaturePtr theSketch, +std::shared_ptr PartSet_Tools::convertTo2D(FeaturePtr theSketch, const std::shared_ptr& thePnt) { std::shared_ptr aRes; @@ -173,7 +198,8 @@ std::shared_ptr PartSet_Tools::convertTo2D(FeaturePtr theSketch, } -std::shared_ptr PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr theSketch) +std::shared_ptr PartSet_Tools::convertTo3D(const double theX, const double theY, + FeaturePtr theSketch) { std::shared_ptr aData = theSketch->data(); @@ -185,7 +211,7 @@ std::shared_ptr PartSet_Tools::convertTo3D(const double theX, const aData->attribute(SketchPlugin_Sketch::NORM_ID())); std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); - std::shared_ptr aPnt2d = + std::shared_ptr aPnt2d = std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); return aPnt2d->to3D(aC->pnt(), aX->dir(), aY); @@ -270,129 +296,6 @@ void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); } -/*std::shared_ptr PartSet_Tools:: - findAttributePoint(CompositeFeaturePtr theSketch, double theX, double theY, - double theTolerance, const QList& theIgnore) -{ - std::shared_ptr aClickedPoint = std::shared_ptr( - new GeomAPI_Pnt2d(theX, theY)); - - std::list > anAttiributes; - for (int i = 0; i < theSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = theSketch->subFeature(i); - if (!theIgnore.contains(aFeature)) { - anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - - std::list >::const_iterator anIt; - for (anIt = anAttiributes.cbegin(); anIt != anAttiributes.cend(); ++anIt) { - std::shared_ptr aCurPoint = - std::dynamic_pointer_cast(*anIt); - double x = aCurPoint->x(); - double y = aCurPoint->y(); - if (aCurPoint && (aCurPoint->pnt()->distance(aClickedPoint) < theTolerance)) { - return aCurPoint; - } - } - } - } - return std::shared_ptr(); -}*/ - - -std::shared_ptr PartSet_Tools::findFirstEqualPointInArgumentFeatures( - const FeaturePtr& theFeature, const std::shared_ptr& thePoint) -{ - std::shared_ptr aFeaturePoint; - - // may be feature is not updated yet, execute is not performed and references features - // are not created. Case: rectangle macro feature - ModuleBase_Tools::flushUpdated(theFeature); - - std::list anAttributes = theFeature->data()->attributes( - ModelAPI_AttributeRefList::typeId()); - std::list::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end(); - for (; anIt != aLast && !aFeaturePoint.get(); anIt++) { - std::shared_ptr aCurSelList = - std::dynamic_pointer_cast(*anIt); - for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFeaturePoint.get(); i++) { - ObjectPtr anObject = aCurSelList->object(i); - FeaturePtr aFeature = std::dynamic_pointer_cast(anObject); - if (aFeature.get()) - aFeaturePoint = PartSet_Tools::findFirstEqualPoint(aFeature, thePoint); - } - } - return aFeaturePoint; -} - -std::shared_ptr PartSet_Tools::findFirstEqualPoint(const FeaturePtr& theFeature, - const std::shared_ptr& thePoint) -{ - std::shared_ptr aFPoint; - - // find the given point in the feature attributes - std::list > anAttiributes = - theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list >::const_iterator anIt = anAttiributes.begin(), - aLast = anAttiributes.end(); - ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); - - for (; anIt != aLast && !aFPoint; anIt++) { - std::shared_ptr aCurPoint = - std::dynamic_pointer_cast(*anIt); - if (aCurPoint && aCurPoint->isInitialized() && - aValidators->isCase(theFeature, aCurPoint->id()) && - (aCurPoint->pnt()->distance(thePoint) < Precision::Confusion())) { - aFPoint = aCurPoint; - break; - } - } - return aFPoint; -} - -void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, - const std::string& theAttribute, double theClickedX, - double theClickedY) -{ - if (!theFeature.get()) - return; - - std::shared_ptr aClickedPoint = std::shared_ptr( - new GeomAPI_Pnt2d(theClickedX, theClickedY)); - - // find a feature point by the selection mode - std::shared_ptr aFeaturePoint; - if (theFeature->isMacro()) { - // the macro feature will be removed after the operation is stopped, so we need to build - // coicidence to possible sub-features - aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(theFeature, aClickedPoint); - } - else { - aFeaturePoint = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute)); - } - if (!aFeaturePoint) - return; - - // 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 - std::shared_ptr aData = theSketch->data(); - std::shared_ptr aRefList = std::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; - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); - if (!aFeature.get() || theFeature == aFeature) - continue; - std::shared_ptr aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature, - aClickedPoint); - if (aFPoint) - PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint); - } -} - std::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { std::shared_ptr aPlane; @@ -432,174 +335,58 @@ ResultPtr PartSet_Tools::findFixedObjectByExternal(const TopoDS_Shape& theShape, const ObjectPtr& theObject, CompositeFeaturePtr theSketch) { - ResultPtr aResult; - if (theShape.ShapeType() == TopAbs_EDGE) { - // Check that we already have such external edge - std::shared_ptr aInEdge = std::shared_ptr(new GeomAPI_Edge()); - aInEdge->setImpl(new TopoDS_Shape(theShape)); - aResult = findExternalEdge(theSketch, aInEdge); - } - if (theShape.ShapeType() == TopAbs_VERTEX) { - std::shared_ptr aInVert = std::shared_ptr(new GeomAPI_Vertex()); - aInVert->setImpl(new TopoDS_Shape(theShape)); - aResult = findExternalVertex(theSketch, aInVert); + 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 aResult; + return ResultPtr(); } -ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape, - const ObjectPtr& theObject, - CompositeFeaturePtr theSketch, - const bool theTemporary) +ResultPtr PartSet_Tools::createFixedObjectByExternal( + const std::shared_ptr& theShape, + const ObjectPtr& theObject, + CompositeFeaturePtr theSketch, + const bool theTemporary, + FeaturePtr& theCreatedFeature) { - if (theShape.ShapeType() == TopAbs_EDGE) { - Standard_Real aStart, aEnd; - Handle(V3d_View) aNullView; - FeaturePtr aMyFeature; - - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(theShape), aStart, aEnd); - GeomAdaptor_Curve aAdaptor(aCurve); - std::shared_ptr anEdge = std::shared_ptr(new GeomAPI_Edge); - anEdge->setImpl(new TopoDS_Shape(theShape)); - if (aAdaptor.GetType() == GeomAbs_Line) { - // Create line - aMyFeature = theSketch->addFeature(SketchPlugin_Line::ID()); - if (!theObject.get()) { - // There is no selected result - std::shared_ptr aPnt1 = anEdge->firstPoint(); - std::shared_ptr aPnt2 = anEdge->lastPoint(); - std::shared_ptr aPnt2d1 = convertTo2D(theSketch, aPnt1); - std::shared_ptr aPnt2d2 = convertTo2D(theSketch, aPnt2); - - std::shared_ptr aData = aMyFeature->data(); - std::shared_ptr aPoint1 = - std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Line::START_ID())); - std::shared_ptr aPoint2 = - std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Line::END_ID())); - - aPoint1->setValue(aPnt2d1); - aPoint2->setValue(aPnt2d2); - - // If this is an axis then its name has to be changed correspondently - std::string aSuffix = ""; - bool aXdir = fabs(aPnt1->x() - aPnt2->x()) > Precision::Confusion(); - bool aYdir = fabs(aPnt1->y() - aPnt2->y()) > Precision::Confusion(); - bool aZdir = fabs(aPnt1->z() - aPnt2->z()) > Precision::Confusion(); - if (aXdir && (!aYdir) && (!aZdir)) - aSuffix = "X"; - else if ((!aXdir) && aYdir && (!aZdir)) - aSuffix = "Y"; - else if ((!aXdir) && (!aYdir) && aZdir) - aSuffix = "Z"; - if (aSuffix.length() > 0) - aData->setName("Axis_" + aSuffix); - aMyFeature->execute(); - - } - } else if (aAdaptor.GetType() == GeomAbs_Circle) { - if (anEdge->isArc()) { - // Create arc - aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID()); - } - else { - // Create circle - aMyFeature = theSketch->addFeature(SketchPlugin_Circle::ID()); - } - } - if (aMyFeature) { - DataPtr aData = aMyFeature->data(); - AttributeSelectionPtr anAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); - - ResultPtr aRes = std::dynamic_pointer_cast(theObject); - // selection shape has no result owner => the trihedron axis - // TODO: make reference to the real axes when they are implemented in the initialization plugin - if (!aRes.get()) { - ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()->objectByName( - ModelAPI_ResultConstruction::group(), "Origin"); - if (aPointObj.get()) { // if initialization plugin performed well - aRes = std::dynamic_pointer_cast(aPointObj); - } - } - if (!aRes.get()) { - aRes = aMyFeature->firstResult(); - } - if (anAttr.get() && aRes.get()) { - std::shared_ptr anEdge(new GeomAPI_Shape); - anEdge->setImpl(new TopoDS_Shape(theShape)); - - anAttr->setValue(aRes, anEdge); - //if (!theTemporary) { - aMyFeature->execute(); - - // fix this edge - FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID()); - aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())-> - setObject(aMyFeature->lastResult()); - //} - return aMyFeature->lastResult(); - } - } - } - if (theShape.ShapeType() == TopAbs_VERTEX) { - FeaturePtr aMyFeature = theSketch->addFeature(SketchPlugin_Point::ID()); - - if (aMyFeature) { - DataPtr aData = aMyFeature->data(); - AttributeSelectionPtr anAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); - - ResultPtr aRes = std::dynamic_pointer_cast(theObject); - // if there is no object, it means that this is the origin point: search it in the module document - if (!aRes.get()) { - ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()->objectByName( - ModelAPI_ResultConstruction::group(), "Origin"); - if (aPointObj.get()) { // if initialization plugin performed well - aRes = std::dynamic_pointer_cast(aPointObj); - } - } - // reference to itself with name "Origin" (but this may cause the infinitive cycling) - if (!aRes.get()) { - // If the point is selected not from Result object - std::shared_ptr aShape = - std::shared_ptr(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(theShape)); - - std::shared_ptr aVertex = - std::shared_ptr(new GeomAPI_Vertex(aShape)); - std::shared_ptr aPnt = aVertex->point(); - - std::shared_ptr aPnt2d = convertTo2D(theSketch, aPnt); - std::shared_ptr aPoint = - std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Point::COORD_ID())); - aPoint->setValue(aPnt2d); - if ((aPnt->x() < Precision::Confusion()) && - (aPnt->y() < Precision::Confusion()) && - (aPnt->z() < Precision::Confusion())) - aData->setName("Origin"); - - aMyFeature->execute(); - aRes = aMyFeature->firstResult(); - } - if (anAttr.get() && aRes.get()) { - std::shared_ptr aVert(new GeomAPI_Shape); - aVert->setImpl(new TopoDS_Shape(theShape)); - - anAttr->setValue(aRes, aVert); - //if (theTemporary) { - aMyFeature->execute(); - - // fix this edge - FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID()); - aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())-> - setObject(aMyFeature->lastResult()); - //} - return aMyFeature->lastResult(); - } - } + 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(); } @@ -613,83 +400,6 @@ bool PartSet_Tools::isContainPresentation(const QList& return false; } -ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch, std::shared_ptr theEdge) -{ - for (int i = 0; i < theSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = theSketch->subFeature(i); - std::shared_ptr aSketchFea = - std::dynamic_pointer_cast(aFeature); - if (aSketchFea) { - if (aSketchFea->isExternal()) { - std::list aResults = aSketchFea->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - ResultConstructionPtr aRes = - std::dynamic_pointer_cast(*aIt); - if (aRes) { - std::shared_ptr aShape = aRes->shape(); - if (aShape) { - if (theEdge->isEqual(aShape)) - return aRes; - } - } - } - } - } - } - return ResultPtr(); -} - - -ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch, std::shared_ptr theVert) -{ - for (int i = 0; i < theSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = theSketch->subFeature(i); - std::shared_ptr aSketchFea = - std::dynamic_pointer_cast(aFeature); - if (aSketchFea) { - if (aSketchFea->isExternal()) { - std::list aResults = aSketchFea->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - ResultConstructionPtr aRes = - std::dynamic_pointer_cast(*aIt); - if (aRes) { - std::shared_ptr aShape = aRes->shape(); - if (aShape) { - if (theVert->isEqual(aShape)) - return aRes; - } - } - } - } - } - } - return ResultPtr(); -} - - -bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrsPtr& thePrs, FeaturePtr theSketch, - Handle_V3d_View theView, double& theX, double& theY) -{ - bool aHasVertex = false; - - const GeomShapePtr& aShape = thePrs->shape(); - if (aShape.get() && !aShape->isNull() && aShape->shapeType() == GeomAPI_Shape::VERTEX) - { - const TopoDS_Shape& aTDShape = aShape->impl(); - const TopoDS_Vertex& aVertex = TopoDS::Vertex(aTDShape); - if (!aVertex.IsNull()) - { - gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); - PartSet_Tools::convertTo2D(aPoint, theSketch, theView, theX, theY); - aHasVertex = true; - } - } - - return aHasVertex; -} - GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop) { @@ -737,35 +447,32 @@ GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, return aShape; } -std::shared_ptr PartSet_Tools::getPoint(std::shared_ptr& theFeature, - const std::string& theAttribute) +std::shared_ptr PartSet_Tools::getPoint( + std::shared_ptr& theFeature, + const std::string& theAttribute) { - std::shared_ptr aPointAttr; - - if (!theFeature->data()) - return std::shared_ptr(); - - FeaturePtr aFeature; - std::shared_ptr anAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); - if (!anAttr) - return std::shared_ptr(); - - aFeature = ModelAPI_Feature::feature(anAttr->object()); - - if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID()) - aPointAttr = std::dynamic_pointer_cast( - aFeature->data()->attribute(SketchPlugin_Point::COORD_ID())); - - else if (anAttr->attr()) { - aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); - } + 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(); } -FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr thePoint) +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); + + return std::shared_ptr(new GeomAPI_Pnt2d(aX, anY)); +} + +FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, + std::shared_ptr thePoint) { FeaturePtr aCoincident; @@ -774,16 +481,16 @@ FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr aAttr = (*aIt); FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); - if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { - std::shared_ptr a2dPnt = + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + std::shared_ptr a2dPnt = PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A()); - if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + 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)) { + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { aCoincident = aConstrFeature; break; } @@ -805,16 +512,16 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, 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 = + 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)) { + 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)) { + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { aCoincident = aConstrFeature; break; } @@ -837,14 +544,14 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& theList, QList& theCoincidencies, - std::string theAttr) + std::string theAttr, QList& theIsAttributes) { std::shared_ptr aOrig = getCoincedencePoint(theStartCoin); if (aOrig.get() == NULL) return; AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr); - if (!aPnt) + if (!aPnt) return; ObjectPtr aObj = aPnt->object(); FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); @@ -852,19 +559,20 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& 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 (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()); - findCoincidences(aConstrFeature, theList, theCoincidencies, - SketchPlugin_ConstraintCoincidence::ENTITY_B()); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes); } } } @@ -875,23 +583,24 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& ResultConstructionPtr aResult = std::dynamic_pointer_cast(aObj); if (aResult.get()) { FeaturePtr aFeature = ModelAPI_Feature::feature(aPnt->object()); - if (!theList.contains(aFeature)) + 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 (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()); - findCoincidences(aConstrFeature, theList, theCoincidencies, - SketchPlugin_ConstraintCoincidence::ENTITY_B()); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes); } } } @@ -902,15 +611,15 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& std::shared_ptr PartSet_Tools::getCoincedencePoint(FeaturePtr theStartCoin) { - std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), - SketchPlugin_Constraint::ENTITY_A()); + 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, +AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, FeaturePtr theSketch) { @@ -925,15 +634,18 @@ AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z())); // find the given point in the feature attributes - std::list anAttiributes = + std::list anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::const_iterator anIt = anAttiributes.begin(), + std::list::const_iterator anIt = anAttiributes.begin(), aLast = anAttiributes.end(); for (; anIt != aLast && !anAttribute; anIt++) { - std::shared_ptr aCurPoint = + std::shared_ptr aCurPoint = std::dynamic_pointer_cast(*anIt); + if (!aCurPoint->isInitialized()) + continue; - std::shared_ptr aPnt = convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch); + std::shared_ptr aPnt = + convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch); if (aPnt && (aPnt->distance(aValue) < Precision::Confusion())) { anAttribute = aCurPoint; break; @@ -952,7 +664,8 @@ void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite return; static Events_Loop* aLoop = Events_Loop::loop(); - for (int i = 0; i < theComposite->numberOfSubs(); i++) { + int aNumberOfSubs = theComposite->numberOfSubs(); + for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aSubFeature = theComposite->subFeature(i); static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); aECreator->sendUpdated(aSubFeature, theEventId); @@ -974,3 +687,100 @@ bool PartSet_Tools::isAuxiliarySketchEntity(const ObjectPtr& theObject) 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; +} + + +ResultPtr PartSet_Tools::createFixedByExternalCenter( + const ObjectPtr& theObject, + const std::shared_ptr& theEdge, + ModelAPI_AttributeSelection::CenterType theType, + const CompositeFeaturePtr& theSketch, + 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->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(); +} + +void PartSet_Tools::getFirstAndLastIndexInFolder(const ObjectPtr& theFolder, + int& theFirst, int& theLast) +{ + theFirst = -1; + theLast = -1; + + DocumentPtr aDoc = theFolder->document(); + FolderPtr aFolder = std::dynamic_pointer_cast(theFolder); + if (!aFolder.get()) + return; + + AttributeReferencePtr aFirstFeatAttr = + aFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); + if (!aFirstFeatAttr.get()) + return; + FeaturePtr aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value()); + if (!aFirstFeatureInFolder.get()) + return; + + AttributeReferencePtr aLastFeatAttr = + aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID()); + if (!aLastFeatAttr.get()) + return; + FeaturePtr aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value()); + if (!aLastFeatureInFolder.get()) + return; + + theFirst = aDoc->index(aFirstFeatureInFolder); + theLast = aDoc->index(aLastFeatureInFolder); +} \ No newline at end of file