Salome HOME
Copyright update 2021
[modules/shaper_study.git] / src / StudyData / StudyData_Object.cpp
1 // Copyright (C) 2019-2021  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
18 //
19
20 #include "StudyData_Object.h"
21
22 #include <TopExp.hxx>
23 #include <TopoDS_Iterator.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRepTools.hxx>
26 #include <BRepBuilderAPI_Copy.hxx>
27
28 StudyData_Object::StudyData_Object(const std::string theFile)
29 {
30   std::istringstream streamBrep(theFile.c_str());
31   BRep_Builder aBuilder;
32   BRepTools::Read(myShape, streamBrep, aBuilder);
33   myTick = 1;
34   myStream = theFile;
35 }
36
37 StudyData_Object::StudyData_Object()
38 {
39   myTick = 0; // when shape is defined, it will be increased to 1
40 }
41
42 int StudyData_Object::type() const
43 {
44   if (myShape.IsNull())
45     return 8; // GEOM.SHAPE
46   return (int) myShape.ShapeType();
47 }
48
49 std::string StudyData_Object::shapeStream() const
50 {
51   return myStream;
52 }
53
54 std::string StudyData_Object::oldShapeStream() const
55 {
56   return myOldStream.empty() ? myStream : myOldStream;
57 }
58
59 long long StudyData_Object::shape() const
60 {
61   return ((long long)(&myShape));
62 }
63
64 void StudyData_Object::updateShape(const std::string theFile)
65 {
66   if (myStream == theFile) { // absolutely identical shapes, no need to store
67     return;
68   }
69   long aDelta = (long)myStream.size() - (long)theFile.size();
70   aDelta = aDelta < 0 ? -aDelta : aDelta;
71   long aSum = (long)myStream.size() + (long)theFile.size();
72   if (double(aDelta) / aSum < 0.05) { // size-difference is less than 10%
73     // check numbers have the minimal differnce
74     std::istringstream aMyStr(myStream);
75     std::istringstream aFileStr(theFile);
76     double aMyNum, aFileNum;
77     std::string aBuf1, aBuf2;
78     while(aMyStr && aFileStr) {
79       if (aMyStr>>aMyNum) {
80         if (aFileStr>>aFileNum) {
81           if (std::abs(aMyNum - aFileNum) > 1.e-9)
82             break; // different numbers
83         } else {
84           break; // number and not number
85         }
86       } else if (aFileStr>>aFileNum) {
87         break; // number and not number
88       } else { // read two non-numbers
89         aMyStr.clear();
90         aMyStr>>aBuf1;
91         aFileStr.clear();
92         aFileStr>>aBuf2;
93         if (aBuf1 != aBuf2)
94           break; // strings are different
95       }
96     }
97     if (!aMyStr || !aFileStr) // both get to the end with equal content
98       return;
99   }
100
101   // update the current shape
102   std::istringstream streamBrep(theFile.c_str());
103   BRep_Builder aBuilder;
104   myOldShape = myShape;
105   BRepTools::Read(myShape, streamBrep, aBuilder);
106   myTick++;
107   myOldStream = myStream;
108   myStream = theFile;
109 }
110
111 int StudyData_Object::getTick() const
112 {
113   return myTick;
114 }
115
116 void StudyData_Object::setTick(const int theValue)
117 {
118   myTick = theValue;
119 }
120
121 void StudyData_Object::SetShapeByPointer(const long long theShape)
122 {
123   myOldShape = myShape;
124   myShape = *((TopoDS_Shape*)theShape);
125   std::ostringstream aStreamBrep;
126   if (!myShape.IsNull()) {
127     BRepTools::Write(myShape, aStreamBrep);
128   }
129   myOldStream = myStream;
130   myStream = aStreamBrep.str();
131   myTick++;
132 }
133
134 long long StudyData_Object::groupShape(long long theMainShape, const std::list<long> theSelection)
135 {
136   if (myShape.IsNull()) { // compute the cashed shape
137     TopoDS_Shape* aShape = (TopoDS_Shape*)theMainShape;
138     TopTools_IndexedMapOfShape anIndices;
139     TopExp::MapShapes(*aShape, anIndices);
140
141     TopoDS_Compound aResult;
142     BRep_Builder aBuilder;
143     aBuilder.MakeCompound(aResult);
144
145     std::list<long>::const_iterator aSelIter = theSelection.cbegin();
146     for(; aSelIter != theSelection.cend(); aSelIter++) {
147       TopoDS_Shape aSel = anIndices.FindKey(*aSelIter);
148       aBuilder.Add(aResult, aSel);
149     }
150     myShape = aResult;
151   } else { // check myShape equals to the new result
152     TopoDS_Shape* aShape = (TopoDS_Shape*)theMainShape;
153     TopTools_IndexedMapOfShape anIndices;
154     TopExp::MapShapes(*aShape, anIndices);
155     TopoDS_Iterator aMyIter(myShape);
156     std::list<long>::const_iterator aSelIter = theSelection.cbegin();
157     for(; aSelIter != theSelection.cend() && aMyIter.More(); aSelIter++, aMyIter.Next()) {
158       TopoDS_Shape aSel = anIndices.FindKey(*aSelIter);
159       if (!aSel.IsSame(aMyIter.Value()))
160         break;
161     }
162     if (aMyIter.More() || aSelIter != theSelection.cend()) { // recompute myShape
163       TopoDS_Compound aResult;
164       BRep_Builder aBuilder;
165       aBuilder.MakeCompound(aResult);
166       std::list<long>::const_iterator aSelIter = theSelection.cbegin();
167       for(; aSelIter != theSelection.cend(); aSelIter++) {
168         TopoDS_Shape aSel = anIndices.FindKey(*aSelIter);
169         aBuilder.Add(aResult, aSel);
170       }
171       myShape = aResult;
172     }
173   }
174   return (long long)(&myShape);
175 }