Salome HOME
Update of CheckDone
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GEOMGenUtils.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_GEOMGenUtils.cxx
25 // Author : Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_GEOMGenUtils.h"
29 #include "SMESHGUI_Utils.h"
30 #include "SMESHGUI.h"
31
32 // SALOME GEOM includes
33 #include <GeometryGUI.h>
34 #include <GEOM_wrap.hxx>
35
36 // SALOME KERNEL includes
37 #include <SALOMEDS_SObject.hxx>
38
39 // IDL includes
40 #include <SALOMEconfig.h>
41 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
42
43 #include <QString>
44
45 #include <TopExp.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <TopoDS_Iterator.hxx>
49
50 namespace SMESH
51 {
52   GEOM::GEOM_Gen_var GetGEOMGen( GEOM::GEOM_Object_ptr go )
53   {
54     GEOM::GEOM_Gen_ptr gen = GEOM::GEOM_Gen::_nil();
55     if ( !CORBA::is_nil( go ))
56       gen = go->GetGen();
57     return gen;
58   }
59
60   GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh(_PTR(SObject) theMeshOrSubmesh,
61                                                 bool*         isMesh)
62   {
63     SALOMEDS_SObject* aMeshOrSubmesh = _CAST(SObject,theMeshOrSubmesh);
64     if(aMeshOrSubmesh) {
65       CORBA::Object_var Obj = aMeshOrSubmesh->GetObject();
66       if ( !CORBA::is_nil( Obj ) ) {
67         SMESH::SMESH_Mesh_var aMesh =
68           SObjectToInterface<SMESH::SMESH_Mesh>( theMeshOrSubmesh );
69         if ( !aMesh->_is_nil() )
70         {
71           if ( isMesh ) *isMesh = true;
72           return aMesh->GetShapeToMesh();
73         }
74         SMESH::SMESH_subMesh_var aSubmesh =
75           SObjectToInterface<SMESH::SMESH_subMesh>( theMeshOrSubmesh );
76         if ( !aSubmesh->_is_nil() )
77         {
78           if ( isMesh ) *isMesh = false;
79           return aSubmesh->GetSubShape();
80         }
81       }
82     }
83     return GEOM::GEOM_Object::_nil();
84   }
85
86   GEOM::GEOM_Object_var GetGeom (_PTR(SObject) theSO)
87   {
88     GEOM::GEOM_Object_var aMeshShape;
89     if (!theSO)
90       return aMeshShape;
91
92     CORBA::Object_var obj = _CAST( SObject,theSO )->GetObject();
93     aMeshShape = GEOM::GEOM_Object::_narrow( obj );
94     if ( !aMeshShape->_is_nil() )
95       return aMeshShape;
96
97     _PTR(ChildIterator) anIter (SMESH::getStudy()->NewChildIterator(theSO));
98     for ( ; anIter->More(); anIter->Next()) {
99       _PTR(SObject) aSObject = anIter->Value();
100       _PTR(SObject) aRefSOClient;
101
102       if (aSObject->ReferencedObject(aRefSOClient)) {
103         SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
104         aMeshShape = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
105       } else {
106         SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
107         aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
108       }
109       if ( !aMeshShape->_is_nil() )
110         return aMeshShape;
111     }
112     return aMeshShape;
113   }
114
115   GEOM::GEOM_Object_var GetGeom( Handle(SALOME_InteractiveObject) io )
116   {
117     GEOM::GEOM_Object_var go;
118     if ( !io.IsNull() && io->hasEntry() )
119     {
120       _PTR(SObject) so = SMESH::getStudy()->FindObjectID( io->getEntry() );
121       go = GetGeom( so );
122     }
123     return go._retn();
124   }
125
126   SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO )
127   {
128     if (!smeshSO)
129       return 0;
130
131     _PTR(ChildIterator) anIter (SMESH::getStudy()->NewChildIterator( smeshSO ));
132     for ( ; anIter->More(); anIter->Next()) {
133       _PTR(SObject) aSObject = anIter->Value();
134       _PTR(SObject) aRefSOClient;
135       GEOM::GEOM_Object_var aMeshShape;
136
137       if (aSObject->ReferencedObject(aRefSOClient)) {
138         SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
139         aMeshShape = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
140         aSObject = aRefSOClient;
141       }
142       else {
143         SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
144         aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
145       }
146
147       if (!aMeshShape->_is_nil())
148       {
149         std::string name = aSObject->GetName();
150         return CORBA::string_dup( name.c_str() );
151       }
152     }
153     return 0;
154   }
155
156   GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
157                                      long                  theID)
158   {
159     if ( CORBA::is_nil( theMainShape ))
160       return GEOM::GEOM_Object::_nil();
161
162     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen( theMainShape );
163     if (geomGen->_is_nil())
164       return GEOM::GEOM_Object::_nil();
165
166     GEOM::GEOM_IShapesOperations_wrap aShapesOp = geomGen->GetIShapesOperations();
167     if (aShapesOp->_is_nil())
168       return GEOM::GEOM_Object::_nil();
169
170     GEOM::GEOM_Object_wrap subShape = aShapesOp->GetSubShape( theMainShape, theID );
171     return subShape._retn();
172   }
173
174   //================================================================================
175   /*!
176    * \brief Return entries of sub-mesh geometry and mesh geometry by an IO of assigned
177    *        hypothesis
178    *  \param [in] hypIO - IO of hyp which is a reference SO to a hyp SO
179    *  \param [out] subGeom - found entry of a sub-mesh if any
180    *  \param [out] meshGeom - found entry of a mesh
181    *  \return bool - \c true if any geometry has been found
182    */
183   //================================================================================
184
185   bool GetGeomEntries( Handle(SALOME_InteractiveObject)& hypIO,
186                        QString&                          subGeom,
187                        QString&                          meshGeom )
188   {
189     subGeom.clear();
190     meshGeom.clear();
191     if ( hypIO.IsNull() ) return false;
192
193     _PTR(SObject) hypSO = SMESH::getStudy()->FindObjectID( hypIO->getEntry() );
194     if ( !hypSO ) return false;
195
196     // Depth() is a number of fathers
197     if ( hypSO->Depth() == 4 ) // hypSO is not a reference to a hyp but a hyp it-self
198     {
199       SMESH::SMESH_Hypothesis_var hyp =
200         SMESH::SObjectToInterface< SMESH::SMESH_Hypothesis >( hypSO );
201       SMESH::SMESH_Mesh_var mesh;
202       GEOM::GEOM_Object_var geom;
203       SMESH::SMESH_Gen_var  gen = SMESHGUI::GetSMESHGUI()->GetSMESHGen();
204       if ( !gen || !gen->GetSoleSubMeshUsingHyp( hyp, mesh.out(), geom.out() ))
205         return false;
206
207       subGeom = toQStr( geom->GetStudyEntry() );
208
209       geom  = mesh->GetShapeToMesh();
210       if ( geom->_is_nil() )
211         return false;
212       meshGeom = toQStr( geom->GetStudyEntry() );
213     }
214     else
215     {
216       _PTR(SObject) appliedSO = hypSO->GetFather(); // "Applied hypotheses" folder
217       if ( !appliedSO ) return false;
218
219       _PTR(SObject) subOrMeshSO = appliedSO->GetFather(); // mesh or sub-mesh SO
220       if ( !subOrMeshSO ) return false;
221
222       bool isMesh;
223       GEOM::GEOM_Object_var geom = GetShapeOnMeshOrSubMesh( subOrMeshSO, &isMesh );
224       if ( geom->_is_nil() )
225         return false;
226
227       if ( isMesh )
228       {
229         meshGeom = toQStr( geom->GetStudyEntry() );
230         return !meshGeom.isEmpty();
231       }
232
233       subGeom = toQStr( geom->GetStudyEntry() );
234
235       _PTR(SObject) subFolderSO = subOrMeshSO->GetFather(); // "SubMeshes on ..." folder
236       if ( !subFolderSO ) return false;
237
238       _PTR(SObject) meshSO = subFolderSO->GetFather(); // mesh SO
239       if ( !meshSO ) return false;
240
241       geom = GetShapeOnMeshOrSubMesh( meshSO );
242       if ( geom->_is_nil() )
243         return false;
244
245       meshGeom = toQStr( geom->GetStudyEntry() );
246     }
247
248     return !meshGeom.isEmpty() && !subGeom.isEmpty();
249   }
250
251
252   //================================================================================
253   /*!
254    * \brief Return type of shape contained in a group
255    */
256   //================================================================================
257
258   TopAbs_ShapeEnum _getGroupType(const TopoDS_Shape& group)
259   {
260     if ( group.ShapeType() != TopAbs_COMPOUND )
261       return group.ShapeType();
262
263     // iterate on a compound
264     TopoDS_Iterator it( group );
265     if ( it.More() )
266       return _getGroupType( it.Value() );
267
268     return TopAbs_SHAPE;
269   }
270
271
272   //================================================================================
273   /*!
274    * \brief Check if a subGeom contains sub-shapes of a mainGeom
275    */
276   //================================================================================
277
278   bool ContainsSubShape( GEOM::GEOM_Object_ptr mainGeom,
279                          GEOM::GEOM_Object_ptr subGeom, bool allowMainShape )
280   {
281     if ( CORBA::is_nil( mainGeom ) ||
282          CORBA::is_nil( subGeom ))
283       return false;
284
285     if (allowMainShape && mainGeom->IsSame(subGeom))
286       return true;
287
288     GEOM::GEOM_Gen_var geomGen = mainGeom->GetGen();
289     if ( geomGen->_is_nil() ) return false;
290
291     GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations();
292     if ( op->_is_nil() ) return false;
293
294     GEOM::GEOM_Object_var mainObj = op->GetMainShape( subGeom ); /* _var not _wrap as
295                                                                     mainObj already exists! */
296     while ( !mainObj->_is_nil() )
297     {
298       CORBA::String_var entry1 = mainObj->GetEntry();
299       CORBA::String_var entry2 = mainGeom->GetEntry();
300       if ( std::string( entry1.in() ) == entry2.in() )
301         return true;
302       mainObj = op->GetMainShape( mainObj );
303     }
304     if ( subGeom->GetShapeType() == GEOM::COMPOUND )
305     {
306       // is subGeom a compound of sub-shapes?
307       GEOM::GEOM_IShapesOperations_wrap sop = geomGen->GetIShapesOperations();
308       if ( sop->_is_nil() ) return false;
309       GEOM::ListOfLong_var ids = sop->GetAllSubShapesIDs( subGeom,
310                                                           GEOM::SHAPE,/*sorted=*/false);
311       if ( ids->length() > 0 )
312       {
313         GEOM_Client geomClient;
314         TopoDS_Shape  subShape = geomClient.GetShape( geomGen, subGeom );
315         TopoDS_Shape mainShape = geomClient.GetShape( geomGen, mainGeom );
316         if ( subShape.IsNull() || mainShape.IsNull() )
317           return false;
318
319         TopAbs_ShapeEnum subType = _getGroupType( subShape );
320         TopTools_IndexedMapOfShape subMap;
321         TopExp::MapShapes( subShape, subType, subMap );
322         for ( TopExp_Explorer exp( mainShape, subType ); exp.More(); exp.Next() )
323           if ( subMap.Contains( exp.Current() ))
324             return true;
325
326       }
327     }
328     return false;
329   }
330
331 } // end of namespace SMESH