1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOM_Client.cxx
23 // Author : Yves FRICAUD/Lucien PIGNOLONI
26 #include <Standard_Stream.hxx>
30 #include "GEOM_Client.hxx"
31 #include <SALOMEconfig.h>
32 #include "Basics_Utils.hxx"
33 #include "utilities.h"
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>
43 #include <TopTools_IndexedMapOfShape.hxx>
51 #include CORBA_SERVER_HEADER(SALOMEDS)
52 #include CORBA_SERVER_HEADER(GEOM_Gen)
54 #define HST_CLIENT_LEN 256
56 //=======================================================================
59 //=======================================================================
60 TopoDS_Shape GEOM_Client::Load( GEOM::GEOM_Gen_ptr geom, GEOM::GEOM_Object_ptr aShape )
62 std::string hst_client = Kernel_Utils::GetHostname();
64 Engines::Container_var ctn_server = geom->GetContainerRef();
65 long pid_server = ctn_server->getPID();
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());
72 /* get sequence of bytes of resulting brep shape from GEOM server */
74 SALOMEDS::TMPFile_var SeqFile = aShape->GetShapeStream();
75 /*int sizebuf = */SeqFile->length();
77 buf = (char*) &SeqFile[0];
78 std::istringstream streamBrep(buf);
79 BRep_Builder aBuilder;
80 BRepTools::Read(S, streamBrep, aBuilder);
85 //=======================================================================
86 // function : Create()
87 // purpose : Create in client not in a container
88 //=======================================================================
89 GEOM_Client::GEOM_Client()
99 //=======================================================================
100 // function : Create()
101 // purpose : Copy constructor
102 //=======================================================================
103 GEOM_Client::GEOM_Client(const GEOM_Client& client)
105 _mySubShapes = client._mySubShapes;
106 myShapesMap = client.myShapesMap;
107 pid_client = client.pid_client;
110 //=======================================================================
111 // function : Create()
113 //=======================================================================
114 GEOM_Client::GEOM_Client(Engines::Container_ptr client)
116 pid_client = client->getPID();
119 //=======================================================================
120 // function : get_client()
121 // purpose : Static method to have the only one instance of GEOM_Client
122 //=======================================================================
124 GEOM_Client& GEOM_Client::get_client()
126 static GEOM_Client a;
130 GEOM_Client GEOM_Client::get_client()
132 return GEOM_Client();
136 //=======================================================================
139 //=======================================================================
140 Standard_Boolean GEOM_Client::Find (const TCollection_AsciiString& IOR, TopoDS_Shape& S)
142 std::map< TCollection_AsciiString , TopoDS_Shape >::iterator i2s = myShapesMap.find( IOR );
143 if ( i2s != myShapesMap.end() ) {
145 return Standard_True;
147 return Standard_False;
150 //=======================================================================
153 //=======================================================================
154 Standard_Boolean GEOM_Client::Find (const TopoDS_Shape& S, TCollection_AsciiString& IOR)
156 std::map< TCollection_AsciiString, TopoDS_Shape >::const_iterator it;
157 for (it = myShapesMap.begin(); it != myShapesMap.end(); ++it) {
158 if ((*it).second == S) {
160 return Standard_True;
163 return Standard_False;
166 //=======================================================================
169 //=======================================================================
170 void GEOM_Client::Bind( const TCollection_AsciiString& IOR, const TopoDS_Shape& S, int Tick )
172 myShapesMap[IOR] = S;
173 myTicksMap[IOR] = Tick;
176 //=======================================================================
177 // function : RemoveShapeFromBuffer()
178 // purpose : Remove shape from Client Buffer
179 //=======================================================================
180 void GEOM_Client::RemoveShapeFromBuffer( const TCollection_AsciiString& IOR)
182 if ( myShapesMap.erase( IOR ))
183 _mySubShapes.erase( IOR );
186 //=======================================================================
187 // function : ClearClientBuffer()
188 // purpose : purge buffer
189 //=======================================================================
190 void GEOM_Client::ClearClientBuffer()
192 _mySubShapes.clear();
196 //=======================================================================
197 // function : GetShape()
199 //=======================================================================
200 TopoDS_Shape GEOM_Client::GetShape( GEOM::GEOM_Gen_ptr geom, GEOM::GEOM_Object_ptr aShape )
202 CORBA::String_var anIOR = geom->GetStringFromIOR(aShape);
203 TCollection_AsciiString IOR = anIOR.in();
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);
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);
231 /******* in case of a MAIN GEOM::SHAPE ********/
232 if ( aShape->IsMainShape() ) {
233 S = Load(geom, aShape);
234 Bind(IOR, S, aShapeTick);
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();
244 CORBA::String_var aMainIOR = geom->GetStringFromIOR( mainGO );
245 TCollection_AsciiString mainIOR = aMainIOR.in();
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 )
252 TopTools_IndexedMapOfShape anIndices;
253 TopExp::MapShapes( aMainShape, anIndices );
254 subShapes.insert( subShapes.end(), anIndices.cbegin(), anIndices.cend() );
257 /* Case of only one subshape, excluding groups of one main shape */
258 if ( list->length() == 1 &&
259 !(aShape->GetType() == 37 && list[0] == 1) &&
261 S = subShapes[list[0]-1];
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] );
275 Bind(IOR, S, aShapeTick);