X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Tools.cpp;h=24a726a90df03bf938282248b2ab5637556dc8c4;hb=329d73a7dbce38e38063ff41186be492e3529ab5;hp=8afc9aec8ab12d26dd304d15ddbe0cb3dac6c513;hpb=973230a6a9b5c239063e3f7ae7a74601238b2a5f;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 8afc9aec8..24a726a90 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -4,33 +4,343 @@ #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 -gp_Pnt PartSet_Tools::ConvertClickToPoint(QPoint thePoint, Handle(V3d_View) theView) +const double PRECISION_TOLERANCE = 0.000001; + +gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theView) { + if (theView.IsNull()) + return gp_Pnt(); + V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt; - theView->Eye( XEye, YEye, ZEye ); + theView->Eye(XEye, YEye, ZEye); - theView->At( XAt, YAt, ZAt ); - gp_Pnt EyePoint( XEye, YEye, ZEye ); - gp_Pnt AtPoint( 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 ); + gp_Vec EyeVector(EyePoint, AtPoint); + gp_Dir EyeDir(EyeVector); - gp_Pln PlaneOfTheView = gp_Pln( AtPoint, EyeDir ); + gp_Pln PlaneOfTheView = gp_Pln(AtPoint, EyeDir); Standard_Real X, Y, Z; - theView->Convert( thePoint.x(), thePoint.y(), X, Y, Z ); - gp_Pnt ConvertedPoint( X, Y, Z ); + theView->Convert(thePoint.x(), thePoint.y(), 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(), PlaneOfTheView ); + gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView, ConvertedPoint); + 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) +{ + if (!theSketch) + return; + + AttributeDoublePtr anAttr; + boost::shared_ptr aData = theSketch->data(); + + boost::shared_ptr anOrigin = + 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 anY = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_DIRY)); + + gp_Pnt anOriginPnt(anOrigin->x(), anOrigin->y(), anOrigin->z()); + gp_Vec aVec(anOriginPnt, thePoint); + + if (!theView.IsNull()) + { + V3d_Coordinate 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(); + + boost::shared_ptr aNormal = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_NORM)); + 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; + 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) +{ + if (!theSketch) + return; + + boost::shared_ptr aData = theSketch->data(); + + 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)); + + boost::shared_ptr aSum = aC->pnt()->xyz()->added( + aX->dir()->xyz()->multiplied(theX))->added(aY->dir()->xyz()->multiplied(theY)); + + boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt(aSum)); + thePoint = gp_Pnt(aPoint->x(), aPoint->y(), aPoint->z()); +} + +FeaturePtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView, + FeaturePtr theSketch, + const std::list& theFeatures) +{ + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView); + PartSet_Tools::convertTo2D(aPoint, theSketch, theView, aX, anY); + + FeaturePtr aFeature; + std::list::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end(); + + FeaturePtr aDeltaFeature; + double aMinDelta = -1; + ModuleBase_ViewerPrs aPrs; + for (; anIt != aLast; anIt++) { + aPrs = *anIt; + if (!aPrs.result()) + continue; + boost::shared_ptr aSketchFeature = + boost::dynamic_pointer_cast(aPrs.result()); + if (!aSketchFeature) + continue; + double aDelta = aSketchFeature->distanceToPoint( + boost::shared_ptr(new GeomAPI_Pnt2d(aX, anY))); + if (aMinDelta < 0 || aMinDelta > aDelta) { + aMinDelta = aDelta; + aDeltaFeature = aPrs.result(); + } + } + return aDeltaFeature; +} + +boost::shared_ptr PartSet_Tools::document() +{ + return ModelAPI_PluginManager::get()->rootDocument(); +} + +void PartSet_Tools::setFeaturePoint(FeaturePtr theFeature, double theX, double theY, + const std::string& theAttribute) +{ + 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); +} + +void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, + const std::string& theAttribute) +{ + if (!theFeature) + return; + boost::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + if (anAttribute) + anAttribute->setValue(theValue); +} + +double PartSet_Tools::featureValue(FeaturePtr theFeature, const std::string& theAttribute, + bool& isValid) +{ + isValid = false; + double aValue; + if (theFeature) { + boost::shared_ptr aData = theFeature->data(); + AttributeDoublePtr anAttribute = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + if (anAttribute) { + aValue = anAttribute->value(); + isValid = true; + } + } + return aValue; +} + +FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theAttribute, + const std::string& theKind) +{ + FeaturePtr aFeature; + if (!theFeature) + return aFeature; + + boost::shared_ptr aData = theFeature->data(); + boost::shared_ptr anAttr = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + if (anAttr) { + aFeature = anAttr->feature(); + if (!theKind.empty() && aFeature && aFeature->getKind() != theKind) { + aFeature = FeaturePtr(); + } + } + return aFeature; +} + +void PartSet_Tools::createConstraint(FeaturePtr theSketch, + boost::shared_ptr thePoint1, + boost::shared_ptr thePoint2) +{ + boost::shared_ptr aDoc = document(); + FeaturePtr aFeature = aDoc->addFeature(SKETCH_CONSTRAINT_COINCIDENCE_KIND); + + if (theSketch) { + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(theSketch); + aSketch->addSub(aFeature); + } + + boost::shared_ptr aData = aFeature->data(); + + boost::shared_ptr aRef1 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); + aRef1->setAttr(thePoint1); + + boost::shared_ptr aRef2 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_B)); + aRef2->setAttr(thePoint2); + + if (aFeature) // TODO: generate an error if feature was not created + aFeature->execute(); +} + +void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, + const std::string& theAttribute, + double theClickedX, double theClickedY) +{ + // find a feature point by the selection mode + //boost::shared_ptr aPoint = featurePoint(theMode); + boost::shared_ptr aFeaturePoint = + boost::dynamic_pointer_cast(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(aData->attribute(SKETCH_ATTR_FEATURES)); + + 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 + (new GeomAPI_Pnt2d(theClickedX, theClickedY)); + for (; anIt != aLast; anIt++) + { + FeaturePtr aFeature = *anIt; + // find the given point in the feature attributes + anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type()); + std::list >::const_iterator anIt = anAttiributes.begin(), + aLast = anAttiributes.end(); + boost::shared_ptr aFPoint; + for (;anIt!=aLast && !aFPoint; anIt++) { + boost::shared_ptr aCurPoint = + boost::dynamic_pointer_cast(*anIt); + if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion()) + aFPoint = aCurPoint; + } + if (aFPoint) + PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint); + } +} + +boost::shared_ptr PartSet_Tools::sketchPlane(FeaturePtr theSketch) +{ + boost::shared_ptr aPlane; + double aA, aB, aC, aD; + + boost::shared_ptr aData = theSketch->data(); + boost::shared_ptr anOrigin = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_ORIGIN)); + boost::shared_ptr aNormal = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_NORM)); + aA = aNormal->x(); + aB = aNormal->y(); + aC = aNormal->z(); + aD = 0; + + aPlane = boost::shared_ptr(new GeomAPI_Pln(aA, aB, aC, aD)); + return aPlane; +} + +boost::shared_ptr PartSet_Tools::point3D( + boost::shared_ptr thePoint2D, + FeaturePtr theSketch) +{ + boost::shared_ptr aPoint; + if (!theSketch || !thePoint2D) + return aPoint; + + boost::shared_ptr aC = + boost::dynamic_pointer_cast(theSketch->data()->attribute(SKETCH_ATTR_ORIGIN)); + boost::shared_ptr aX = + boost::dynamic_pointer_cast(theSketch->data()->attribute(SKETCH_ATTR_DIRX)); + boost::shared_ptr aY = + boost::dynamic_pointer_cast(theSketch->data()->attribute(SKETCH_ATTR_DIRY)); + + return thePoint2D->to3D(aC->pnt(), aX->dir(), aY->dir()); +} + +bool PartSet_Tools::isConstraintFeature(const std::string& theKind) +{ + return theKind == SKETCH_CONSTRAINT_DISTANCE_KIND || + theKind == SKETCH_CONSTRAINT_LENGTH_KIND || + theKind == SKETCH_CONSTRAINT_RADIUS_KIND; +}