X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=f6e8ae84fe8645128b6b020f056cf3e409b41207;hb=c11c3bbeb38d103a882fc24c0f2cb933b20d4053;hp=668cb4653b28ced6903969b4fda8b250d0279b7f;hpb=8c99e5e8dd74d99dfbf534bd66b32b70ca134aa7;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 668cb4653..f6e8ae84f 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -43,6 +45,8 @@ #include #include #include +#include +#include #ifdef _DEBUG #include @@ -84,14 +88,14 @@ Handle(V3d_View) theView, return; AttributeDoublePtr anAttr; - boost::shared_ptr aData = theSketch->data(); + std::shared_ptr aData = theSketch->data(); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( + std::shared_ptr anOrigin = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( + std::shared_ptr aX = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr anY = boost::dynamic_pointer_cast( + std::shared_ptr anY = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRY_ID())); gp_Pnt anOriginPnt(anOrigin->x(), anOrigin->y(), anOrigin->z()); @@ -108,7 +112,7 @@ Handle(V3d_View) theView, gp_Vec anEyeVec(EyePoint, AtPoint); anEyeVec.Normalize(); - boost::shared_ptr aNormal = boost::dynamic_pointer_cast( + std::shared_ptr aNormal = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::NORM_ID())); gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z()); @@ -122,74 +126,102 @@ Handle(V3d_View) theView, theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z(); } -void PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr theSketch, - gp_Pnt& thePoint) +std::shared_ptr PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr theSketch) { - if (!theSketch) - return; - - boost::shared_ptr aData = theSketch->data(); + std::shared_ptr aData = theSketch->data(); - boost::shared_ptr aC = boost::dynamic_pointer_cast( + std::shared_ptr aC = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( + std::shared_ptr aX = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aY = boost::dynamic_pointer_cast( + std::shared_ptr aY = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::DIRY_ID())); - boost::shared_ptr aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX)) - ->added(aY->dir()->xyz()->multiplied(theY)); + std::shared_ptr aPnt2d = + std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); - boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt(aSum)); - thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z()); + return aPnt2d->to3D(aC->pnt(), aX->dir(), aY->dir()); } -FeaturePtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, - FeaturePtr theSketch, - const QList& theFeatures) +ObjectPtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, + FeaturePtr theSketch, + const QList& theSelected, + const QList& theHighlighted) { - double aX, anY; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView); - PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY); + // firstly it finds the feature in the list of highlight + ObjectPtr aDeltaObject = nearestFeature(thePoint, theView, theSketch, theHighlighted); + if (!aDeltaObject) + // secondly it finds the feature in the list of selected objects + aDeltaObject = nearestFeature(thePoint, theView, theSketch, theSelected); - FeaturePtr aFeature; - FeaturePtr aDeltaFeature; - double aMinDelta = -1; - ModuleBase_ViewerPrs aPrs; - foreach (ModuleBase_ViewerPrs aPrs, theFeatures) { - if (!aPrs.object()) - continue; - boost::shared_ptr aSketchFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(aPrs.object()); - if (!aSketchFeature) - continue; - double aDelta = aSketchFeature->distanceToPoint( - boost::shared_ptr(new GeomAPI_Pnt2d(aX, anY))); - if (aMinDelta < 0 || aMinDelta > aDelta) { - aMinDelta = aDelta; - // TODO aDeltaFeature = aPrs.result(); + return aDeltaObject; +} + +ObjectPtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, + FeaturePtr theSketch, + const QList& thePresentations) +{ + ObjectPtr aDeltaObject; + + CompositeFeaturePtr aSketch = + std::dynamic_pointer_cast(theSketch); + // 1. find it in the selected list by the selected point + if (!aDeltaObject) { + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView); + PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY); + + FeaturePtr aFeature; + double aMinDelta = -1; + ModuleBase_ViewerPrs aPrs; + foreach (ModuleBase_ViewerPrs aPrs, thePresentations) { + if (!aPrs.object()) + continue; + FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object()); + std::shared_ptr aSketchFeature = std::dynamic_pointer_cast< + SketchPlugin_Feature>(aFeature); + if (!aSketchFeature || !aSketch->isSub(aSketchFeature)) + continue; + + double aDelta = aSketchFeature->distanceToPoint( + std::shared_ptr(new GeomAPI_Pnt2d(aX, anY))); + if (aMinDelta < 0 || aMinDelta > aDelta) { + aMinDelta = aDelta; + // TODO aDeltaObject = aPrs.result(); + } + } + } + // 2. if the object is not found, returns the first selected sketch feature + if (!aDeltaObject && thePresentations.size() > 0) { + // there can be some highlighted objects, e.g. a result of boolean operation and a sketch point + foreach (ModuleBase_ViewerPrs aPrs, thePresentations) { + if (!aPrs.object()) + continue; + FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object()); + if (aFeature && aSketch->isSub(aFeature)) + aDeltaObject = aPrs.object(); } } - return aDeltaFeature; + return aDeltaObject; } -boost::shared_ptr PartSet_Tools::document() +std::shared_ptr PartSet_Tools::document() { return ModelAPI_Session::get()->moduleDocument(); } -boost::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr theFeature, +std::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr theFeature, double theX, double theY) { - boost::shared_ptr aClickedPoint = boost::shared_ptr( + std::shared_ptr aClickedPoint = std::shared_ptr( new GeomAPI_Pnt2d(theX, theY)); - std::list > anAttiributes = + std::list > anAttiributes = theFeature->data()->attributes(GeomDataAPI_Point2D::type()); - std::list >::const_iterator anIt = anAttiributes.begin(), + std::list >::const_iterator anIt = anAttiributes.begin(), aLast = anAttiributes.end(); - boost::shared_ptr aFPoint; + std::shared_ptr aFPoint; for (; anIt != aLast && !aFPoint; anIt++) { - boost::shared_ptr aCurPoint = boost::dynamic_pointer_cast< + std::shared_ptr aCurPoint = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(*anIt); if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion()) aFPoint = aCurPoint; @@ -203,8 +235,8 @@ void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, { if (!theFeature) return; - boost::shared_ptr aData = theFeature->data(); - AttributeDoublePtr anAttribute = boost::dynamic_pointer_cast( + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( aData->attribute(theAttribute)); if (anAttribute) anAttribute->setValue(theValue); @@ -214,10 +246,10 @@ double PartSet_Tools::featureValue(FeaturePtr theFeature, const std::string& the bool& isValid) { isValid = false; - double aValue; + double aValue = 0; if (theFeature) { - boost::shared_ptr aData = theFeature->data(); - AttributeDoublePtr anAttribute = boost::dynamic_pointer_cast( + std::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = std::dynamic_pointer_cast( aData->attribute(theAttribute)); if (anAttribute) { aValue = anAttribute->value(); @@ -234,11 +266,11 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA if (!theFeature) return aFeature; - boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr anAttr = boost::dynamic_pointer_cast< + std::shared_ptr aData = theFeature->data(); + std::shared_ptr anAttr = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(theAttribute)); if (anAttr) { - aFeature = boost::dynamic_pointer_cast(anAttr->object()); + aFeature = std::dynamic_pointer_cast(anAttr->object()); if (!theKind.empty() && aFeature && aFeature->getKind() != theKind) { aFeature = FeaturePtr(); } @@ -247,24 +279,24 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA } void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, - boost::shared_ptr thePoint1, - boost::shared_ptr thePoint2) + std::shared_ptr thePoint1, + std::shared_ptr thePoint2) { FeaturePtr aFeature; if (theSketch) { aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } else { - boost::shared_ptr aDoc = document(); + std::shared_ptr aDoc = document(); aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } - boost::shared_ptr aData = aFeature->data(); + std::shared_ptr aData = aFeature->data(); - boost::shared_ptr aRef1 = boost::dynamic_pointer_cast< + std::shared_ptr aRef1 = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); aRef1->setAttr(thePoint1); - boost::shared_ptr aRef2 = boost::dynamic_pointer_cast< + std::shared_ptr aRef2 = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); aRef2->setAttr(thePoint2); @@ -277,32 +309,32 @@ void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr the double theClickedY) { // find a feature point by the selection mode - //boost::shared_ptr aPoint = featurePoint(theMode); - boost::shared_ptr aFeaturePoint = boost::dynamic_pointer_cast< + //std::shared_ptr aPoint = featurePoint(theMode); + std::shared_ptr 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 - boost::shared_ptr aData = theSketch->data(); - boost::shared_ptr aRefList = boost::dynamic_pointer_cast< + 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; - boost::shared_ptr aClickedPoint = boost::shared_ptr( + std::list > anAttiributes; + std::shared_ptr aClickedPoint = std::shared_ptr( new GeomAPI_Pnt2d(theClickedX, theClickedY)); for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = boost::dynamic_pointer_cast(*anIt); + FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); // find the given point in the feature attributes anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type()); - std::list >::const_iterator anIt = anAttiributes.begin(), + std::list >::const_iterator anIt = anAttiributes.begin(), aLast = anAttiributes.end(); - boost::shared_ptr aFPoint; + std::shared_ptr aFPoint; for (; anIt != aLast && !aFPoint; anIt++) { - boost::shared_ptr aCurPoint = boost::dynamic_pointer_cast< + std::shared_ptr aCurPoint = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(*anIt); if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion()) aFPoint = aCurPoint; @@ -312,37 +344,45 @@ void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr the } } -boost::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) +std::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { - boost::shared_ptr aPlane; - double aA, aB, aC, aD; + std::shared_ptr aPlane; - boost::shared_ptr aData = theSketch->data(); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( + std::shared_ptr aData = theSketch->data(); + std::shared_ptr anOrigin = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aNormal = boost::dynamic_pointer_cast( + std::shared_ptr aNormal = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Sketch::NORM_ID())); - aA = aNormal->x(); - aB = aNormal->y(); - aC = aNormal->z(); - aD = 0; - - aPlane = boost::shared_ptr(new GeomAPI_Pln(aA, aB, aC, aD)); + if (aNormal && anOrigin) { + double adX = aNormal->x(); + double adY = aNormal->y(); + double adZ = aNormal->z(); + + if ( (adX != 0) || (adY != 0) || (adZ != 0) ) { // Plane is valid + double aX = anOrigin->x(); + double aY = anOrigin->y(); + double aZ = anOrigin->z(); + gp_Pln aPln(gp_Pnt(aX, aY, aZ), gp_Dir(adX, adY, adZ)); + double aA, aB, aC, aD; + aPln.Coefficients(aA, aB, aC, aD); + aPlane = std::shared_ptr(new GeomAPI_Pln(aA, aB, aC, aD)); + } + } return aPlane; } -boost::shared_ptr PartSet_Tools::point3D(boost::shared_ptr thePoint2D, +std::shared_ptr PartSet_Tools::point3D(std::shared_ptr thePoint2D, CompositeFeaturePtr theSketch) { - boost::shared_ptr aPoint; + std::shared_ptr aPoint; if (!theSketch || !thePoint2D) return aPoint; - boost::shared_ptr aC = boost::dynamic_pointer_cast( + std::shared_ptr aC = std::dynamic_pointer_cast( theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( + std::shared_ptr aX = std::dynamic_pointer_cast( theSketch->data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aY = boost::dynamic_pointer_cast( + std::shared_ptr aY = std::dynamic_pointer_cast( theSketch->data()->attribute(SketchPlugin_Sketch::DIRY_ID())); return thePoint2D->to3D(aC->pnt(), aX->dir(), aY->dir()); @@ -356,45 +396,34 @@ bool PartSet_Tools::isConstraintFeature(const std::string& theKind) || theKind == SketchPlugin_ConstraintRigid::ID(); } -ResultPtr PartSet_Tools::createFixedObjectByEdge(const ModuleBase_ViewerPrs& thePrs, CompositeFeaturePtr theSketch) +ResultPtr PartSet_Tools::createFixedObjectByEdge(const TopoDS_Shape& theShape, + const ObjectPtr& theObject, + CompositeFeaturePtr theSketch) { - TopoDS_Shape aShape = thePrs.shape(); - if (aShape.ShapeType() != TopAbs_EDGE) + if (theShape.ShapeType() != TopAbs_EDGE) return ResultPtr(); + // Check that we already have such external edge + std::shared_ptr aInEdge = std::shared_ptr(new GeomAPI_Edge()); + aInEdge->setImpl(new TopoDS_Shape(theShape)); + ResultPtr aResult = findExternalEdge(theSketch, aInEdge); + if (aResult) + return aResult; + + // If not found then we have to create new Standard_Real aStart, aEnd; Handle(V3d_View) aNullView; FeaturePtr aMyFeature; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aStart, aEnd); + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(theShape), aStart, aEnd); GeomAdaptor_Curve aAdaptor(aCurve); if (aAdaptor.GetType() == GeomAbs_Line) { // Create line aMyFeature = theSketch->addFeature(SketchPlugin_Line::ID()); - - //DataPtr aData = myFeature->data(); - //boost::shared_ptr anEndAttr = - // boost::dynamic_pointer_cast(aData->attribute(SketchPlugin_Line::END_ID())); - - //double aX, aY; - //gp_Pnt Pnt1 = aAdaptor.Value(aStart); - //convertTo2D(Pnt1, theSketch, aNullView, aX, aY); - //setFeaturePoint(myFeature, aX, aY, SketchPlugin_Line::START_ID()); - - //gp_Pnt Pnt2 = aAdaptor.Value(aEnd); - //convertTo2D(Pnt2, theSketch, aNullView, aX, aY); - //setFeaturePoint(myFeature, aX, aY, SketchPlugin_Line::END_ID()); } else if (aAdaptor.GetType() == GeomAbs_Circle) { if (aAdaptor.IsClosed()) { // Create circle aMyFeature = theSketch->addFeature(SketchPlugin_Circle::ID()); - //gp_Circ aCirc = aAdaptor.Circle(); - //gp_Pnt aCenter = aCirc.Location(); - - //double aX, aY; - //convertTo2D(aCenter, theSketch, aNullView, aX, aY); - //setFeaturePoint(myFeature, aX, aY, SketchPlugin_Circle::CENTER_ID()); - //setFeatureValue(myFeature, aCirc.Radius(), SketchPlugin_Circle::RADIUS_ID()); } else { // Create arc aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID()); @@ -403,13 +432,13 @@ ResultPtr PartSet_Tools::createFixedObjectByEdge(const ModuleBase_ViewerPrs& the if (aMyFeature) { DataPtr aData = aMyFeature->data(); AttributeSelectionPtr anAttr = - boost::dynamic_pointer_cast + std::dynamic_pointer_cast (aData->attribute(SketchPlugin_Feature::EXTERNAL_ID())); - ResultPtr aRes = boost::dynamic_pointer_cast(thePrs.object()); + ResultPtr aRes = std::dynamic_pointer_cast(theObject); if (anAttr && aRes) { - boost::shared_ptr anEdge(new GeomAPI_Shape); - anEdge->setImpl(new TopoDS_Shape(aShape)); + std::shared_ptr anEdge(new GeomAPI_Shape); + anEdge->setImpl(new TopoDS_Shape(theShape)); anAttr->setValue(aRes, anEdge); @@ -435,3 +464,86 @@ bool PartSet_Tools::isContainPresentation(const QList& the } 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(); +} + +bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrs& thePrs, FeaturePtr theSketch, + Handle_V3d_View theView, double& theX, double& theY) +{ + bool aHasVertex = false; + + const TopoDS_Shape& aShape = thePrs.shape(); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) + { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); + if (!aVertex.IsNull()) + { + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + PartSet_Tools::convertTo2D(aPoint, theSketch, theView, theX, theY); + aHasVertex = true; + } + } + + return aHasVertex; +} + +AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch) +{ + + AttributePtr anAttribute; + FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); + if (aFeature) { + if (theShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(theShape); + if (!aVertex.IsNull()) { + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + std::shared_ptr aValue = std::shared_ptr( + new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z())); + + // find the given point in the feature attributes + std::list anAttiributes = + aFeature->data()->attributes(GeomDataAPI_Point2D::type()); + std::list::const_iterator anIt = anAttiributes.begin(), + aLast = anAttiributes.end(); + for (; anIt != aLast && !anAttribute; anIt++) { + std::shared_ptr aCurPoint = + std::dynamic_pointer_cast(*anIt); + + std::shared_ptr aPnt = convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch); + if (aPnt && (aPnt->distance(aValue) < Precision::Confusion())) { + anAttribute = aCurPoint; + break; + } + } + } + } + } + return anAttribute; +}