-// Copyright (C) 2014-2017 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
//
// 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<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <PartSet_Tools.h>
#include <ModelGeomAlgo_Point2D.h>
#include <Events_Loop.h>
+#include <Events_InfoMessage.h>
#include <SketcherPrs_Tools.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Dir.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
#include <GeomAPI_Pln.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_Pnt.h>
#include <GeomAPI_Edge.h>
#include <GeomAPI_Vertex.h>
+#include <GeomAPI_ShapeExplorer.h>
#include <GeomAPI_Dir.h>
#include <GeomAPI_XYZ.h>
#include <AIS_InteractiveObject.hxx>
#include <StdSelect_BRepOwner.hxx>
#include <SelectMgr_IndexedMapOfOwner.hxx>
-#include <V3d_Coordinate.hxx>
#include <QMouseEvent>
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;
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,
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<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
- aData->attribute(SketchPlugin_Sketch::NORM_ID()));
- gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z());
+ std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ 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();
return aPlane;
}
+void PartSet_Tools::nullifySketchPlane(CompositeFeaturePtr theSketch)
+{
+ std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+ theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+ std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+
+ aNormal->reset();
+ anOrigin->reset();
+}
+
std::shared_ptr<GeomAPI_Pnt> PartSet_Tools::point3D(std::shared_ptr<GeomAPI_Pnt2d> thePoint2D,
CompositeFeaturePtr theSketch)
{
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<FeaturePtr> aFeatures;
// attribute, returns the shape
PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(theWorkshop->module());
PartSet_SketcherMgr* aSketchMgr = aModule->sketchMgr();
- AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(anAttributeFeature,
- aBRepShape, aSketchMgr->activeSketch());
- if (aPntAttr.get() != NULL && aPntAttr == theAttribute) {
+ std::pair<AttributePtr, int> aPntAttrIndex = PartSet_Tools::findAttributeBy2dPoint(
+ anAttributeFeature, aBRepShape, aSketchMgr->activeSketch());
+ if (aPntAttrIndex.first.get() != NULL && aPntAttrIndex.first == theAttribute) {
aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
aShape->setImpl(new TopoDS_Shape(aBRepShape));
break;
return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY));
}
+std::shared_ptr<GeomAPI_Pnt2d> 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<GeomAPI_Pnt2d> thePoint)
{
/// Find by result
if (!aCoincident.get()) {
std::list<ResultPtr> aResults = theFeature->results();
- std::list<ResultPtr>::const_iterator aIt;
- for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
- ResultPtr aResult = *aIt;
+ std::list<ResultPtr>::const_iterator aResIt;
+ for (aResIt = aResults.cbegin(); aResIt != aResults.cend(); ++aResIt) {
+ ResultPtr aResult = *aResIt;
aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint);
if (aCoincident.get())
break;
FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
if (!theCoincidencies.contains(aConstrFeature)) {
- std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
- if (aPnt.get() && aOrig->isEqual(aPnt)) {
+ std::shared_ptr<GeomAPI_Pnt2d> aCoincPnt = getCoincedencePoint(aConstrFeature);
+ if (aCoincPnt.get() && aOrig->isEqual(aCoincPnt)) {
findCoincidences(aConstrFeature, theList, theCoincidencies,
SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes);
findCoincidences(aConstrFeature, theList, theCoincidencies,
// Find by Results
ResultConstructionPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(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
FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
if (!theCoincidencies.contains(aConstrFeature)) {
- std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
- if (aPnt.get() && aOrig->isEqual(aPnt)) {
+ std::shared_ptr<GeomAPI_Pnt2d> aCoincPnt = getCoincedencePoint(aConstrFeature);
+ if (aCoincPnt.get() && aOrig->isEqual(aCoincPnt)) {
findCoincidences(aConstrFeature, theList, theCoincidencies,
SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes);
findCoincidences(aConstrFeature, theList, theCoincidencies,
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<GeomDataAPI_Point2D>(theAttribute)),
+ myArray(std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(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<AttributePtr, int> 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) {
// find the given point in the feature attributes
std::list<AttributePtr> anAttiributes =
aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<AttributePtr> anArrays =
+ aFeature->data()->attributes(GeomDataAPI_Point2DArray::typeId());
+ anAttiributes.insert(anAttiributes.end(), anArrays.begin(), anArrays.end());
+
std::list<AttributePtr>::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<GeomDataAPI_Point2D> aCurPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
- if (!aCurPoint->isInitialized())
- continue;
-
- std::shared_ptr<GeomAPI_Pnt> 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<GeomAPI_Pnt> 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<AttributePtr, int>(anAttribute, aPointIndex);
}
void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite,
if (!theComposite.get())
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);
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<ModelAPI_Folder>(theFolder);
if (!aFolder.get())
AttributeReferencePtr aFirstFeatAttr =
aFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ if (!aFirstFeatAttr.get())
+ return;
FeaturePtr aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
- if (!aFirstFeatureInFolder.get()) {
- theFirst = -1;
+ if (!aFirstFeatureInFolder.get())
return;
- }
- AttributeReferencePtr aLastFeatAttr =
- aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
- FeaturePtr aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
- if (!aLastFeatureInFolder.get()) {
- theLast = -1;
+
+ FeaturePtr aLastFeatureInFolder = aFolder->lastVisibleFeature();
+ if (!aLastFeatureInFolder.get())
return;
- }
theFirst = aDoc->index(aFirstFeatureInFolder);
theLast = aDoc->index(aLastFeatureInFolder);
-}
\ No newline at end of file
+}
+
+
+void PartSet_Tools::getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid,
+ std::vector<int>& theColor)
+{
+ theColor.clear();
+ // get default color from the preferences manager for the given result
+ 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.
+ // 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<ModelAPI_Result>(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();
+}