Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / SketcherPrs / SketcherPrs_PositionMgr.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "SketcherPrs_PositionMgr.h"
21 #include "SketcherPrs_Tools.h"
22
23 #include <GeomAPI_Edge.h>
24 #include <GeomAPI_Curve.h>
25 #include <GeomAPI_Vertex.h>
26 #include <GeomAPI_Dir.h>
27
28 static SketcherPrs_PositionMgr* MyPosMgr = NULL;
29
30 // The class is implemented as a singlton
31 SketcherPrs_PositionMgr* SketcherPrs_PositionMgr::get()
32 {
33   if (MyPosMgr == NULL)
34     MyPosMgr = new SketcherPrs_PositionMgr();
35   return MyPosMgr;
36 }
37
38 SketcherPrs_PositionMgr::SketcherPrs_PositionMgr()
39 {
40 }
41
42
43 int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine,
44                                               const SketcherPrs_SymbolPrs* thePrs)
45 {
46   if (myShapes.count(theLine) == 1) {
47     // Find the map and add new [Presentation - Index] pair
48     PositionsMap& aPosMap = myShapes[theLine];
49     if (aPosMap.count(thePrs) == 1) {
50       // return existing index
51       return aPosMap[thePrs];
52     } else {
53       // Add a new [Presentation - Index] pair
54       int aInd = int(aPosMap.size());
55       aPosMap[thePrs] = aInd;
56       return aInd;
57     }
58   } else {
59     // Create a new map with initial index
60     PositionsMap aPosMap;
61     aPosMap[thePrs] = 0;
62     myShapes[theLine] = aPosMap;
63     return 0;
64   }
65 }
66
67 gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape,
68                                             const SketcherPrs_SymbolPrs* thePrs,
69                                             double theStep)
70 {
71   std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(theShape);
72   gp_Pnt aP; // Central point
73   gp_Vec aVec1; // main vector
74   if (aShape->isEdge()) {
75     std::shared_ptr<GeomAPI_Curve> aCurve =
76       std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
77     std::shared_ptr<GeomAPI_Pnt> aPnt1; // Start point of main vector
78     std::shared_ptr<GeomAPI_Pnt> aPnt2; // End point of main vector
79     if (aCurve->isLine()) {
80       std::shared_ptr<GeomAPI_Edge> aEdge =
81         std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape));
82
83       aPnt1 = aEdge->firstPoint();
84       aPnt2 = aEdge->lastPoint();
85
86       // Find the middle point
87       aP = gp_Pnt((aPnt1->x() + aPnt2->x())/2.,
88                   (aPnt1->y() + aPnt2->y())/2.,
89                   (aPnt1->z() + aPnt2->z())/2.);
90
91     } else {
92       // this is a circle or arc
93       double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.;
94       std::shared_ptr<GeomAPI_Pnt> aPnt = aCurve->getPoint(aMidParam);
95       aP = aPnt->impl<gp_Pnt>();
96
97       aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.);
98       aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.);
99     }
100     aVec1 = gp_Vec(aPnt1->impl<gp_Pnt>(), aPnt2->impl<gp_Pnt>());
101   } else {
102     // This is a point
103     std::shared_ptr<GeomAPI_Vertex> aVertex =
104       std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
105     std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
106     aP = aPnt->impl<gp_Pnt>();
107
108     std::shared_ptr<GeomAPI_Dir> aDir = thePrs->plane()->dirX();
109     aVec1 = gp_Vec(aDir->impl<gp_Dir>());
110   }
111   // Compute shifting vector for a one symbol
112   gp_Vec aShift = aVec1.Crossed(thePrs->plane()->normal()->impl<gp_Dir>());
113   aShift.Normalize();
114   aShift.Multiply(theStep * 0.8);
115
116   // Shift the position coordinate according to position index
117   int aPos = getPositionIndex(theShape, thePrs);
118   int aM = 1;
119   if ((aPos % 2) == 0) {
120     // Even position
121     aP.Translate(aShift);
122     if (aPos > 0) {
123       if (aPos % 4 == 0)
124         aM = aPos / 4;
125       else
126         aM = -(aPos + 2) / 4;
127     }
128   } else {
129     // Odd position
130     aP.Translate(-aShift);
131     if (aPos > 1) {
132       if ((aPos - 1) % 4 == 0)
133         aM = (aPos - 1) / 4;
134       else
135         aM = -(aPos + 1) / 4;
136     }
137   }
138   if (aPos > 1) {
139     // Normalize vector along the line
140     aVec1.Normalize();
141     aVec1.Multiply(theStep);
142     aP.Translate(aVec1.Multiplied(aM));
143   }
144   return aP;
145 }
146
147 void SketcherPrs_PositionMgr::deleteConstraint(const SketcherPrs_SymbolPrs* thePrs)
148 {
149   std::map<ObjectPtr, PositionsMap>::iterator aIt;
150   std::list<ObjectPtr> aToDel;
151   // Clear map for deleted presentation
152   for (aIt = myShapes.begin(); aIt != myShapes.end(); ++aIt) {
153     PositionsMap& aPosMap = aIt->second;
154     if (aPosMap.count(thePrs) > 0) {
155       // Erase index
156       aPosMap.erase(aPosMap.find(thePrs));
157       if (aPosMap.size() == 0)
158         // Delete the map
159         aToDel.push_back(aIt->first);
160       else {
161         // Reindex objects positions in order to avoid spaces
162         PositionsMap::iterator aIt;
163         int i = 0;
164         for (aIt = aPosMap.begin(); aIt != aPosMap.end(); aIt++, i++)
165           aIt->second = i;
166       }
167     }
168   }
169   std::list<ObjectPtr>::const_iterator aListIt;
170   for (aListIt = aToDel.cbegin(); aListIt != aToDel.cend(); ++aListIt) {
171     myShapes.erase(*aListIt);
172   }
173 }