Salome HOME
1. Mirror/Rotation/Translation constraint: using RefList instead of SelectionList
[modules/shaper.git] / src / ModelAPI / ModelAPI_Tools.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModelAPI_Tools.cpp
4 // Created:     06 Aug 2014
5 // Author:      Vitaly Smetannikov
6
7 #include "ModelAPI_Tools.h"
8 #include <ModelAPI_Session.h>
9 #include <ModelAPI_Document.h>
10 #include <ModelAPI_Object.h>
11 #include <ModelAPI_AttributeDouble.h>
12 #include <ModelAPI_ResultParameter.h>
13 #include <ModelAPI_ResultPart.h>
14 #include <ModelAPI_AttributeDocRef.h>
15 #include <list>
16 #include <map>
17
18 namespace ModelAPI_Tools {
19
20 std::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
21 {
22   return theResult->shape();
23 }
24
25 ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, const std::string& theName)
26 {
27   for (int anIndex = 0; anIndex < theDocument->size(theGroup); ++anIndex) {
28     ObjectPtr anObject = theDocument->object(theGroup, anIndex);
29     if (anObject->data()->name() == theName)
30       return anObject;
31   }
32   // not found
33   return ObjectPtr();
34 }
35
36 bool findVariable(const DocumentPtr& theDocument, 
37                   const std::string& theName, double& outValue, ResultParameterPtr& theParam)
38 {
39   ObjectPtr aParamObj = objectByName(theDocument, ModelAPI_ResultParameter::group(), theName);
40   theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
41   if (!theParam.get())
42     return false;
43   AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE());
44   outValue = aValueAttribute->value();
45   return true;
46 }
47
48 bool findVariable(const std::string& theName, double& outValue, ResultParameterPtr& theParam,
49                   const DocumentPtr& theDocument /*= DocumentPtr()*/)
50 {
51   SessionPtr aSession = ModelAPI_Session::get();
52   std::list<DocumentPtr> aDocList;
53   DocumentPtr aDocument = theDocument.get() ? theDocument : aSession->activeDocument();
54   DocumentPtr aRootDocument = aSession->moduleDocument();
55   aDocList.push_back(aDocument);
56   if (aDocument != aRootDocument) {
57     aDocList.push_back(aRootDocument);
58   }
59   for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
60     if (findVariable(*it, theName, outValue, theParam))
61       return true;
62   }
63   return false;
64 }
65
66 static std::map<int, std::vector<int> > myColorMap;
67
68 void appendValues(std::vector<int>& theRGB, const int theRed, const int theGreen, const int theBlue)
69 {
70   theRGB.push_back(theRed);
71   theRGB.push_back(theGreen);
72   theRGB.push_back(theBlue);
73 }
74
75 bool containsValues(std::map<int, std::vector<int> >& theColorMap, std::vector<int>& theValues)
76 {
77   std::map<int, std::vector<int> >::const_iterator anIt = theColorMap.begin(), aLast = theColorMap.end();
78   bool isFound = false;
79   for (; anIt != aLast && !isFound; anIt++) {
80     std::vector<int> aValues = anIt->second;
81     isFound = aValues[0] == theValues[0] &&
82               aValues[1] == theValues[1] &&
83               aValues[2] == theValues[2];
84   }
85   return isFound;
86 }
87
88 std::vector<int> HSVtoRGB(int theH, int theS, int theV)
89 {
90   std::vector<int> aRGB;
91   if (theH < 0 || theH > 360 ||
92       theS < 0 || theS > 100 ||
93       theV < 0 || theV > 100)
94     return aRGB;
95
96   int aHi = (int)theH/60;
97
98   double aV = theV;
99   double aVmin = (100 - theS)*theV/100;
100
101   double anA = (theV - aVmin)* (theH % 60) / 60;
102
103   double aVinc = aVmin + anA;
104   double aVdec = theV - anA;
105
106   double aPercentToValue = 255./100;
107   int aV_int    = (int)(aV*aPercentToValue);
108   int aVinc_int = (int)(aVinc*aPercentToValue);
109   int aVmin_int = (int)(aVmin*aPercentToValue);
110   int aVdec_int = (int)(aVdec*aPercentToValue);
111
112   switch(aHi) {
113     case 0: appendValues(aRGB, aV_int,    aVinc_int, aVmin_int); break;
114     case 1: appendValues(aRGB, aVdec_int, aV_int,    aVmin_int); break;
115     case 2: appendValues(aRGB, aVmin_int, aV_int,    aVinc_int); break;
116     case 3: appendValues(aRGB, aVmin_int, aVdec_int, aV_int); break;
117     case 4: appendValues(aRGB, aVinc_int, aVmin_int, aV_int); break;
118     case 5: appendValues(aRGB, aV_int,    aVmin_int, aVdec_int); break;
119     default: break;
120   }
121   return aRGB;
122 }
123
124
125 void fillColorMap()
126 {
127   if (!myColorMap.empty())
128     return;
129
130   int i = 0;
131   for (int s = 100; s > 0; s = s - 50)
132   {
133     for (int v = 100; v >= 40; v = v - 20)
134     {
135       for (int h = 0; h < 359 ; h = h + 60)
136       {
137         std::vector<int> aColor = HSVtoRGB(h, s, v);
138         if (containsValues(myColorMap, aColor))
139           continue;
140         myColorMap[i] = aColor;
141         i++;
142       }
143     }
144   }
145 }
146
147 void findRandomColor(std::vector<int>& theValues)
148 {
149   theValues.clear();
150   if (myColorMap.empty()) {
151     fillColorMap();
152   }
153
154   int aSize = myColorMap.size();
155   int anIndex = rand() % aSize;
156   if (myColorMap.find(anIndex) != myColorMap.end()) {
157     theValues = myColorMap.at(anIndex);
158   }
159 }
160
161 ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub)
162 {
163   for (int a = theMain->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) {
164     ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(
165         theMain->object(ModelAPI_ResultPart::group(), a));
166     if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == theSub) {
167       return aPart;
168     }
169   }
170   return ResultPtr();
171 }
172
173 CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature)
174 {
175   if (theFeature.get() && theFeature->data()->isValid()) {
176     const std::set<std::shared_ptr<ModelAPI_Attribute> > aRefs = theFeature->data()->refsToMe();
177     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.begin();
178     for(; aRefIter != aRefs.end(); aRefIter++) {
179       CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>
180         ((*aRefIter)->owner());
181       if (aComp.get() && aComp->data()->isValid() && aComp->isSub(theFeature))
182         return aComp;
183     }
184   }
185   return CompositeFeaturePtr(); // not found
186 }
187
188 ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub)
189 {
190   ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theSub);
191   if (aBody.get()) {
192     FeaturePtr aFeatureOwner = aBody->document()->feature(aBody);
193     if (aFeatureOwner.get()) {
194       std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter = 
195         aFeatureOwner->results().cbegin();
196       for(; aResIter != aFeatureOwner->results().cend(); aResIter++) {
197         ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aResIter);
198         if (aComp && aComp->isSub(aBody))
199           return aComp;
200       }
201     }
202   }
203   return ResultCompSolidPtr(); // not found
204 }
205
206 bool hasSubResults(const ResultPtr& theResult)
207 {
208   ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theResult);
209   return aCompSolid.get() && aCompSolid->numberOfSubs() > 0;
210 }
211
212 } // namespace ModelAPI_Tools
213