X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=09f2e143726776d661a379a62fd906eacffb590c;hb=d6d93bc8be11df99d82dc34232e924502333f0d6;hp=2a5f0f08d0ee6ed45326ecb64c9e6f68b10cfce3;hpb=7074394f8f08413d885f63be01df6bd5007b868c;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp old mode 100755 new mode 100644 index 2a5f0f08d..09f2e1437 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 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 @@ -12,10 +12,9 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include @@ -37,6 +36,7 @@ #include #include +#include #include @@ -49,11 +49,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -70,6 +72,8 @@ #include #include #include +#include +#include #include #include @@ -89,6 +93,7 @@ #include #include #include +#include #include @@ -98,6 +103,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() { @@ -308,6 +314,17 @@ std::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theS return aPlane; } +void PartSet_Tools::nullifySketchPlane(CompositeFeaturePtr theSketch) +{ + 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())); + + aNormal->reset(); + anOrigin->reset(); +} + std::shared_ptr PartSet_Tools::point3D(std::shared_ptr thePoint2D, CompositeFeaturePtr theSketch) { @@ -331,201 +348,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); + 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; } - 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); + 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(); } - return aResult; -} - -ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape, - const ObjectPtr& theObject, - CompositeFeaturePtr theSketch, - const bool theTemporary) -{ - 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()); - if (theShape.Orientation() == TopAbs_REVERSED) - aMyFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(true); - } - 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(); - - // issue #2125: Naming problem: two edges in Naming for one circle on solid - // this is result of boolean and seamedge - if (aAdaptor.GetType() == GeomAbs_Circle) { - ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators(); - if (!aFactory->validate(aMyFeature)) { - anAttr->setValue(ResultPtr(), GeomShapePtr()); - std::set aFeatures; - aFeatures.insert(aMyFeature); - ModelAPI_Tools::removeFeaturesAndReferences(aFeatures); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); - - return ResultPtr(); - } - } + FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object()); + if (aProjection.get() && aProjection->lastResult().get()) + return aProjection->lastResult(); - // // fix this edge - // FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID()); - // aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())-> - // setObject(aMyFeature->lastResult()); - // // we need to flush created signal in order to fixed constraint is processed by solver - // Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - //} - 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()); - // // we need to flush created signal in order to fixed constraint is processed by solver - // Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - //} - return aMyFeature->lastResult(); - } - } - } return ResultPtr(); } @@ -539,86 +413,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); - // not displayed result of feature projection should not be returned as external edge - if (aSketchFea && aSketchFea->canBeDisplayed()) { - 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) { @@ -650,9 +444,9 @@ GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, // 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) { + std::pair aPntAttrIndex = PartSet_Tools::findAttributeBy2dPoint( + anAttributeFeature, aBRepShape, aSketchMgr->activeSketch()); + if (aPntAttrIndex.first.get() != NULL && aPntAttrIndex.first == theAttribute) { aShape = std::shared_ptr(new GeomAPI_Shape); aShape->setImpl(new TopoDS_Shape(aBRepShape)); break; @@ -690,6 +484,24 @@ std::shared_ptr PartSet_Tools::getPnt2d(QMouseEvent* theEvent, return std::shared_ptr(new GeomAPI_Pnt2d(aX, anY)); } +std::shared_ptr PartSet_Tools::getPnt2d(const Handle(V3d_View)& theView, + const TopoDS_Shape& theShape, + const FeaturePtr& theSketch) +{ + GeomPnt2dPtr aPoint2D; + if (!theShape.IsNull() && theShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(theShape); + if (!aVertex.IsNull()) { + // the case when the point is taken from the existing vertex + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + double aX, aY; + PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, aY); + aPoint2D.reset(new GeomAPI_Pnt2d(aX, aY)); + } + } + return aPoint2D; +} + FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr thePoint) { @@ -731,7 +543,7 @@ 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()) { + 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)) { @@ -837,12 +649,44 @@ std::shared_ptr PartSet_Tools::getCoincedencePoint(FeaturePtr the return aPnt; } -AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, - const TopoDS_Shape theShape, - FeaturePtr theSketch) +class PointWrapper +{ +public: + PointWrapper(AttributePtr theAttribute) + : myPoint(std::dynamic_pointer_cast(theAttribute)), + myArray(std::dynamic_pointer_cast(theAttribute)) + {} + + int size() const { return myPoint.get() ? 1 : (myArray.get() ? myArray->size() : 0); } + + GeomPointPtr point(int theIndex, FeaturePtr theSketch) + { + GeomPnt2dPtr aP2d; + if (myPoint.get()) + aP2d = myPoint->pnt(); + else if (myArray.get()) + aP2d = myArray->pnt(theIndex); + + GeomPointPtr aP3d; + if (aP2d.get()) + aP3d = PartSet_Tools::convertTo3D(aP2d->x(), aP2d->y(), theSketch); + return aP3d; + } + + bool isArray() const { return myArray.get(); } + +private: + AttributePoint2DPtr myPoint; + AttributePoint2DArrayPtr myArray; +}; + +std::pair PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch) { AttributePtr anAttribute; + int aPointIndex = -1; FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); if (aFeature) { if (theShape.ShapeType() == TopAbs_VERTEX) { @@ -855,25 +699,32 @@ AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, // find the given point in the feature attributes std::list anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list anArrays = + aFeature->data()->attributes(GeomDataAPI_Point2DArray::typeId()); + anAttiributes.insert(anAttiributes.end(), anArrays.begin(), anArrays.end()); + std::list::const_iterator anIt = anAttiributes.begin(), aLast = anAttiributes.end(); + double aMinDistance = 1.e-6; // searching for point with minimal distance and < 1.e-6 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; + PointWrapper aWrapper(*anIt); + for (int anIndex = 0, aSize = aWrapper.size(); anIndex < aSize; ++anIndex) { + std::shared_ptr aPnt = aWrapper.point(anIndex, theSketch); + if (aPnt) { + double aDistance = aPnt->distance(aValue); + if (aDistance < aMinDistance) { + anAttribute = *anIt; + if (aWrapper.isArray()) + aPointIndex = anIndex; + aMinDistance = aPnt->distance(aValue); + } + } } } } } } - return anAttribute; + return std::pair(anAttribute, aPointIndex); } void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite, @@ -883,7 +734,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); @@ -906,28 +758,164 @@ 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) + bool theTemporary, + FeaturePtr& theCreatedFeature) { - FeaturePtr aMyFeature = theSketch->addFeature(SketchPlugin_Point::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(); - if (aMyFeature) { - DataPtr aData = aMyFeature->data(); - AttributeSelectionPtr anAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); + return ResultPtr(); +} - ResultPtr aRes = std::dynamic_pointer_cast(theObject); - if (anAttr.get() && aRes.get()) { - anAttr->setValueCenter(aRes, theEdge, theType, theTemporary); - aMyFeature->execute(); - return aMyFeature->lastResult(); +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; + + FeaturePtr aLastFeatureInFolder = aFolder->lastVisibleFeature(); + if (!aLastFeatureInFolder.get()) + return; + + theFirst = aDoc->index(aFirstFeatureInFolder); + theLast = aDoc->index(aLastFeatureInFolder); +} + + +void PartSet_Tools::getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid, + std::vector& theColor) +{ + theColor.clear(); + // get default color from the preferences manager for the given result + if (theColor.empty()) { + std::string aSection, aName, aDefault; + theObject->colorConfigInfo(aSection, aName, aDefault); + if (!aSection.empty() && !aName.empty()) { + theColor = Config_PropManager::color(aSection, aName); } } - return ResultPtr(); + if (!isEmptyColorValid && theColor.empty()) { + // all AIS objects, where the color is not set, are in black. + // The color should be defined in XML or set in the attribute + theColor = Config_PropManager::color("Visualization", "object_default_color"); + Events_InfoMessage("PartSet_Tools", + "A default color is not defined in the preferences for this result type").send(); + } +} + +double PartSet_Tools::getDefaultDeflection(const ObjectPtr& theObject) +{ + double aDeflection = -1; + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + bool isConstruction = false; + + std::string aResultGroup = aResult->groupName(); + if (aResultGroup == ModelAPI_ResultConstruction::group()) + isConstruction = true; + else if (aResultGroup == ModelAPI_ResultBody::group()) { + GeomShapePtr aGeomShape = aResult->shape(); + if (aGeomShape.get()) { + // if the shape could not be exploded on faces, it contains only wires, edges, and vertices + // correction of deviation for them should not influence to the application performance + GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE); + isConstruction = !anExp.more(); + } + } + if (isConstruction) + aDeflection = Config_PropManager::real("Visualization", "construction_deflection"); + else + aDeflection = Config_PropManager::real("Visualization", "body_deflection"); + } + return aDeflection; +} + + +double PartSet_Tools::getDefaultTransparency() +{ + return Config_PropManager::integer("Visualization", "shaper_default_transparency") / 100.; +} + +QCursor PartSet_Tools::getOperationCursor() +{ + int aId = Config_PropManager::integer(SKETCH_TAB_NAME, "operation_cursor"); + switch (aId) { + case 0: + return QCursor(Qt::ArrowCursor); + case 1: + return QCursor(Qt::CrossCursor); + case 2: + return QCursor(Qt::PointingHandCursor); + } + return QCursor(); }