X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=d88fd2ac20da9cfaa78d8898040c52feaee2aec7;hb=20ead226b1355fcf49d396036e6527b2ac043cb0;hp=3cfa835db921703800889a8d995ff0aaeab7cb67;hpb=d8d98cccf4ca2dae9466d115ce9961a3ce8431e6;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 3cfa835db..d88fd2ac2 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -1,16 +1,42 @@ -// File: PartSet_Tools.h +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: PartSet_Tools.cpp // Created: 28 Apr 2014 // Author: Natalia ERMOLAEVA #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 #include @@ -18,27 +44,46 @@ #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 +#include +#include +#include +#include +#include +#include #ifdef _DEBUG #include #endif const double PRECISION_TOLERANCE = 0.000001; +const int AIS_DEFAULT_WIDTH = 2; + +int PartSet_Tools::getAISDefaultWidth() +{ + return AIS_DEFAULT_WIDTH; +} gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theView) { @@ -61,32 +106,34 @@ gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theV gp_Pnt ConvertedPoint(X, Y, Z); gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView, ConvertedPoint); - gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView); + gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), + PlaneOfTheView); return ResultPoint; } void PartSet_Tools::convertTo2D(const gp_Pnt& thePoint, FeaturePtr theSketch, - Handle(V3d_View) theView, double& theX, double& theY) +Handle(V3d_View) theView, + double& theX, double& theY) { if (!theSketch) return; - boost::shared_ptr anAttr; - boost::shared_ptr aData = theSketch->data(); + AttributeDoublePtr anAttr; + std::shared_ptr aData = theSketch->data(); - boost::shared_ptr anOrigin = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_ORIGIN)); + std::shared_ptr anOrigin = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_DIRX)); - boost::shared_ptr anY = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_DIRY)); + 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 anY = aNorm->xyz()->cross(aX->xyz()); gp_Pnt anOriginPnt(anOrigin->x(), anOrigin->y(), anOrigin->z()); gp_Vec aVec(anOriginPnt, thePoint); - if (!theView.IsNull()) - { + if (!theView.IsNull()) { V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt; theView->Eye(XEye, YEye, ZEye); @@ -97,223 +144,824 @@ void PartSet_Tools::convertTo2D(const gp_Pnt& thePoint, FeaturePtr theSketch, gp_Vec anEyeVec(EyePoint, AtPoint); anEyeVec.Normalize(); - boost::shared_ptr aNormal = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_NORM)); + std::shared_ptr aNormal = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z()); double aDen = anEyeVec * aNormalVec; double aLVec = aDen != 0 ? aVec * aNormalVec / aDen : DBL_MAX; - gp_Vec aDeltaVec = anEyeVec*aLVec; + gp_Vec aDeltaVec = anEyeVec * aLVec; aVec = aVec - aDeltaVec; } theX = aVec.X() * aX->x() + aVec.Y() * aX->y() + aVec.Z() * aX->z(); 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) + 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); +} + + +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())); + 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()))); + + std::shared_ptr aPnt2d = + std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); + + return aPnt2d->to3D(aC->pnt(), aX->dir(), aY); +} + +std::shared_ptr PartSet_Tools::document() +{ + return ModelAPI_Session::get()->moduleDocument(); +} + +void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, + const std::string& theAttribute) +{ + if (!theFeature) return; + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( + aData->attribute(theAttribute)); + if (anAttribute) + anAttribute->setValue(theValue); +} - boost::shared_ptr aData = theSketch->data(); +double PartSet_Tools::featureValue(FeaturePtr theFeature, const std::string& theAttribute, + bool& isValid) +{ + isValid = false; + double aValue = 0; + if (theFeature) { + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( + aData->attribute(theAttribute)); + if (anAttribute) { + aValue = anAttribute->value(); + isValid = true; + } + } + return aValue; +} - boost::shared_ptr aC = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_ORIGIN)); - boost::shared_ptr aX = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_DIRX)); - boost::shared_ptr aY = - boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_DIRY)); +FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theAttribute, + const std::string& theKind) +{ + FeaturePtr aFeature; + if (!theFeature) + return aFeature; + + std::shared_ptr aData = theFeature->data(); + std::shared_ptr anAttr = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(theAttribute)); + if (anAttr) { + aFeature = std::dynamic_pointer_cast(anAttr->object()); + if (!theKind.empty() && aFeature && aFeature->getKind() != theKind) { + aFeature = FeaturePtr(); + } + } + return aFeature; +} + +void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, + std::shared_ptr thePoint1, + std::shared_ptr thePoint2) +{ + FeaturePtr aFeature; + if (theSketch) { + aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } else { + std::shared_ptr aDoc = document(); + aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } + + std::shared_ptr aData = aFeature->data(); + + std::shared_ptr aRef1 = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); + aRef1->setAttr(thePoint1); + + std::shared_ptr aRef2 = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); + aRef2->setAttr(thePoint2); + + // we need to flush created signal in order to coincidence is processed by solver + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); +} - boost::shared_ptr aSum = aC->pnt()->xyz()->added( - aX->dir()->xyz()->multiplied(theX))->added(aY->dir()->xyz()->multiplied(theY)); +/*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(); +}*/ - boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt(aSum)); - thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z()); + +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; } -void PartSet_Tools::intersectLines(double theX0, double theY0, double theX1, double theY1, - double theX2, double theY2, double theX3, double theY3, - double& theX, double& theY) +std::shared_ptr PartSet_Tools::findFirstEqualPoint(const FeaturePtr& theFeature, + const std::shared_ptr& thePoint) { - double aV1 = theX1 - theX0, aV2 = theY1 - theY0; - double aW1 = theX3 - theX2, aW2 = theY3 - theY2; - - double aT2 = 0; - if (aV1 != 0 && aV2 != 0) - aT2 = (( theY2 - theY0 )/aV2 - ( theX2 - theX0 )/aV1) / ( aW1/aV1 - aW2/aV2 ); - else - aT2 = DBL_MAX; - - theX = theX2 + aT2*aW1; - theY = theY2 + aT2*aW2; - - // the coordinates of two lines are on the common line - //It is not possible to use Precision::Confusion(), because it is e-0.8, but V is sometimes e-6 - Standard_Real aPrec = PRECISION_TOLERANCE; - if (fabs(theX - theX0) < aPrec && fabs(theY - theY0) < aPrec) { - projectPointOnLine(theX2, theY2, theX3, theY3, theX1, theY1, theX, theY); + 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::projectPointOnLine(double theX1, double theY1, double theX2, double theY2, - double thePointX, double thePointY, double& theX, double& theY) +void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, + const std::string& theAttribute, double theClickedX, + double theClickedY) { - theX = theY = 0; + if (!theFeature.get()) + return; - Handle(Geom_Line) aLine = new Geom_Line(gp_Pnt(theX1, theY1, 0), - gp_Dir(gp_Vec(gp_Pnt(theX1, theY1, 0), gp_Pnt(theX2, theY2, 0)))); - GeomAPI_ProjectPointOnCurve aProj(gp_Pnt(thePointX, thePointY, 0), aLine); + std::shared_ptr aClickedPoint = std::shared_ptr( + new GeomAPI_Pnt2d(theClickedX, theClickedY)); - Standard_Integer aNbPoint = aProj.NbPoints(); - if (aNbPoint > 0) { - gp_Pnt aPoint = aProj.Point(1); - theX = aPoint.X(); - theY = aPoint.Y(); + // 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) || (aFeaturePoint->owner() == aFeature)) + continue; + std::shared_ptr aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature, + aClickedPoint); + if (aFPoint) + PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint); } } -boost::shared_ptr PartSet_Tools::createFeaturePrs(const std::string& theKind, - FeaturePtr theSketch, - FeaturePtr theFeature) +std::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { - PartSet_FeaturePrs* aFeaturePrs; + 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 (theKind == PartSet_FeaturePointPrs::getKind()) { - aFeaturePrs = new PartSet_FeaturePointPrs(theSketch); + 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; + 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); } - else if (theKind == PartSet_FeatureLinePrs::getKind()) { - aFeaturePrs = new PartSet_FeatureLinePrs(theSketch); + 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); } - else if (theKind == PartSet_FeatureCirclePrs::getKind()) { - aFeaturePrs = new PartSet_FeatureCirclePrs(theSketch); + 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()); + } + 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()); + // 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(); + } + } } - else if (theKind == PartSet_FeatureArcPrs::getKind()) { - aFeaturePrs = new PartSet_FeatureArcPrs(theSketch); + 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(); + } + } } - if (theFeature) - aFeaturePrs->init(theFeature, FeaturePtr()); + return ResultPtr(); +} - return boost::shared_ptr(aFeaturePrs); +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; } -FeaturePtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, - FeaturePtr theSketch, - const std::list& theFeatures) +ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch, std::shared_ptr theEdge) { - double aX, anY; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView); - PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY); + 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(); +} - FeaturePtr aFeature; - std::list::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end(); - FeaturePtr aDeltaFeature; - double aMinDelta = -1; - XGUI_ViewerPrs aPrs; - for (; anIt != aLast; anIt++) { - aPrs = *anIt; - if (!aPrs.feature()) - continue; - double aDelta = distanceToPoint(aPrs.feature(), aX, anY); - if (aMinDelta < 0 || aMinDelta > aDelta) { - aMinDelta = aDelta; - aDeltaFeature = aPrs.feature(); +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 aDeltaFeature; + return ResultPtr(); } -double PartSet_Tools::distanceToPoint(FeaturePtr theFeature, - double theX, double theY) + +bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrsPtr& thePrs, FeaturePtr theSketch, + Handle_V3d_View theView, double& theX, double& theY) { - boost::shared_ptr aFeaturePrs = PartSet_Tools::createFeaturePrs( - theFeature->getKind(), FeaturePtr(), theFeature); - double aDelta = 0; - if (aFeaturePrs) - aDelta = aFeaturePrs->distanceToPoint(theFeature, theX, theY); + bool aHasVertex = false; - return aDelta; + 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; } -void PartSet_Tools::moveFeature(FeaturePtr theFeature, double theDeltaX, double theDeltaY) +GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, + ModuleBase_IWorkshop* theWorkshop) { - if (!theFeature) - return; - - boost::shared_ptr aFeaturePrs = PartSet_Tools::createFeaturePrs( - theFeature->getKind(), FeaturePtr(), theFeature); - if (aFeaturePrs) - aFeaturePrs->move(theDeltaX, theDeltaY); + 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++) { + 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; + } + } + } + } + } + } + } + return aShape; } -boost::shared_ptr PartSet_Tools::document() +std::shared_ptr PartSet_Tools::getPoint(std::shared_ptr& theFeature, + const std::string& theAttribute) { - return ModelAPI_PluginManager::get()->rootDocument(); + 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(); } -void PartSet_Tools::setFeaturePoint(FeaturePtr theFeature, double theX, double theY, - const std::string& theAttribute) +FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr thePoint) { - 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); + 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; } -void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, - const std::string& theAttribute) +FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, + std::shared_ptr thePoint) { - if (!theFeature) - return; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr anAttribute = - boost::dynamic_pointer_cast(aData->attribute(theAttribute)); - if (anAttribute) - anAttribute->setValue(theValue); + 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->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::createConstraint(FeaturePtr theSketch, - boost::shared_ptr thePoint1, - boost::shared_ptr thePoint2) +void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& theList, + QList& theCoincidencies, + std::string theAttr) { - boost::shared_ptr aDoc = document(); - FeaturePtr aFeature = aDoc->addFeature(SKETCH_CONSTRAINT_COINCIDENCE_KIND); + std::shared_ptr aOrig = getCoincedencePoint(theStartCoin); + if (aOrig.get() == NULL) + return; - if (theSketch) { - boost::shared_ptr aSketch = - boost::dynamic_pointer_cast(theSketch); - aSketch->addSub(aFeature); + 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); + 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()); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + } + } + } + } + } + } 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); + + 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()); + findCoincidences(aConstrFeature, theList, theCoincidencies, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + } + } + } + } + } } +} - boost::shared_ptr aData = aFeature->data(); +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; +} - boost::shared_ptr aRef1 = - boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); - aRef1->setAttr(thePoint1); +AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch) +{ - boost::shared_ptr aRef2 = - boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_B)); - aRef2->setAttr(thePoint2); + 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; - if (aFeature) // TODO: generate an error if feature was not created - aFeature->execute(); + 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); } -boost::shared_ptr PartSet_Tools::findPoint(FeaturePtr theFeature, - double theX, double theY) +bool PartSet_Tools::isAuxiliarySketchEntity(const ObjectPtr& theObject) { - boost::shared_ptr aFeaturePrs = PartSet_Tools::createFeaturePrs( - theFeature->getKind(), FeaturePtr(), theFeature); + 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(); - boost::shared_ptr aPoint2D; - if (aFeaturePrs) - aPoint2D = aFeaturePrs->findPoint(theFeature, theX, theY); - return aPoint2D; + return isAuxiliaryFeature; }