]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_Tools.cpp
Salome HOME
refs #30 - Sketch base GUI: create, draw lines
[modules/shaper.git] / src / PartSet / PartSet_Tools.cpp
1 // File:        PartSet_Tools.h
2 // Created:     28 Apr 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_Tools.h>
6
7 #include <V3d_View.hxx>
8 #include <gp_Pln.hxx>
9 #include <ProjLib.hxx>
10 #include <ElSLib.hxx>
11
12 #include <ModelAPI_Data.h>
13 #include <ModelAPI_AttributeDouble.h>
14 #include <GeomDataAPI_Point.h>
15 #include <GeomDataAPI_Dir.h>
16 #include <GeomAPI_Dir.h>
17 #include <GeomAPI_XYZ.h>
18 #include <SketchPlugin_Sketch.h>
19
20 #ifdef _DEBUG
21 #include <QDebug>
22 #endif
23
24 const double PRECISION_TOLERANCE = 0.000001;
25
26 gp_Pnt PartSet_Tools::ConvertClickToPoint(QPoint thePoint, Handle(V3d_View) theView)
27 {
28   if (theView.IsNull())
29     return gp_Pnt();
30
31   V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt;
32   theView->Eye(XEye, YEye, ZEye);
33
34   theView->At(XAt, YAt, ZAt);
35   gp_Pnt EyePoint(XEye, YEye, ZEye);
36   gp_Pnt AtPoint(XAt, YAt, ZAt);
37
38   gp_Vec EyeVector(EyePoint, AtPoint);
39   gp_Dir EyeDir(EyeVector);
40
41   gp_Pln PlaneOfTheView = gp_Pln(AtPoint, EyeDir);
42   Standard_Real X, Y, Z;
43   theView->Convert(thePoint.x(), thePoint.y(), X, Y, Z);
44   gp_Pnt ConvertedPoint(X, Y, Z);
45
46   gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView, ConvertedPoint);
47   gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView);
48   return ResultPoint;
49 }
50
51 void PartSet_Tools::ConvertTo2D(const gp_Pnt& thePoint, boost::shared_ptr<ModelAPI_Feature> theSketch,
52                                 Handle(V3d_View) theView, double& theX, double& theY)
53 {
54   if (!theSketch)
55     return;
56
57   boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
58   boost::shared_ptr<ModelAPI_Data> aData = theSketch->data();
59
60   boost::shared_ptr<GeomDataAPI_Point> anOrigin = 
61     boost::dynamic_pointer_cast<GeomDataAPI_Point>(aData->attribute(SKETCH_ATTR_ORIGIN));
62
63   boost::shared_ptr<GeomDataAPI_Dir> aX = 
64     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRX));
65   boost::shared_ptr<GeomDataAPI_Dir> anY = 
66     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRY));
67
68   gp_Pnt anOriginPnt(anOrigin->x(), anOrigin->y(), anOrigin->z());
69   gp_Vec aVec(anOriginPnt, thePoint);
70
71   if (!theView.IsNull())
72   {
73     V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt;
74     theView->Eye(XEye, YEye, ZEye);
75
76     theView->At(XAt, YAt, ZAt);
77     gp_Pnt EyePoint(XEye, YEye, ZEye);
78     gp_Pnt AtPoint(XAt, YAt, ZAt);
79
80     gp_Vec anEyeVec(EyePoint, AtPoint);
81     anEyeVec.Normalize();
82
83     boost::shared_ptr<GeomDataAPI_Dir> aNormal = 
84                   boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
85     gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z());
86
87     double aDen = anEyeVec * aNormalVec;
88     double aLVec = aDen != 0 ? aVec * aNormalVec / aDen : DBL_MAX;
89
90     gp_Vec aDeltaVec = anEyeVec*aLVec;
91     aVec = aVec - aDeltaVec;
92   }
93   theX = aVec.X() * aX->x() + aVec.Y() * aX->y() + aVec.Z() * aX->z();
94   theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z();
95 }
96
97 void PartSet_Tools::IntersectLines(double theX0, double theX1, double theX2, double theX3,
98                                    double theY0, double theY1, double theY2, double theY3,
99                                    double& theX, double& theY)
100 {
101   double aV1 = theX1 - theX0, aV2 = theY1 - theY0;
102   double aW1 = theX3 - theX2, aW2 = theY3 - theY2;
103
104   double aT2 = 0;
105   if (aV1  != 0 && aV2 != 0)
106     aT2 = (( theY2 - theY0 )/aV2 - ( theX2 - theX0 )/aV1) / ( aW1/aV1 - aW2/aV2 );
107   else
108     aT2 = DBL_MAX;
109
110   theX  = theX2 + aT2*aW1;
111   theY = theY2 + aT2*aW2;
112
113   // the coordinates of two lines are on the common line
114   //It is not possible to use Precision::Confusion(), because it is e-0.8, but V is sometimes e-6
115   Standard_Real aPrec = PRECISION_TOLERANCE;
116   if (fabs(theX - theX0) < aPrec && fabs(theY - theY0) < aPrec) {
117     ProjectPointOnLine(theX2, theX3, theY2, theY3, theX1, theY1, theX, theY);    
118   }
119 }
120
121 void PartSet_Tools::ProjectPointOnLine(double theX1, double theX2, double theY1, double theY2,
122                                        double thePointX, double thePointY, double& theX, double& theY)
123 {
124   //GEOM_Line aLine(gp_Pnt(theX1, theY1), gp_Dir(gp_Vec(gp_Pnt(theX1, theY1), gp_Pnt(theX2, theY2))));
125   //GeomAPI_ProjectPointOnCurve aProj(gp_Pnt(thePointX, thePointY));
126   /*  
127   Standard_Integer aNbPoint = aProj.NbPoints();
128   if (aNbPoint > 0) {
129     for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) {
130       gp_Pnt aNewPoint = aProj.Point( j );
131       theParameter = aProj.Parameter( j );
132
133       int aX, anY;
134       CurveCreator_Utils::ConvertPointToClick( aNewPoint, theView, aX, anY );
135
136       isFound = isEqualPixels( aX, anY, theX, theY, SCENE_PIXEL_PROJECTION_TOLERANCE, theDelta );
137     }
138   }
139   return isFound;
140   */
141 }