X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=315abbd77907f4c240cc7c230734e82a59db0f9e;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=fbb50228faf57290a384d347d72b2e8b0b0dffec;hpb=0ea6294d5f1a664fbf05fc2cb05ba74e25bac785;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index fbb50228f..315abbd77 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,6 @@ #include #include #include -#include #include @@ -114,15 +114,14 @@ gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theV if (theView.IsNull()) return gp_Pnt(); - V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt; - theView->Eye(XEye, YEye, ZEye); - + Standard_Real XAt, YAt, ZAt; theView->At(XAt, YAt, ZAt); - gp_Pnt EyePoint(XEye, YEye, ZEye); gp_Pnt AtPoint(XAt, YAt, ZAt); - gp_Vec EyeVector(EyePoint, AtPoint); - gp_Dir EyeDir(EyeVector); + double aX, aY, aZ; + theView->Proj(aX, aY, aZ); + gp_Dir EyeDir(aX, aY, aZ); + EyeDir.Reverse(); gp_Pln PlaneOfTheView = gp_Pln(AtPoint, EyeDir); Standard_Real X, Y, Z; @@ -130,9 +129,8 @@ 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(), + return ElSLib::Value(ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView); - return ResultPoint; } void PartSet_Tools::convertTo2D(const gp_Pnt& thePoint, FeaturePtr theSketch, @@ -158,25 +156,27 @@ Handle(V3d_View) theView, gp_Vec aVec(anOriginPnt, thePoint); if (!theView.IsNull()) { - V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt; + Standard_Real XEye, YEye, ZEye, XAt, YAt, ZAt; theView->Eye(XEye, YEye, ZEye); theView->At(XAt, YAt, ZAt); gp_Pnt EyePoint(XEye, YEye, ZEye); gp_Pnt AtPoint(XAt, YAt, ZAt); - gp_Vec anEyeVec(EyePoint, AtPoint); - anEyeVec.Normalize(); + if (EyePoint.Distance(AtPoint) > gp::Resolution()) { + gp_Vec anEyeVec(EyePoint, AtPoint); + anEyeVec.Normalize(); - std::shared_ptr aNormal = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::NORM_ID())); - gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z()); + 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; + double aDen = anEyeVec * aNormalVec; + double aLVec = aDen != 0 ? aVec * aNormalVec / aDen : DBL_MAX; - gp_Vec aDeltaVec = anEyeVec * aLVec; - aVec = aVec - aDeltaVec; + 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(); @@ -383,10 +383,13 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal( anIntoResult->setValue(SKETCH_PROJECTION_INCLUDE_INTO_RESULT); aProjectionFeature->execute(); + ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); + bool isValid = aValidators->validate(aProjectionFeature); + // if projection feature has not been created, exit AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr( SketchPlugin_Projection::PROJECTED_FEATURE_ID()); - if (!aRefAttr || !aRefAttr->isInitialized()) + if (!isValid || !aRefAttr || !aRefAttr->isInitialized()) { // remove external feature if the attribute is not filled std::set aFeatures; @@ -443,9 +446,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; @@ -483,6 +486,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) { @@ -543,9 +564,9 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, /// 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; + std::list::const_iterator aResIt; + for (aResIt = aResults.cbegin(); aResIt != aResults.cend(); ++aResIt) { + ResultPtr aResult = *aResIt; aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint); if (aCoincident.get()) break; @@ -579,8 +600,8 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& 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)) { + std::shared_ptr aCoincPnt = getCoincedencePoint(aConstrFeature); + if (aCoincPnt.get() && aOrig->isEqual(aCoincPnt)) { findCoincidences(aConstrFeature, theList, theCoincidencies, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); findCoincidences(aConstrFeature, theList, theCoincidencies, @@ -594,9 +615,9 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& // 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); + FeaturePtr aFeat = ModelAPI_Feature::feature(aPnt->object()); + if (!theList.contains(aFeat)) + theList.append(aFeat); theCoincidencies.append(theStartCoin); theIsAttributes.append(false); // point attribute on a feature @@ -607,8 +628,8 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& 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)) { + std::shared_ptr aCoincPnt = getCoincedencePoint(aConstrFeature); + if (aCoincPnt.get() && aOrig->isEqual(aCoincPnt)) { findCoincidences(aConstrFeature, theList, theCoincidencies, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes); findCoincidences(aConstrFeature, theList, theCoincidencies, @@ -630,12 +651,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) { @@ -648,29 +701,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) { - double aDistance = aPnt->distance(aValue); - if (aDistance < aMinDistance) { - anAttribute = aCurPoint; - aMinDistance = aPnt->distance(aValue); + 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, @@ -679,7 +735,6 @@ void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite if (!theComposite.get()) return; - static Events_Loop* aLoop = Events_Loop::loop(); int aNumberOfSubs = theComposite->numberOfSubs(); for (int i = 0; i < aNumberOfSubs; i++) { FeaturePtr aSubFeature = theComposite->subFeature(i); @@ -803,12 +858,10 @@ void PartSet_Tools::getDefaultColor(ObjectPtr theObject, const bool isEmptyColor { 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); - } + std::string aSection, aName, aDefault; + theObject->colorConfigInfo(aSection, aName, aDefault); + if (!aSection.empty() && !aName.empty()) { + theColor = Config_PropManager::color(aSection, aName); } if (!isEmptyColorValid && theColor.empty()) { // all AIS objects, where the color is not set, are in black. @@ -851,3 +904,17 @@ 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(); +}