+
+ if ( !aShape.IsNull() && _isShapeToMesh ) {
+ if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change
+ _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
+ throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+ }
+ // clear current data
+ if ( !_myMeshDS->ShapeToMesh().IsNull() )
+ {
+ // removal of a shape to mesh, delete objects referring to sub-shapes:
+ // - sub-meshes
+ map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
+ for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
+ delete i_sm->second;
+ _mapSubMesh.clear();
+ // - groups on geometry
+ map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
+ while ( i_gr != _mapGroup.end() ) {
+ if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
+ _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
+ delete i_gr->second;
+ _mapGroup.erase( i_gr++ );
+ }
+ else
+ i_gr++;
+ }
+ _mapAncestors.Clear();
+
+ // clear SMESHDS
+ TopoDS_Shape aNullShape;
+ _myMeshDS->ShapeToMesh( aNullShape );
+
+ _shapeDiagonal = 0.0;
+ }
+
+ // set a new geometry
+ if ( !aShape.IsNull() )
+ {
+ _myMeshDS->ShapeToMesh(aShape);
+ _isShapeToMesh = true;
+ _nbSubShapes = _myMeshDS->MaxShapeIndex();
+
+ // fill map of ancestors
+ fillAncestorsMap(aShape);
+ }
+ else
+ {
+ _isShapeToMesh = false;
+ _shapeDiagonal = 0.0;
+ _myMeshDS->ShapeToMesh( PseudoShape() );
+ }
+ _isModified = false;
+}
+
+//=======================================================================
+/*!
+ * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+ */
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
+{
+ return _myMeshDS->ShapeToMesh();
+}
+
+//=======================================================================
+/*!
+ * \brief Return a solid which is returned by GetShapeToMesh() if
+ * a real geometry to be meshed was not set
+ */
+//=======================================================================
+
+const TopoDS_Solid& SMESH_Mesh::PseudoShape()
+{
+ static TopoDS_Solid aSolid;
+ if ( aSolid.IsNull() )
+ {
+ aSolid = BRepPrimAPI_MakeBox(1,1,1);
+ }
+ return aSolid;
+}
+
+//=======================================================================
+/*!
+ * \brief Return diagonal size of bounding box of a shape
+ */
+//=======================================================================
+
+double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
+{
+ if ( !aShape.IsNull() ) {
+ Bnd_Box Box;
+ BRepBndLib::Add(aShape, Box);
+ return sqrt( Box.SquareExtent() );
+ }
+ return 0;
+}
+
+//=======================================================================
+/*!
+ * \brief Return diagonal size of bounding box of shape to mesh
+ */
+//=======================================================================
+
+double SMESH_Mesh::GetShapeDiagonalSize() const
+{
+ if ( _shapeDiagonal == 0. && _isShapeToMesh )
+ const_cast<SMESH_Mesh*>(this)->_shapeDiagonal = GetShapeDiagonalSize( GetShapeToMesh() );
+
+ return _shapeDiagonal;
+}
+
+//================================================================================
+/*!
+ * \brief Load mesh from study file
+ */
+//================================================================================
+
+void SMESH_Mesh::Load()
+{
+ if (_callUp)
+ _callUp->Load();
+}
+
+//=======================================================================
+/*!
+ * \brief Remove all nodes and elements
+ */
+//=======================================================================
+
+void SMESH_Mesh::Clear()
+{
+ if ( HasShapeToMesh() ) // remove all nodes and elements
+ {
+ // clear mesh data
+ _myMeshDS->ClearMesh();
+
+ // update compute state of submeshes
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
+ {
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+ }
+ }
+ else // remove only nodes/elements computed by algorithms
+ {
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
+ {
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+ /*complexShapeFirst=*/true);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ }
+ }
+ }
+ _isModified = false;
+}
+
+//=======================================================================
+/*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+//=======================================================================
+
+void SMESH_Mesh::ClearSubMesh(const int theShapeId)
+{
+ // clear sub-meshes; get ready to re-compute as a side-effect
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
+ {
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+ /*complexShapeFirst=*/false);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
+ if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
+ // all other shapes depends on vertices so they are already cleaned
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ // to recompute even if failed
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ }