Salome HOME
Fix for stable processing of mirror constraint (eliminating SolveSpace problems)
[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 const int MyStep = 20;
16
17 static SketcherPrs_PositionMgr* MyPosMgr = NULL;
18
19
20 SketcherPrs_PositionMgr* SketcherPrs_PositionMgr::get()
21 {
22   if (MyPosMgr == NULL) 
23     MyPosMgr = new SketcherPrs_PositionMgr();
24   return MyPosMgr;
25 }
26
27 SketcherPrs_PositionMgr::SketcherPrs_PositionMgr()
28 {
29 }
30
31
32 int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine, 
33                                               Handle(SketcherPrs_SymbolPrs) thePrs)
34 {
35   if (myShapes.count(theLine) == 1) {
36     PositionsMap& aPosMap = myShapes[theLine];
37     if (aPosMap.count(thePrs.Access()) == 1) {
38       return aPosMap[thePrs.Access()];
39     } else {
40       int aInd = aPosMap.size();
41       aPosMap[thePrs.Access()] = aInd;
42       return aInd;
43     }
44   } else {
45     PositionsMap aPosMap;
46     aPosMap[thePrs.Access()] = 0;
47     myShapes[theLine] = aPosMap;
48     return 0;
49   }
50 }
51
52 gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape, 
53                                             Handle(SketcherPrs_SymbolPrs) thePrs)
54 {
55   std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(theShape);
56   gp_Pnt aP; // Central point
57   gp_Vec aVec1; // main vector
58   if (aShape->isEdge()) {
59     std::shared_ptr<GeomAPI_Curve> aCurve = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
60     std::shared_ptr<GeomAPI_Pnt> aPnt1; // Start point of main vector
61     std::shared_ptr<GeomAPI_Pnt> aPnt2; // End point of main vector
62     if (aCurve->isLine()) {
63       std::shared_ptr<GeomAPI_Edge> aEdge = 
64         std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape));
65
66       aPnt1 = aEdge->firstPoint();
67       aPnt2 = aEdge->lastPoint();
68
69       // Find the middle point
70       aP = gp_Pnt((aPnt1->x() + aPnt2->x())/2.,
71                   (aPnt1->y() + aPnt2->y())/2.,
72                   (aPnt1->z() + aPnt2->z())/2.);
73
74     } else {
75       double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.;
76       std::shared_ptr<GeomAPI_Pnt> aPnt = aCurve->getPoint(aMidParam);
77       aP = aPnt->impl<gp_Pnt>();
78
79       aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.);
80       aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.);
81     }
82     aVec1 = gp_Vec(aPnt1->impl<gp_Pnt>(), aPnt2->impl<gp_Pnt>());
83   } else {
84     // This is a point
85     std::shared_ptr<GeomAPI_Vertex> aVertex = std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
86     std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
87     aP = aPnt->impl<gp_Pnt>();
88
89     std::shared_ptr<GeomAPI_Dir> aDir = thePrs->plane()->dirX();
90     aVec1 = gp_Vec(aDir->impl<gp_Dir>());
91   }
92   gp_Vec aShift = aVec1.Crossed(thePrs->plane()->norm()->impl<gp_Dir>());
93   aShift.Normalize();
94   aShift.Multiply(MyStep);
95
96   int aPos = getPositionIndex(theShape, thePrs);
97   int aM = 1;
98   if ((aPos % 2) == 0) {
99     // Even position
100     aP.Translate(aShift);
101     if (aPos > 0) {
102       if (aPos % 4 == 0) 
103         aM = aPos / 4;
104       else
105         aM = -(aPos + 2) / 4;
106     }
107   } else {
108     // Odd position
109     aP.Translate(-aShift);
110     if (aPos > 1) {
111       if (aPos % 4 == 0) 
112         aM = (aPos - 1) / 4;
113       else
114         aM = -(aPos + 1) / 4;
115     }
116   }
117   if (aPos > 1) {
118     // Normalize vector along the line
119     aVec1.Normalize();
120     aVec1.Multiply(MyStep);
121     aP.Translate(aVec1.Multiplied(aM));
122   }
123   return aP;
124 }
125
126 void SketcherPrs_PositionMgr::deleteConstraint(Handle(SketcherPrs_SymbolPrs) thePrs)
127 {
128   std::map<ObjectPtr, PositionsMap>::iterator aIt;
129   for (aIt = myShapes.begin(); aIt != myShapes.end(); ++aIt) {
130     PositionsMap& aPosMap = aIt->second;
131     if (aPosMap.count(thePrs.Access()) > 0) 
132       aPosMap.erase(aPosMap.find(thePrs.Access()));
133   }
134   for (aIt = myShapes.begin(); aIt != myShapes.end(); ++aIt) {
135     if (aIt->second.size() == 0) {
136       myShapes.erase(aIt);
137       aIt = myShapes.begin();
138     }
139   }
140 }