Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom.git into Dev_1.1.0
[modules/shaper.git] / src / SketcherPrs / SketcherPrs_PositionMgr.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        SketcherPrs_PositionMgr.cpp
4 // Created:     13 March 2015
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "SketcherPrs_PositionMgr.h"
8 #include "SketcherPrs_Tools.h"
9
10 #include <GeomAPI_Edge.h>
11 #include <GeomAPI_Curve.h>
12 #include <GeomAPI_Vertex.h>
13 #include <GeomAPI_Dir.h>
14
15 static SketcherPrs_PositionMgr* MyPosMgr = NULL;
16
17
18 SketcherPrs_PositionMgr* SketcherPrs_PositionMgr::get()
19 {
20   if (MyPosMgr == NULL) 
21     MyPosMgr = new SketcherPrs_PositionMgr();
22   return MyPosMgr;
23 }
24
25 SketcherPrs_PositionMgr::SketcherPrs_PositionMgr()
26 {
27 }
28
29
30 int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine, 
31                                               const SketcherPrs_SymbolPrs* thePrs)
32 {
33   if (myShapes.count(theLine) == 1) {
34     PositionsMap& aPosMap = myShapes[theLine];
35     if (aPosMap.count(thePrs) == 1) {
36       return aPosMap[thePrs];
37     } else {
38       int aInd = aPosMap.size();
39       aPosMap[thePrs] = aInd;
40       return aInd;
41     }
42   } else {
43     PositionsMap aPosMap;
44     aPosMap[thePrs] = 0;
45     myShapes[theLine] = aPosMap;
46     return 0;
47   }
48 }
49
50 gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape, 
51                                             const SketcherPrs_SymbolPrs* thePrs,
52                                             double theStep)
53 {
54   std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(theShape);
55   gp_Pnt aP; // Central point
56   gp_Vec aVec1; // main vector
57   if (aShape->isEdge()) {
58     std::shared_ptr<GeomAPI_Curve> aCurve = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
59     std::shared_ptr<GeomAPI_Pnt> aPnt1; // Start point of main vector
60     std::shared_ptr<GeomAPI_Pnt> aPnt2; // End point of main vector
61     if (aCurve->isLine()) {
62       std::shared_ptr<GeomAPI_Edge> aEdge = 
63         std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape));
64
65       aPnt1 = aEdge->firstPoint();
66       aPnt2 = aEdge->lastPoint();
67
68       // Find the middle point
69       aP = gp_Pnt((aPnt1->x() + aPnt2->x())/2.,
70                   (aPnt1->y() + aPnt2->y())/2.,
71                   (aPnt1->z() + aPnt2->z())/2.);
72
73     } else {
74       double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.;
75       std::shared_ptr<GeomAPI_Pnt> aPnt = aCurve->getPoint(aMidParam);
76       aP = aPnt->impl<gp_Pnt>();
77
78       aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.);
79       aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.);
80     }
81     aVec1 = gp_Vec(aPnt1->impl<gp_Pnt>(), aPnt2->impl<gp_Pnt>());
82   } else {
83     // This is a point
84     std::shared_ptr<GeomAPI_Vertex> aVertex = std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
85     std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
86     aP = aPnt->impl<gp_Pnt>();
87
88     std::shared_ptr<GeomAPI_Dir> aDir = thePrs->plane()->dirX();
89     aVec1 = gp_Vec(aDir->impl<gp_Dir>());
90   }
91   gp_Vec aShift = aVec1.Crossed(thePrs->plane()->norm()->impl<gp_Dir>());
92   aShift.Normalize();
93   aShift.Multiply(theStep * 0.8);
94
95   int aPos = getPositionIndex(theShape, thePrs);
96   int aM = 1;
97   if ((aPos % 2) == 0) {
98     // Even position
99     aP.Translate(aShift);
100     if (aPos > 0) {
101       if (aPos % 4 == 0) 
102         aM = aPos / 4;
103       else
104         aM = -(aPos + 2) / 4;
105     }
106   } else {
107     // Odd position
108     aP.Translate(-aShift);
109     if (aPos > 1) {
110       if ((aPos - 1) % 4 == 0) 
111         aM = (aPos - 1) / 4;
112       else
113         aM = -(aPos + 1) / 4;
114     }
115   }
116   if (aPos > 1) {
117     // Normalize vector along the line
118     aVec1.Normalize();
119     aVec1.Multiply(theStep);
120     aP.Translate(aVec1.Multiplied(aM));
121   }
122   return aP;
123 }
124
125 void SketcherPrs_PositionMgr::deleteConstraint(const SketcherPrs_SymbolPrs* thePrs)
126 {
127   std::map<ObjectPtr, PositionsMap>::iterator aIt;
128   std::list<ObjectPtr> aToDel;
129   for (aIt = myShapes.begin(); aIt != myShapes.end(); ++aIt) {
130     PositionsMap& aPosMap = aIt->second;
131     if (aPosMap.count(thePrs) > 0) {
132       aPosMap.erase(aPosMap.find(thePrs));
133       if (aPosMap.size() == 0)
134         aToDel.push_back(aIt->first);
135     }
136   }
137   std::list<ObjectPtr>::const_iterator aListIt;
138   for (aListIt = aToDel.cbegin(); aListIt != aToDel.cend(); ++aListIt) {
139     myShapes.erase(*aListIt);
140   }
141 }