Salome HOME
d76a2c600c12d0085cd2e301f4b6da32a6b41aa1
[modules/geom.git] / src / GEOMClient / GEOM_Client.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : GEOM_Client.cxx
23 //  Author : Yves FRICAUD/Lucien PIGNOLONI
24 //  Module : GEOM
25
26 #include <Standard_Stream.hxx>
27
28 #include <sstream>
29
30 #include "GEOM_Client.hxx"
31 #include <SALOMEconfig.h>
32 #include "Basics_Utils.hxx"
33 #include "utilities.h"
34
35 #include <BRep_Builder.hxx>
36 #include <BRepTools.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TCollection_AsciiString.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopExp.hxx>
42 #include <TopAbs.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44
45 #ifdef WIN32
46 #include <process.h>
47 #else
48 #include <unistd.h>
49 #endif
50
51 #include CORBA_SERVER_HEADER(SALOMEDS)
52 #include CORBA_SERVER_HEADER(GEOM_Gen)
53
54 #define HST_CLIENT_LEN 256
55
56 //=======================================================================
57 // function : Load()
58 // purpose  :
59 //=======================================================================
60 TopoDS_Shape GEOM_Client::Load( GEOM::GEOM_Gen_ptr geom, GEOM::GEOM_Object_ptr aShape )
61 {
62   std::string hst_client = Kernel_Utils::GetHostname();
63
64   Engines::Container_var ctn_server = geom->GetContainerRef();
65   long                   pid_server = ctn_server->getPID();
66
67   CORBA::String_var hostname = ctn_server->getHostName();
68   if ( pid_client == pid_server && !strcmp(hst_client.c_str(), hostname.in()) ) {
69     TopoDS_Shape* S = (TopoDS_Shape*)(aShape->getShape());
70     return(*S);
71   } else {
72     /* get sequence of bytes of resulting brep shape from GEOM server */
73     TopoDS_Shape S;
74     SALOMEDS::TMPFile_var SeqFile = aShape->GetShapeStream();
75     /*int sizebuf = */SeqFile->length();
76     char* buf;
77     buf = (char*) &SeqFile[0];
78     std::istringstream streamBrep(buf);
79     BRep_Builder aBuilder;
80     BRepTools::Read(S, streamBrep, aBuilder);
81     return(S);
82   }
83 }
84
85 //=======================================================================
86 // function : Create()
87 // purpose  : Create in client not in a container
88 //=======================================================================
89 GEOM_Client::GEOM_Client()
90 {
91   pid_client =
92 #ifdef WIN32
93     (long)_getpid();
94 #else
95     (long)getpid();
96 #endif
97 }
98
99 //=======================================================================
100 // function : Create()
101 // purpose  : Copy constructor
102 //=======================================================================
103 GEOM_Client::GEOM_Client(const GEOM_Client& client)
104 {
105   _mySubShapes = client._mySubShapes;
106   myShapesMap = client.myShapesMap;
107   pid_client = client.pid_client;
108 }
109
110 //=======================================================================
111 // function : Create()
112 // purpose  :
113 //=======================================================================
114 GEOM_Client::GEOM_Client(Engines::Container_ptr client)
115 {
116   pid_client = client->getPID();
117 }
118
119 //=======================================================================
120 // function : get_client()
121 // purpose  : Static method to have the only one instance of GEOM_Client
122 //=======================================================================
123 #ifdef SINGLE_CLIENT
124 GEOM_Client& GEOM_Client::get_client()
125 {
126   static GEOM_Client a;
127   return a;
128 }
129 #else
130 GEOM_Client GEOM_Client::get_client()
131 {
132   return GEOM_Client();
133 }
134 #endif
135
136 //=======================================================================
137 // function : Find()
138 // purpose  :
139 //=======================================================================
140 Standard_Boolean GEOM_Client::Find (const TCollection_AsciiString& IOR, TopoDS_Shape& S)
141 {
142   std::map< TCollection_AsciiString , TopoDS_Shape >::iterator i2s = myShapesMap.find( IOR );
143   if ( i2s != myShapesMap.end() ) {
144     S = i2s->second;
145     return Standard_True;
146   }
147   return Standard_False;
148 }
149
150 //=======================================================================
151 // function : Find()
152 // purpose  :
153 //=======================================================================
154 Standard_Boolean GEOM_Client::Find (const TopoDS_Shape& S, TCollection_AsciiString& IOR)
155 {
156   std::map< TCollection_AsciiString, TopoDS_Shape >::const_iterator it;
157   for (it = myShapesMap.begin(); it != myShapesMap.end(); ++it) {
158     if ((*it).second == S) {
159       IOR = (*it).first;
160       return Standard_True;
161     }
162   }
163   return Standard_False;
164 }
165
166 //=======================================================================
167 // function : Bind()
168 // purpose  :
169 //=======================================================================
170 void GEOM_Client::Bind( const TCollection_AsciiString& IOR, const TopoDS_Shape& S, int Tick )
171 {
172   myShapesMap[IOR] = S;
173   myTicksMap[IOR] = Tick;
174 }
175
176 //=======================================================================
177 // function : RemoveShapeFromBuffer()
178 // purpose  : Remove shape from Client Buffer
179 //=======================================================================
180 void GEOM_Client::RemoveShapeFromBuffer( const TCollection_AsciiString& IOR)
181 {
182   if ( myShapesMap.erase( IOR ))
183     _mySubShapes.erase( IOR );
184 }
185
186 //=======================================================================
187 // function : ClearClientBuffer()
188 // purpose  : purge buffer
189 //=======================================================================
190 void GEOM_Client::ClearClientBuffer()
191 {
192   _mySubShapes.clear();
193   myShapesMap.clear();
194 }
195
196 //=======================================================================
197 // function : GetShape()
198 // purpose  :
199 //=======================================================================
200 TopoDS_Shape GEOM_Client::GetShape( GEOM::GEOM_Gen_ptr geom, GEOM::GEOM_Object_ptr aShape )
201 {
202   CORBA::String_var     anIOR = geom->GetStringFromIOR(aShape);
203   TCollection_AsciiString IOR = anIOR.in();
204
205   // Special treatment for groups: group value (shape) is computed on
206   // first demand, and its tick is set to main shape's tick after that;
207   // tick of modified group is decremented.
208   // There is a not fixed problem: if anyone modifies a group and updates
209   // it before call to this method, the group will not be changed in the buffer
210   bool isModifiedSubShape = false;
211   int aShapeTick = aShape->GetTick();
212   if ( !aShape->IsMainShape() ) {
213     int anOldTick = aShapeTick;
214     aShape->GetShapeType(); // compute subshape and update its tick, if not yet
215     aShapeTick = aShape->GetTick();
216     isModifiedSubShape = (anOldTick != aShapeTick);
217   }
218
219   std::map< TCollection_AsciiString , int >::iterator i2t = myTicksMap.find( IOR );
220   if ( i2t != myTicksMap.end() ) {
221     if (i2t->second != aShapeTick || isModifiedSubShape) {
222       // The shape was modified, clean the stored one
223       RemoveShapeFromBuffer(IOR);
224     }
225   }
226
227   TopoDS_Shape S;
228   if ( Find( IOR, S ))
229     return S;
230
231   /******* in case of a MAIN GEOM::SHAPE ********/
232   if ( aShape->IsMainShape() ) {
233     S = Load(geom, aShape);
234     Bind(IOR, S, aShapeTick);
235     return S;
236   }
237
238   /******* in case of SUB GEOM::SHAPE ***********/
239   // Load and Explore the Main Shape
240   GEOM::GEOM_Object_var mainGO = aShape->GetMainShape();
241   TopoDS_Shape      aMainShape = GetShape( geom, mainGO );
242   GEOM::ListOfLong_var    list = aShape->GetSubShapeIndices();
243
244   CORBA::String_var      aMainIOR = geom->GetStringFromIOR( mainGO );
245   TCollection_AsciiString mainIOR = aMainIOR.in();
246
247   //find subshapes only one time
248   auto pos2isnew = _mySubShapes.insert( std::make_pair( mainIOR, std::vector<TopoDS_Shape>() ));
249   std::vector<TopoDS_Shape> & subShapes = pos2isnew.first->second;
250   if ( pos2isnew.second )
251   {
252     TopTools_IndexedMapOfShape anIndices;
253     TopExp::MapShapes( aMainShape, anIndices );
254     subShapes.insert( subShapes.end(), anIndices.cbegin(), anIndices.cend() );
255   }
256
257   /* Case of only one subshape, excluding groups of one main shape */
258   if ( list->length() == 1 &&
259        !(aShape->GetType() == 37 && list[0] == 1) &&
260        list[0] > 0 ) {
261     S = subShapes[list[0]-1];
262   }
263   else {
264     BRep_Builder B;
265     TopoDS_Compound aCompound;
266     B.MakeCompound(aCompound);
267     CORBA::Long nbSub = subShapes.size();
268     for ( size_t i = 0; i < list->length(); i++ )
269       if ( 0 < list[i] && list[i] <= nbSub )
270         B.Add(aCompound, subShapes[list[i]-1] );
271
272     S = aCompound;
273   }
274
275   Bind(IOR, S, aShapeTick);
276   return S;
277 }