SMESH_Comment.hxx \
SMESH_ComputeError.hxx \
SMESH_File.hxx \
- SMESH_SMESH.hxx
+ SMESH_SMESH.hxx \
+ SMESH_ProxyMesh.hxx
# Libraries targets
SMESH_MesherHelper.cxx \
SMESH_Octree.cxx \
SMESH_OctreeNode.cxx \
- SMESH_File.cxx
+ SMESH_File.cxx \
+ SMESH_ProxyMesh.cxx
# additionnal information to compile and link file
libSMESHimpl_la_CPPFLAGS = \
--- /dev/null
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SMESH_ProxyMesh.cxx
+// Created : Thu Dec 2 12:32:53 2010
+// Author : Edward AGAPOV (eap)
+
+#include "SMESH_ProxyMesh.hxx"
+
+#include "SMDS_IteratorOnIterators.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+//================================================================================
+/*!
+ * \brief Constructor; mesh must be set by a descendant class
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0)
+{
+}
+//================================================================================
+/*!
+ * \brief Make a proxy mesh from components. Components become empty
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SMESH_ProxyMesh(vector<SMESH_ProxyMesh::Ptr>& components):
+ _mesh(0)
+{
+ if ( components.empty() ) return;
+
+ for ( unsigned i = 0; i < components.size(); ++i )
+ {
+ SMESH_ProxyMesh* m = components[i].get();
+ if ( !m ) continue;
+
+ takeTmpElemsInMesh( m );
+
+ if ( !_mesh ) _mesh = m->_mesh;
+ if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes;
+
+ if ( _subMeshes.size() < m->_subMeshes.size() )
+ _subMeshes.resize( m->_subMeshes.size(), 0 );
+ for ( unsigned j = 0; j < m->_subMeshes.size(); ++j )
+ {
+ if ( !m->_subMeshes[j] ) continue;
+ if ( _subMeshes[j] )
+ {
+ // unite 2 sub-meshes
+ set< const SMDS_MeshElement * > elems( _subMeshes[j]->_elements.begin(),
+ _subMeshes[j]->_elements.end());
+ elems.insert( m->_subMeshes[j]->_elements.begin(),
+ m->_subMeshes[j]->_elements.end());
+ _subMeshes[j]->_elements.assign( elems.begin(), elems.end() );
+ m->_subMeshes[j]->_elements.clear();
+
+ if ( !_subMeshes[j]->_n2n )
+ _subMeshes[j]->_n2n = m->_subMeshes[j]->_n2n, m->_subMeshes[j]->_n2n = 0;
+
+ else if ( _subMeshes[j]->_n2n && m->_subMeshes[j]->_n2n )
+ _subMeshes[j]->_n2n->insert( m->_subMeshes[j]->_n2n->begin(),
+ m->_subMeshes[j]->_n2n->end());
+ }
+ else
+ {
+ _subMeshes[j] = m->_subMeshes[j];
+ m->_subMeshes[j] = 0;
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Destructor deletes proxy submeshes and tmp elemens
+ */
+//================================================================================
+
+SMESH_ProxyMesh::~SMESH_ProxyMesh()
+{
+ for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+ delete _subMeshes[i];
+ _subMeshes.clear();
+
+ set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.begin();
+ for ( ; i != _elemsInMesh.end(); ++i )
+ GetMeshDS()->RemoveFreeElement( *i, 0 );
+ _elemsInMesh.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Returns index of a shape
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const
+{
+ return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape));
+}
+
+//================================================================================
+/*!
+ * \brief Returns the submesh of a shape; it can be a proxy sub-mesh
+ */
+//================================================================================
+
+const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const
+{
+ const SMESHDS_SubMesh* sm = 0;
+
+ int i = shapeIndex(shape);
+ if ( i < _subMeshes.size() )
+ sm = _subMeshes[i];
+ if ( !sm )
+ sm = GetMeshDS()->MeshElements( i );
+
+ return sm;
+}
+
+//================================================================================
+/*!
+ * \brief Returns the proxy sub-mesh of a shape; it can be NULL
+ */
+//================================================================================
+
+const SMESH_ProxyMesh::SubMesh*
+SMESH_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const
+{
+ int i = shapeIndex(shape);
+ return i < _subMeshes.size() ? _subMeshes[i] : 0;
+}
+
+//================================================================================
+/*!
+ * \brief Returns the proxy node of a node; the input node is returned if no proxy exists
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_ProxyMesh::GetProxyNode( const SMDS_MeshNode* node ) const
+{
+ const SMDS_MeshNode* proxy = node;
+ if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+ {
+ if ( const SubMesh* proxySM = findProxySubMesh( node->GetPosition()->GetShapeId() ))
+ proxy = proxySM->GetProxyNode( node );
+ }
+ else
+ {
+ TopoDS_Shape shape = SMESH_MesherHelper::GetSubShapeByNode( node, GetMeshDS());
+ TopTools_ListIteratorOfListOfShape ancIt;
+ if ( !shape.IsNull() ) ancIt.Initialize( _mesh->GetAncestors( shape ));
+ for ( ; ancIt.More() && proxy == node; ancIt.Next() )
+ if ( const SubMesh* proxySM = findProxySubMesh( shapeIndex(ancIt.Value())))
+ proxy = proxySM->GetProxyNode( node );
+ }
+ return proxy;
+}
+
+namespace
+{
+ //================================================================================
+ /*!
+ * \brief Iterator filtering elements by type
+ */
+ //================================================================================
+
+ class TFilteringIterator : public SMDS_ElemIterator
+ {
+ SMDS_ElemIteratorPtr _iter;
+ const SMDS_MeshElement * _curElem;
+ vector< SMDSAbs_EntityType> _okTypes;
+ public:
+ TFilteringIterator( const vector< SMDSAbs_EntityType>& okTypes,
+ const SMDS_ElemIteratorPtr& elemIterator)
+ :_iter(elemIterator), _curElem(0), _okTypes(okTypes)
+ {
+ next();
+ }
+ virtual bool more()
+ {
+ return _curElem;
+ }
+ virtual const SMDS_MeshElement* next()
+ {
+ const SMDS_MeshElement* res = _curElem;
+ _curElem = 0;
+ while ( _iter->more() && !_curElem )
+ {
+ _curElem = _iter->next();
+ if ( find( _okTypes.begin(), _okTypes.end(), _curElem->GetEntityType()) == _okTypes.end())
+ _curElem = 0;
+ }
+ return res;
+ }
+ };
+}
+
+//================================================================================
+/*!
+ * \brief Returns iterator on all faces on the shape taking into account substitutions
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const
+{
+ if ( !_mesh->HasShapeToMesh() )
+ return SMDS_ElemIteratorPtr();
+
+ _subContainer.RemoveAllSubmeshes();
+
+ TopTools_IndexedMapOfShape FF;
+ TopExp::MapShapes( shape, TopAbs_FACE, FF );
+ for ( int i = 1; i <= FF.Extent(); ++i )
+ if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
+ _subContainer.AddSubMesh( sm );
+
+ return _subContainer.SMESHDS_SubMesh::GetElements();
+}
+
+//================================================================================
+/*!
+ * \brief Returns iterator on all faces of the mesh taking into account substitutions
+ * To be used in case of mesh without shape
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const
+{
+ if ( _mesh->HasShapeToMesh() )
+ return SMDS_ElemIteratorPtr();
+
+ _subContainer.RemoveAllSubmeshes();
+ for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+ if ( _subMeshes[i] )
+ _subContainer.AddSubMesh( _subMeshes[i] );
+
+ if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted
+ return GetMeshDS()->elementsIterator(SMDSAbs_Face);
+
+ // if _allowedTypes is empty, only elements from _subMeshes are returned,...
+ SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements();
+ if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() )
+ return proxyIter;
+
+ // ... else elements filtered using allowedTypes are additionally returned
+ SMDS_ElemIteratorPtr facesIter = GetMeshDS()->elementsIterator(SMDSAbs_Face);
+ SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter ));
+ vector< SMDS_ElemIteratorPtr > iters(2);
+ iters[0] = proxyIter;
+ iters[1] = filterIter;
+
+ typedef vector< SMDS_ElemIteratorPtr > TElemIterVector;
+ typedef SMDS_IteratorOnIterators<const SMDS_MeshElement *, TElemIterVector> TItersIter;
+ return SMDS_ElemIteratorPtr( new TItersIter( iters ));
+}
+
+//================================================================================
+/*!
+ * \brief Return total nb of faces taking into account substitutions
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::NbFaces() const
+{
+ int nb = 0;
+ if ( _mesh->HasShapeToMesh() )
+ {
+ TopTools_IndexedMapOfShape FF;
+ TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_FACE, FF );
+ for ( int i = 1; i <= FF.Extent(); ++i )
+ if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
+ nb += sm->NbElements();
+ }
+ else
+ {
+ if ( _subMeshes.empty() )
+ return GetMeshDS()->NbFaces();
+
+ for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+ if ( _subMeshes[i] )
+ nb += _subMeshes[i]->NbElements();
+
+ // if _allowedTypes is empty, only elements from _subMeshes are returned,
+ // else elements filtered using allowedTypes are additionally returned
+ if ( !_allowedTypes.empty() )
+ {
+ for ( int t = SMDSEntity_Triangle; t <= SMDSEntity_Quad_Quadrangle; ++t )
+ {
+ bool allowed =
+ ( find( _allowedTypes.begin(), _allowedTypes.end(), t ) != _allowedTypes.end() );
+ if ( allowed )
+ nb += GetMeshDS()->GetMeshInfo().NbEntities( SMDSAbs_EntityType( t ));
+ }
+ }
+ }
+ return nb;
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh; it is created if not yet exists
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(int index)
+{
+ if ( int(_subMeshes.size()) <= index )
+ _subMeshes.resize( index+1, 0 );
+ if ( !_subMeshes[index] )
+ _subMeshes[index] = new SubMesh;
+ return _subMeshes[index];
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh; it is created if not yet exists
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(const TopoDS_Shape& shape)
+{
+ return getProxySubMesh( shapeIndex( shape ));
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::findProxySubMesh(int shapeIndex) const
+{
+ return shapeIndex < int(_subMeshes.size()) ? _subMeshes[shapeIndex] : 0;
+}
+
+//================================================================================
+/*!
+ * \brief Returns mesh DS
+ */
+//================================================================================
+
+SMESHDS_Mesh* SMESH_ProxyMesh::GetMeshDS() const
+{
+ return (SMESHDS_Mesh*)( _mesh ? _mesh->GetMeshDS() : 0 );
+}
+
+//================================================================================
+/*!
+ * \brief Move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::takeProxySubMesh( const TopoDS_Shape& shape,
+ SMESH_ProxyMesh* proxyMesh )
+{
+ if ( proxyMesh && proxyMesh->_mesh == _mesh )
+ {
+ int iS = shapeIndex( shape );
+ if ( SubMesh* sm = proxyMesh->findProxySubMesh( iS ))
+ {
+ if ( iS >= int(_subMeshes.size()) )
+ _subMeshes.resize( iS + 1, 0 );
+ _subMeshes[iS] = sm;
+ proxyMesh->_subMeshes[iS] = 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Move tmp elements residing the _mesh from other proxy mesh to this
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh )
+{
+ if ( proxyMesh )
+ {
+ _elemsInMesh.insert( proxyMesh->_elemsInMesh.begin(),
+ proxyMesh->_elemsInMesh.end());
+ proxyMesh->_elemsInMesh.clear();
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Removes tmp faces from the _mesh
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::removeTmpElement( const SMDS_MeshElement* face )
+{
+ if ( face && face->GetID() > 0 )
+ {
+ set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.find( face );
+ if ( i != _elemsInMesh.end() )
+ {
+ GetMeshDS()->RemoveFreeElement( face, 0 );
+ _elemsInMesh.erase( i );
+ }
+ }
+ else
+ {
+ delete face;
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Stores tmp element residing the _mesh
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::storeTmpElement( const SMDS_MeshElement* face )
+{
+ _elemsInMesh.insert( face );
+}
+
+//================================================================================
+/*!
+ * \brief Set node-node correspondence
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::setNode2Node(const SMDS_MeshNode* srcNode,
+ const SMDS_MeshNode* proxyNode,
+ const SubMesh* subMesh)
+{
+ SubMesh* sm = const_cast<SubMesh*>( subMesh );
+ if ( !subMesh->_n2n )
+ sm->_n2n = new TN2NMap;
+ sm->_n2n->insert( make_pair( srcNode, proxyNode ));
+}
+
+//================================================================================
+/*!
+ * \brief Return true if the element is a temporary one
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const
+{
+ return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem );
+}
+
+//================================================================================
+/*!
+ * \brief Return a proxy node or an input node
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_ProxyMesh::SubMesh::GetProxyNode( const SMDS_MeshNode* n ) const
+{
+ TN2NMap::iterator n2n;
+ if ( _n2n && ( n2n = _n2n->find( n )) != _n2n->end())
+ return n2n->second;
+ return n;
+}
+
+//================================================================================
+/*!
+ * \brief Deletes temporary elements
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::SubMesh::Clear()
+{
+ for ( unsigned i = 0; i < _elements.size(); ++i )
+ if ( _elements[i]->GetID() < 0 )
+ delete _elements[i];
+ _elements.clear();
+ if ( _n2n )
+ delete _n2n, _n2n = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return number of elements in a proxy submesh
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::SubMesh::NbElements() const
+{
+ return _elements.size();
+}
+
+//================================================================================
+/*!
+ * \brief Return elements of a proxy submesh
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const
+{
+ return SMDS_ElemIteratorPtr
+ ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() ));
+}
+
+//================================================================================
+/*!
+ * \brief Store an element
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::SubMesh::AddElement(const SMDS_MeshElement * e)
+{
+ _elements.push_back( e );
+}
+
+//================================================================================
+/*!
+ * \brief Check presence of element inside it-self
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::SubMesh::Contains(const SMDS_MeshElement * ME) const
+{
+ if ( ME->GetType() != SMDSAbs_Node )
+ return find( _elements.begin(), _elements.end(), ME ) != _elements.end();
+ return false;
+}
--- /dev/null
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File : SMESH_ProxyMesh.hxx
+// Created : Thu Dec 2 10:05:35 2010
+// Author : Edward AGAPOV (eap)
+
+#ifndef __SMESH_ProxyMesh_HXX__
+#define __SMESH_ProxyMesh_HXX__
+
+#include "SMESH_SMESH.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMESHDS_SubMesh.hxx"
+
+#include <TopoDS_Shape.hxx>
+
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+class SMDS_MeshNode;
+class SMESHDS_Mesh;
+class SMESH_Mesh;
+
+/*!
+ * \brief Container of mesh faces substituting other faces in the input mesh of 3D algorithm
+ */
+class SMESH_EXPORT SMESH_ProxyMesh
+{
+public:
+
+ typedef boost::shared_ptr<SMESH_ProxyMesh> Ptr;
+
+ typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare > TN2NMap;
+
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Proxy sub-mesh
+ */
+ class SubMesh : public SMESHDS_SubMesh
+ {
+ public:
+
+ const TN2NMap* GetNodeNodeMap() const { return _n2n; }
+ const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* n ) const;
+ virtual void AddElement(const SMDS_MeshElement * e);
+ virtual int NbElements() const;
+ virtual SMDS_ElemIteratorPtr GetElements() const;
+ virtual void Clear();
+ virtual bool Contains(const SMDS_MeshElement * ME) const;
+
+ template< class ITERATOR >
+ void ChangeElements( ITERATOR it, ITERATOR end )
+ {
+ // change SubMesh contents without deleting tmp faces
+ // for which the caller is responsible
+ _elements.clear();
+ while ( it != end ) _elements.push_back( *it++ );
+ }
+ SubMesh():_n2n(0) {}
+ ~SubMesh() { Clear(); }
+
+ private:
+ std::vector<const SMDS_MeshElement *> _elements;
+ TN2NMap* _n2n;
+ friend class SMESH_ProxyMesh;
+ };
+ //--------------------------------------------------------------------------------
+ // Public interface
+
+ SMESH_ProxyMesh();
+ SMESH_ProxyMesh(std::vector<SMESH_ProxyMesh::Ptr>& components);
+ SMESH_ProxyMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
+ virtual ~SMESH_ProxyMesh();
+
+ // Returns the submesh of a face; it can be a proxy sub-mesh
+ const SMESHDS_SubMesh* GetSubMesh(const TopoDS_Shape& face) const;
+
+ // Returns the proxy sub-mesh of a face; it can be NULL
+ const SubMesh* GetProxySubMesh(const TopoDS_Shape& face) const;
+
+ // Returns the proxy node of a node; the input node is returned if no proxy exists
+ const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* node ) const;
+
+ // Returns iterator on all faces of the mesh taking into account substitutions
+ // To be used in case of mesh without shape
+ SMDS_ElemIteratorPtr GetFaces() const;
+
+ // Returns iterator on all faces on the face taking into account substitutions
+ SMDS_ElemIteratorPtr GetFaces(const TopoDS_Shape& face) const;
+
+ // Return total nb of faces taking into account substitutions
+ int NbFaces() const;
+
+ bool IsTemporary(const SMDS_MeshElement* elem ) const;
+
+
+
+ const SMESH_Mesh* GetMesh() const { return _mesh; }
+
+ SMESHDS_Mesh* GetMeshDS() const;
+
+ //--------------------------------------------------------------------------------
+ // Interface for descendants
+ protected:
+
+ void setMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
+
+ int shapeIndex(const TopoDS_Shape& shape) const;
+
+ // returns a proxy sub-mesh; zero index is for the case of mesh w/o shape
+ SubMesh* findProxySubMesh(int shapeIndex=0) const;
+
+ // returns a proxy sub-mesh; it is created if not yet exists
+ SubMesh* getProxySubMesh(int shapeIndex);
+
+ // returns a proxy sub-mesh; it is created if not yet exists
+ SubMesh* getProxySubMesh(const TopoDS_Shape& shape=TopoDS_Shape());
+
+ // move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
+ bool takeProxySubMesh( const TopoDS_Shape& shape, SMESH_ProxyMesh* proxyMesh );
+
+ // move tmp elements residing the _mesh from other proxy mesh to this
+ void takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh );
+
+ // removes tmp faces from the _mesh
+ void removeTmpElement( const SMDS_MeshElement* face );
+
+ // stores tmp element residing the _mesh
+ void storeTmpElement( const SMDS_MeshElement* face );
+
+ // store node-node correspondence
+ void setNode2Node(const SMDS_MeshNode* srcNode,
+ const SMDS_MeshNode* proxyNode,
+ const SubMesh* subMesh);
+
+ // types of elements needed to implement NbFaces() and GetFaces();
+ // if _allowedTypes is empty, only elements from _subMeshes are returned,
+ // else elements of _mesh filtered using allowedTypes are additionally returned
+ std::vector< SMDSAbs_EntityType> _allowedTypes;
+
+ private:
+
+ const SMESH_Mesh* _mesh;
+
+ // proxy sub-meshes; index in vector == shapeIndex(shape)
+ std::vector< SubMesh* > _subMeshes;
+
+ // tmp elements residing the _mesh, to be deleted at destruction
+ std::set< const SMDS_MeshElement* > _elemsInMesh;
+
+ // Complex submesh used to iterate over elements in other sub-meshes
+ mutable SubMesh _subContainer;
+};
+
+#endif
StdMeshers_ImportSource.hxx \
StdMeshers_Import_1D.hxx \
StdMeshers_Import_1D2D.hxx \
- StdMeshers_ViscousLayers.hxx \
- StdMeshers_ProxyMesh.hxx
+ StdMeshers_ViscousLayers.hxx
# Libraries targets
StdMeshers_ImportSource.cxx \
StdMeshers_Import_1D.cxx \
StdMeshers_Import_1D2D.cxx \
- StdMeshers_ViscousLayers.cxx \
- StdMeshers_ProxyMesh.cxx
+ StdMeshers_ViscousLayers.cxx
# additionnal information to compil and link file
libStdMeshers_la_CPPFLAGS = \
+++ /dev/null
-// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-// File : StdMeshers_ProxyMesh.cxx
-// Created : Thu Dec 2 12:32:53 2010
-// Author : Edward AGAPOV (eap)
-
-#include "StdMeshers_ProxyMesh.hxx"
-
-#include "SMDS_IteratorOnIterators.hxx"
-#include "SMDS_SetIterator.hxx"
-#include "SMESH_MesherHelper.hxx"
-
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopExp.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-
-//================================================================================
-/*!
- * \brief Constructor; mesh must be set by a descendant class
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::StdMeshers_ProxyMesh():_mesh(0)
-{
-}
-//================================================================================
-/*!
- * \brief Make a proxy mesh from components. Components become empty
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::StdMeshers_ProxyMesh(vector<StdMeshers_ProxyMesh::Ptr>& components):
- _mesh(0)
-{
- if ( components.empty() ) return;
-
- for ( unsigned i = 0; i < components.size(); ++i )
- {
- StdMeshers_ProxyMesh* m = components[i].get();
- if ( !m ) continue;
-
- takeTmpElemsInMesh( m );
-
- if ( !_mesh ) _mesh = m->_mesh;
- if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes;
-
- if ( _subMeshes.size() < m->_subMeshes.size() )
- _subMeshes.resize( m->_subMeshes.size(), 0 );
- for ( unsigned j = 0; j < m->_subMeshes.size(); ++j )
- {
- if ( !m->_subMeshes[j] ) continue;
- if ( _subMeshes[j] )
- {
- // unite 2 sub-meshes
- set< const SMDS_MeshElement * > elems( _subMeshes[j]->_elements.begin(),
- _subMeshes[j]->_elements.end());
- elems.insert( m->_subMeshes[j]->_elements.begin(),
- m->_subMeshes[j]->_elements.end());
- _subMeshes[j]->_elements.assign( elems.begin(), elems.end() );
- m->_subMeshes[j]->_elements.clear();
-
- if ( !_subMeshes[j]->_n2n )
- _subMeshes[j]->_n2n = m->_subMeshes[j]->_n2n, m->_subMeshes[j]->_n2n = 0;
-
- else if ( _subMeshes[j]->_n2n && m->_subMeshes[j]->_n2n )
- _subMeshes[j]->_n2n->insert( m->_subMeshes[j]->_n2n->begin(),
- m->_subMeshes[j]->_n2n->end());
- }
- else
- {
- _subMeshes[j] = m->_subMeshes[j];
- m->_subMeshes[j] = 0;
- }
- }
- }
-}
-
-//================================================================================
-/*!
- * \brief Destructor deletes proxy submeshes and tmp elemens
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::~StdMeshers_ProxyMesh()
-{
- for ( unsigned i = 0; i < _subMeshes.size(); ++i )
- delete _subMeshes[i];
- _subMeshes.clear();
-
- set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.begin();
- for ( ; i != _elemsInMesh.end(); ++i )
- getMeshDS()->RemoveFreeElement( *i, 0 );
- _elemsInMesh.clear();
-}
-
-//================================================================================
-/*!
- * \brief Returns index of a shape
- */
-//================================================================================
-
-int StdMeshers_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const
-{
- return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : getMeshDS()->ShapeToIndex(shape));
-}
-
-//================================================================================
-/*!
- * \brief Returns the submesh of a shape; it can be a proxy sub-mesh
- */
-//================================================================================
-
-const SMESHDS_SubMesh* StdMeshers_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const
-{
- const SMESHDS_SubMesh* sm = 0;
-
- int i = shapeIndex(shape);
- if ( i < _subMeshes.size() )
- sm = _subMeshes[i];
- if ( !sm )
- sm = getMeshDS()->MeshElements( i );
-
- return sm;
-}
-
-//================================================================================
-/*!
- * \brief Returns the proxy sub-mesh of a shape; it can be NULL
- */
-//================================================================================
-
-const StdMeshers_ProxyMesh::SubMesh*
-StdMeshers_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const
-{
- int i = shapeIndex(shape);
- return i < _subMeshes.size() ? _subMeshes[i] : 0;
-}
-
-//================================================================================
-/*!
- * \brief Returns the proxy node of a node; the input node is returned if no proxy exists
- */
-//================================================================================
-
-const SMDS_MeshNode* StdMeshers_ProxyMesh::GetProxyNode( const SMDS_MeshNode* node ) const
-{
- const SMDS_MeshNode* proxy = node;
- if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
- {
- if ( const SubMesh* proxySM = findProxySubMesh( node->GetPosition()->GetShapeId() ))
- proxy = proxySM->GetProxyNode( node );
- }
- else
- {
- TopoDS_Shape shape = SMESH_MesherHelper::GetSubShapeByNode( node, getMeshDS());
- TopTools_ListIteratorOfListOfShape ancIt;
- if ( !shape.IsNull() ) ancIt.Initialize( _mesh->GetAncestors( shape ));
- for ( ; ancIt.More() && proxy == node; ancIt.Next() )
- if ( const SubMesh* proxySM = findProxySubMesh( shapeIndex(ancIt.Value())))
- proxy = proxySM->GetProxyNode( node );
- }
- return proxy;
-}
-
-namespace
-{
- //================================================================================
- /*!
- * \brief Iterator filtering elements by type
- */
- //================================================================================
-
- class TFilteringIterator : public SMDS_ElemIterator
- {
- SMDS_ElemIteratorPtr _iter;
- const SMDS_MeshElement * _curElem;
- vector< SMDSAbs_EntityType> _okTypes;
- public:
- TFilteringIterator( const vector< SMDSAbs_EntityType>& okTypes,
- const SMDS_ElemIteratorPtr& elemIterator)
- :_iter(elemIterator), _curElem(0), _okTypes(okTypes)
- {
- next();
- }
- virtual bool more()
- {
- return _curElem;
- }
- virtual const SMDS_MeshElement* next()
- {
- const SMDS_MeshElement* res = _curElem;
- _curElem = 0;
- while ( _iter->more() && !_curElem )
- {
- _curElem = _iter->next();
- if ( find( _okTypes.begin(), _okTypes.end(), _curElem->GetEntityType()) == _okTypes.end())
- _curElem = 0;
- }
- return res;
- }
- };
-}
-
-//================================================================================
-/*!
- * \brief Returns iterator on all faces on the shape taking into account substitutions
- */
-//================================================================================
-
-SMDS_ElemIteratorPtr StdMeshers_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const
-{
- if ( !_mesh->HasShapeToMesh() )
- return SMDS_ElemIteratorPtr();
-
- _subContainer.RemoveAllSubmeshes();
-
- TopTools_IndexedMapOfShape FF;
- TopExp::MapShapes( shape, TopAbs_FACE, FF );
- for ( int i = 1; i <= FF.Extent(); ++i )
- if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
- _subContainer.AddSubMesh( sm );
-
- return _subContainer.SMESHDS_SubMesh::GetElements();
-}
-
-//================================================================================
-/*!
- * \brief Returns iterator on all faces of the mesh taking into account substitutions
- * To be used in case of mesh without shape
- */
-//================================================================================
-
-SMDS_ElemIteratorPtr StdMeshers_ProxyMesh::GetFaces() const
-{
- if ( _mesh->HasShapeToMesh() )
- return SMDS_ElemIteratorPtr();
-
- _subContainer.RemoveAllSubmeshes();
- for ( unsigned i = 0; i < _subMeshes.size(); ++i )
- if ( _subMeshes[i] )
- _subContainer.AddSubMesh( _subMeshes[i] );
-
- if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted
- return getMeshDS()->elementsIterator(SMDSAbs_Face);
-
- // if _allowedTypes is empty, only elements from _subMeshes are returned,...
- SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements();
- if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() )
- return proxyIter;
-
- // ... else elements filtered using allowedTypes are additionally returned
- SMDS_ElemIteratorPtr facesIter = getMeshDS()->elementsIterator(SMDSAbs_Face);
- SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter ));
- vector< SMDS_ElemIteratorPtr > iters(2);
- iters[0] = proxyIter;
- iters[1] = filterIter;
-
- typedef vector< SMDS_ElemIteratorPtr > TElemIterVector;
- typedef SMDS_IteratorOnIterators<const SMDS_MeshElement *, TElemIterVector> TItersIter;
- return SMDS_ElemIteratorPtr( new TItersIter( iters ));
-}
-
-//================================================================================
-/*!
- * \brief Return total nb of faces taking into account substitutions
- */
-//================================================================================
-
-int StdMeshers_ProxyMesh::NbFaces() const
-{
- int nb = 0;
- if ( _mesh->HasShapeToMesh() )
- {
- TopTools_IndexedMapOfShape FF;
- TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_FACE, FF );
- for ( int i = 1; i <= FF.Extent(); ++i )
- if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
- nb += sm->NbElements();
- }
- else
- {
- if ( _subMeshes.empty() )
- return getMeshDS()->NbFaces();
-
- for ( unsigned i = 0; i < _subMeshes.size(); ++i )
- if ( _subMeshes[i] )
- nb += _subMeshes[i]->NbElements();
-
- // if _allowedTypes is empty, only elements from _subMeshes are returned,
- // else elements filtered using allowedTypes are additionally returned
- if ( !_allowedTypes.empty() )
- {
- for ( int t = SMDSEntity_Triangle; t <= SMDSEntity_Quad_Quadrangle; ++t )
- {
- bool allowed =
- ( find( _allowedTypes.begin(), _allowedTypes.end(), t ) != _allowedTypes.end() );
- if ( allowed )
- nb += getMeshDS()->GetMeshInfo().NbEntities( SMDSAbs_EntityType( t ));
- }
- }
- }
- return nb;
-}
-
-//================================================================================
-/*!
- * \brief Returns a proxy sub-mesh; it is created if not yet exists
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::SubMesh* StdMeshers_ProxyMesh::getProxySubMesh(int index)
-{
- if ( int(_subMeshes.size()) <= index )
- _subMeshes.resize( index+1, 0 );
- if ( !_subMeshes[index] )
- _subMeshes[index] = new SubMesh;
- return _subMeshes[index];
-}
-
-//================================================================================
-/*!
- * \brief Returns a proxy sub-mesh; it is created if not yet exists
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::SubMesh* StdMeshers_ProxyMesh::getProxySubMesh(const TopoDS_Shape& shape)
-{
- return getProxySubMesh( shapeIndex( shape ));
-}
-
-//================================================================================
-/*!
- * \brief Returns a proxy sub-mesh
- */
-//================================================================================
-
-StdMeshers_ProxyMesh::SubMesh* StdMeshers_ProxyMesh::findProxySubMesh(int shapeIndex) const
-{
- return shapeIndex < int(_subMeshes.size()) ? _subMeshes[shapeIndex] : 0;
-}
-
-//================================================================================
-/*!
- * \brief Returns mesh DS
- */
-//================================================================================
-
-SMESHDS_Mesh* StdMeshers_ProxyMesh::getMeshDS() const
-{
- return (SMESHDS_Mesh*)( _mesh ? _mesh->GetMeshDS() : 0 );
-}
-
-//================================================================================
-/*!
- * \brief Move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
- */
-//================================================================================
-
-bool StdMeshers_ProxyMesh::takeProxySubMesh( const TopoDS_Shape& shape,
- StdMeshers_ProxyMesh* proxyMesh )
-{
- if ( proxyMesh && proxyMesh->_mesh == _mesh )
- {
- int iS = shapeIndex( shape );
- if ( SubMesh* sm = proxyMesh->findProxySubMesh( iS ))
- {
- if ( iS >= int(_subMeshes.size()) )
- _subMeshes.resize( iS + 1, 0 );
- _subMeshes[iS] = sm;
- proxyMesh->_subMeshes[iS] = 0;
- return true;
- }
- }
- return false;
-}
-
-//================================================================================
-/*!
- * \brief Move tmp elements residing the _mesh from other proxy mesh to this
- */
-//================================================================================
-
-void StdMeshers_ProxyMesh::takeTmpElemsInMesh( StdMeshers_ProxyMesh* proxyMesh )
-{
- if ( proxyMesh )
- {
- _elemsInMesh.insert( proxyMesh->_elemsInMesh.begin(),
- proxyMesh->_elemsInMesh.end());
- proxyMesh->_elemsInMesh.clear();
- }
-}
-
-//================================================================================
-/*!
- * \brief Removes tmp faces from the _mesh
- */
-//================================================================================
-
-void StdMeshers_ProxyMesh::removeTmpElement( const SMDS_MeshElement* face )
-{
- if ( face && face->GetID() > 0 )
- {
- set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.find( face );
- if ( i != _elemsInMesh.end() )
- {
- getMeshDS()->RemoveFreeElement( face, 0 );
- _elemsInMesh.erase( i );
- }
- }
- else
- {
- delete face;
- }
-}
-
-//================================================================================
-/*!
- * \brief Stores tmp element residing the _mesh
- */
-//================================================================================
-
-void StdMeshers_ProxyMesh::storeTmpElement( const SMDS_MeshElement* face )
-{
- _elemsInMesh.insert( face );
-}
-
-//================================================================================
-/*!
- * \brief Return true if the element is a temporary one
- */
-//================================================================================
-
-bool StdMeshers_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const
-{
- return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem );
-}
-
-//================================================================================
-/*!
- * \brief Return a proxy node or an input node
- */
-//================================================================================
-
-const SMDS_MeshNode* StdMeshers_ProxyMesh::SubMesh::GetProxyNode( const SMDS_MeshNode* n ) const
-{
- TN2NMap::iterator n2n;
- if ( _n2n && ( n2n = _n2n->find( n )) != _n2n->end())
- return n2n->second;
- return n;
-}
-
-//================================================================================
-/*!
- * \brief Deletes temporary elements
- */
-//================================================================================
-
-void StdMeshers_ProxyMesh::SubMesh::Clear()
-{
- for ( unsigned i = 0; i < _elements.size(); ++i )
- if ( _elements[i]->GetID() < 0 )
- delete _elements[i];
- _elements.clear();
-}
-
-//================================================================================
-/*!
- * \brief Return number of elements in a proxy submesh
- */
-//================================================================================
-
-int StdMeshers_ProxyMesh::SubMesh::NbElements() const
-{
- return _elements.size();
-}
-
-//================================================================================
-/*!
- * \brief Return elements of a proxy submesh
- */
-//================================================================================
-
-SMDS_ElemIteratorPtr StdMeshers_ProxyMesh::SubMesh::GetElements() const
-{
- return SMDS_ElemIteratorPtr
- ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() ));
-}
-
-//================================================================================
-/*!
- * \brief Store an element
- */
-//================================================================================
-
-void StdMeshers_ProxyMesh::SubMesh::AddElement(const SMDS_MeshElement * e)
-{
- _elements.push_back( e );
-}
-
+++ /dev/null
-// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File : StdMeshers_ProxyMesh.hxx
-// Created : Thu Dec 2 10:05:35 2010
-// Author : Edward AGAPOV (eap)
-
-#ifndef __StdMeshers_ProxyMesh_HXX__
-#define __StdMeshers_ProxyMesh_HXX__
-
-#include "SMESH_StdMeshers.hxx"
-
-#include "SMDS_MeshElement.hxx"
-#include "SMESHDS_SubMesh.hxx"
-
-#include <TopoDS_Shape.hxx>
-
-#include <map>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-
-class SMDS_MeshNode;
-class SMESHDS_Mesh;
-class SMESH_Mesh;
-
-/*!
- * \brief Container of mesh faces substituting other faces in the input mesh of 3D algorithm
- */
-class STDMESHERS_EXPORT StdMeshers_ProxyMesh
-{
-public:
-
- typedef boost::shared_ptr<StdMeshers_ProxyMesh> Ptr;
-
- typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare > TN2NMap;
-
- //--------------------------------------------------------------------------------
- /*!
- * \brief Proxy sub-mesh
- */
- class SubMesh : public SMESHDS_SubMesh
- {
- public:
-
- const TN2NMap* GetNodeNodeMap() const { return _n2n; }
- const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* n ) const;
- virtual void AddElement(const SMDS_MeshElement * e);
- virtual int NbElements() const;
- virtual SMDS_ElemIteratorPtr GetElements() const;
- virtual void Clear();
-
- template< class ITERATOR >
- void ChangeElements( ITERATOR it, ITERATOR end )
- {
- // change SubMesh contents without deleting tmp faces
- // for which the caller is responsible
- _elements.clear();
- while ( it != end ) _elements.push_back( *it++ );
- }
- SubMesh():_n2n(0) {}
- ~SubMesh() { Clear(); }
-
- private:
- std::vector<const SMDS_MeshElement *> _elements;
- TN2NMap* _n2n;
- friend class StdMeshers_ProxyMesh;
- };
- //--------------------------------------------------------------------------------
- // Public interface
-
- StdMeshers_ProxyMesh();
- StdMeshers_ProxyMesh(std::vector<StdMeshers_ProxyMesh::Ptr>& components);
- StdMeshers_ProxyMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
- virtual ~StdMeshers_ProxyMesh();
-
- // Returns the submesh of a face; it can be a proxy sub-mesh
- const SMESHDS_SubMesh* GetSubMesh(const TopoDS_Shape& face) const;
-
- // Returns the proxy sub-mesh of a face; it can be NULL
- const SubMesh* GetProxySubMesh(const TopoDS_Shape& face) const;
-
- // Returns the proxy node of a node; the input node is returned if no proxy exists
- const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* node ) const;
-
- // Returns iterator on all faces of the mesh taking into account substitutions
- // To be used in case of mesh without shape
- SMDS_ElemIteratorPtr GetFaces() const;
-
- // Returns iterator on all faces on the face taking into account substitutions
- SMDS_ElemIteratorPtr GetFaces(const TopoDS_Shape& face) const;
-
- // Return total nb of faces taking into account substitutions
- int NbFaces() const;
-
- bool IsTemporary(const SMDS_MeshElement* elem ) const;
-
- //--------------------------------------------------------------------------------
- // Interface for descendants
- protected:
-
- void setMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
-
- const SMESH_Mesh* getMesh() const { return _mesh; }
-
- SMESHDS_Mesh* getMeshDS() const;
-
- int shapeIndex(const TopoDS_Shape& shape) const;
-
- // returns a proxy sub-mesh; zero index is for the case of mesh w/o shape
- SubMesh* findProxySubMesh(int shapeIndex=0) const;
-
- // returns a proxy sub-mesh; it is created if not yet exists
- SubMesh* getProxySubMesh(int shapeIndex);
-
- // returns a proxy sub-mesh; it is created if not yet exists
- SubMesh* getProxySubMesh(const TopoDS_Shape& shape=TopoDS_Shape());
-
- // move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
- bool takeProxySubMesh( const TopoDS_Shape& shape, StdMeshers_ProxyMesh* proxyMesh );
-
- // move tmp elements residing the _mesh from other proxy mesh to this
- void takeTmpElemsInMesh( StdMeshers_ProxyMesh* proxyMesh );
-
- // removes tmp faces from the _mesh
- void removeTmpElement( const SMDS_MeshElement* face );
-
- // stores tmp element residing the _mesh
- void storeTmpElement( const SMDS_MeshElement* face );
-
- // types of elements needed to implement NbFaces() and GetFaces();
- // if _allowedTypes is empty, only elements from _subMeshes are returned,
- // else elements of _mesh filtered using allowedTypes are additionally returned
- std::vector< SMDSAbs_EntityType> _allowedTypes;
-
- private:
-
- const SMESH_Mesh* _mesh;
-
- // proxy sub-meshes; index in vector == shapeIndex(shape)
- std::vector< SubMesh* > _subMeshes;
-
- // tmp elements residing the _mesh, to be deleted at destruction
- std::set< const SMDS_MeshElement* > _elemsInMesh;
-
- // Complex submesh used to iterate over elements in other sub-meshes
- mutable SubMesh _subContainer;
-};
-
-#endif
const SMDS_MeshElement* elem = inverseElems[i];
vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() );
nodes[ elem->GetType() == SMDSAbs_Volume ? PYRAM_APEX : TRIA_APEX ] = CommonNode;
- getMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size());
+ GetMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size());
}
ASSERT( Nrem->NbInverseElements() == 0 );
- getMeshDS()->RemoveFreeNode( Nrem,
- getMeshDS()->MeshElements( Nrem->GetPosition()->GetShapeId()),
+ GetMeshDS()->RemoveFreeNode( Nrem,
+ GetMeshDS()->MeshElements( Nrem->GetPosition()->GetShapeId()),
/*fromGroups=*/false);
}
const SMDS_MeshElement* PrmJ = vIt->next();
if ( PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second )
continue;
- if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, getMesh()->HasShapeToMesh() ))
+ if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, GetMesh()->HasShapeToMesh() ))
{
MergePiramids( PrmI, PrmJ, nodesToMove );
mergedPyrams = true;
StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor()
{
- // temporary faces are deleted by ~StdMeshers_ProxyMesh()
+ // temporary faces are deleted by ~SMESH_ProxyMesh()
if ( myElemSearcher ) delete myElemSearcher;
myElemSearcher=0;
}
bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
- StdMeshers_ProxyMesh* aProxyMesh)
+ SMESH_ProxyMesh* aProxyMesh)
{
- StdMeshers_ProxyMesh::setMesh( aMesh );
+ SMESH_ProxyMesh::setMesh( aMesh );
if ( aShape.ShapeType() != TopAbs_SOLID &&
aShape.ShapeType() != TopAbs_SHELL )
}
if ( hasNewTrias )
{
- StdMeshers_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh( aShapeFace );
+ SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh( aShapeFace );
prxSubMesh->ChangeElements( trias.begin(), trias.end() );
// delete tmp quadrangles removed from aProxyMesh
bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
{
- StdMeshers_ProxyMesh::setMesh( aMesh );
- StdMeshers_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Triangle );
- StdMeshers_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Quad_Triangle );
+ SMESH_ProxyMesh::setMesh( aMesh );
+ SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Triangle );
+ SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Quad_Triangle );
if ( aMesh.NbQuadrangles() < 1 )
return false;
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- StdMeshers_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh();
+ SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh();
SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true);
while( fIt->more())
if ( !myRemovedTrias.empty() )
{
for ( int i = 0; i <= meshDS->MaxShapeIndex(); ++i )
- if ( StdMeshers_ProxyMesh::SubMesh* sm = findProxySubMesh(i))
+ if ( SMESH_ProxyMesh::SubMesh* sm = findProxySubMesh(i))
{
vector<const SMDS_MeshElement *> faces;
faces.reserve( sm->NbElements() );
#include "SMESH_StdMeshers.hxx"
-#include "StdMeshers_ProxyMesh.hxx"
+#include "SMESH_ProxyMesh.hxx"
class SMESH_Mesh;
class SMESH_ElementSearcher;
/*!
* \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
*/
-class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor : public StdMeshers_ProxyMesh
+class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor : public SMESH_ProxyMesh
{
public:
StdMeshers_QuadToTriaAdaptor();
~StdMeshers_QuadToTriaAdaptor();
- bool Compute(SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape,
- StdMeshers_ProxyMesh* aProxyMesh=0);
+ bool Compute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_ProxyMesh* aProxyMesh=0);
bool Compute(SMESH_Mesh& aMesh);
#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
-#include "StdMeshers_ProxyMesh.hxx"
+#include "SMESH_ProxyMesh.hxx"
#include "utilities.h"
enum UIndex { U_TGT = 1, U_SRC, LEN_TGT };
/*!
- * \brief StdMeshers_ProxyMesh computed by _ViscousBuilder for a solid.
+ * \brief SMESH_ProxyMesh computed by _ViscousBuilder for a solid.
* It is stored in a SMESH_subMesh of the SOLID as SMESH_subMeshEventListenerData
*/
- struct _MeshOfSolid : public StdMeshers_ProxyMesh,
+ struct _MeshOfSolid : public SMESH_ProxyMesh,
public SMESH_subMeshEventListenerData
{
- _MeshOfSolid( SMESH_Mesh* mesh):SMESH_subMeshEventListenerData( /*isDeletable=*/true)
+ bool _n2nMapComputed;
+
+ _MeshOfSolid( SMESH_Mesh* mesh)
+ :SMESH_subMeshEventListenerData( /*isDeletable=*/true),_n2nMapComputed(false)
{
- StdMeshers_ProxyMesh::setMesh( *mesh );
+ SMESH_ProxyMesh::setMesh( *mesh );
}
// returns submesh for a geom face
- StdMeshers_ProxyMesh::SubMesh* getFaceSubM(const TopoDS_Face& F, bool create=false)
+ SMESH_ProxyMesh::SubMesh* getFaceSubM(const TopoDS_Face& F, bool create=false)
+ {
+ TGeomID i = SMESH_ProxyMesh::shapeIndex(F);
+ return create ? SMESH_ProxyMesh::getProxySubMesh(i) : findProxySubMesh(i);
+ }
+ void setNode2Node(const SMDS_MeshNode* srcNode,
+ const SMDS_MeshNode* proxyNode,
+ const SMESH_ProxyMesh::SubMesh* subMesh)
{
- TGeomID i = StdMeshers_ProxyMesh::shapeIndex(F);
- return create ? StdMeshers_ProxyMesh::getProxySubMesh(i) : findProxySubMesh(i);
+ SMESH_ProxyMesh::setNode2Node( srcNode,proxyNode,subMesh);
}
};
//--------------------------------------------------------------------------------
{
if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
{
- // delete StdMeshers_ProxyMesh containing temporary faces
+ // delete SMESH_ProxyMesh containing temporary faces
subMesh->DeleteEventListener( this );
}
}
SMESH_subMesh* sm = mesh->GetSubMesh(solid);
_MeshOfSolid* data = (_MeshOfSolid*) sm->GetEventListenerData( Get() );
if ( !data && toCreate )
- ( data = new _MeshOfSolid(mesh)), sm->SetEventListener( Get(), data, sm );
+ {
+ data = new _MeshOfSolid(mesh);
+ data->mySubMeshes.push_back( sm ); // to find SOLID by _MeshOfSolid
+ sm->SetEventListener( Get(), data, sm );
+ }
return data;
}
// Removes proxy mesh of the solid
public:
_ViscousBuilder();
// does it's job
- SMESH_ComputeErrorPtr Compute(SMESH_Mesh& mesh, const TopoDS_Shape& theShape);
+ SMESH_ComputeErrorPtr Compute(SMESH_Mesh& mesh,
+ const TopoDS_Shape& shape);
// restore event listeners used to clear an inferior dim sub-mesh modified by viscous layers
void RestoreListeners();
+ // computes SMESH_ProxyMesh::SubMesh::_n2n;
+ bool MakeN2NMap( _MeshOfSolid* pm );
+
private:
bool findSolidsWithLayers();
const SMESHDS_SubMesh* faceSubMesh );
bool addBoundaryElements();
- bool error( const string& text, _SolidData* data );
+ bool error( const string& text, int solidID=-1 );
SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); }
// debug
if ( _stretchFactor != factor )
_stretchFactor = factor, NotifySubMeshesHypothesisModification();
} // --------------------------------------------------------------------------------
-StdMeshers_ProxyMesh::Ptr StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh,
- const TopoDS_Shape& theShape) const
+SMESH_ProxyMesh::Ptr
+StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ const bool toMakeN2NMap) const
{
using namespace VISCOUS;
_ViscousBuilder bulder;
SMESH_ComputeErrorPtr err = bulder.Compute( theMesh, theShape );
if ( err && !err->IsOK() )
- return StdMeshers_ProxyMesh::Ptr();
+ return SMESH_ProxyMesh::Ptr();
- vector<StdMeshers_ProxyMesh::Ptr> components;
+ vector<SMESH_ProxyMesh::Ptr> components;
TopExp_Explorer exp( theShape, TopAbs_SOLID );
for ( ; exp.More(); exp.Next() )
{
if ( _MeshOfSolid* pm =
_ViscousListener::GetSolidMesh( &theMesh, exp.Current(), /*toCreate=*/false))
{
- components.push_back( StdMeshers_ProxyMesh::Ptr( pm ));
- pm->myIsDeletable =false; // it will de deleted by boost::shared_ptr
+ if ( toMakeN2NMap && !pm->_n2nMapComputed )
+ if ( !bulder.MakeN2NMap( pm ))
+ return SMESH_ProxyMesh::Ptr();
+ components.push_back( SMESH_ProxyMesh::Ptr( pm ));
+ pm->myIsDeletable = false; // it will de deleted by boost::shared_ptr
}
_ViscousListener::RemoveSolidMesh ( &theMesh, exp.Current() );
}
case 1: return components[0];
- default: return StdMeshers_ProxyMesh::Ptr( new StdMeshers_ProxyMesh( components ));
+ default: return SMESH_ProxyMesh::Ptr( new SMESH_ProxyMesh( components ));
}
- return StdMeshers_ProxyMesh::Ptr();
+ return SMESH_ProxyMesh::Ptr();
} // --------------------------------------------------------------------------------
std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save)
{
*/
//================================================================================
-bool _ViscousBuilder::error(const string& text, _SolidData* data )
+bool _ViscousBuilder::error(const string& text, int solidId )
{
_error->myName = COMPERR_ALGO_FAILED;
_error->myComment = string("Viscous layers builder: ") + text;
if ( _mesh )
{
- if ( !data && !_sdVec.empty() )
- data = & _sdVec[0];
- if ( data )
+ SMESH_subMesh* sm = _mesh->GetSubMeshContaining( solidId );
+ if ( !sm && !_sdVec.empty() )
+ sm = _mesh->GetSubMeshContaining( _sdVec[0]._index );
+ if ( sm && sm->GetSubShape().ShapeType() == TopAbs_SOLID )
{
- SMESH_subMesh* sm = _mesh->GetSubMesh( data->_solid );
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
if ( smError && smError->myAlgo )
_error->myAlgo = smError->myAlgo;
// TODO
}
+//================================================================================
+/*!
+ * \brief computes SMESH_ProxyMesh::SubMesh::_n2n
+ */
+//================================================================================
+
+bool _ViscousBuilder::MakeN2NMap( _MeshOfSolid* pm )
+{
+ SMESH_subMesh* solidSM = pm->mySubMeshes.front();
+ TopExp_Explorer fExp( solidSM->GetSubShape(), TopAbs_FACE );
+ for ( ; fExp.More(); fExp.Next() )
+ {
+ SMESHDS_SubMesh* srcSmDS = pm->GetMeshDS()->MeshElements( fExp.Current() );
+ const SMESH_ProxyMesh::SubMesh* prxSmDS = pm->GetProxySubMesh( fExp.Current() );
+
+ if ( !srcSmDS || !prxSmDS || !srcSmDS->NbElements() || !prxSmDS->NbElements() )
+ continue;
+ if ( srcSmDS->GetElements()->next() == prxSmDS->GetElements()->next())
+ continue;
+
+ if ( srcSmDS->NbElements() != prxSmDS->NbElements() )
+ return error( "Different nb elements in a source and a proxy sub-mesh", solidSM->GetId());
+
+ SMDS_ElemIteratorPtr srcIt = srcSmDS->GetElements();
+ SMDS_ElemIteratorPtr prxIt = prxSmDS->GetElements();
+ while( prxIt->more() )
+ {
+ const SMDS_MeshElement* fSrc = srcIt->next();
+ const SMDS_MeshElement* fPrx = prxIt->next();
+ if ( fSrc->NbNodes() != fPrx->NbNodes())
+ return error( "Different elements in a source and a proxy sub-mesh", solidSM->GetId());
+ for ( int i = 0 ; i < fPrx->NbNodes(); ++i )
+ pm->setNode2Node( fSrc->GetNode(i), fPrx->GetNode(i), prxSmDS );
+ }
+ }
+ pm->_n2nMapComputed = true;
+ return true;
+}
+
//================================================================================
/*!
* \brief Does its job
SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh& theMesh,
const TopoDS_Shape& theShape)
{
- PyDump debugDump;
// TODO: set priority of solids during Gen::Compute()
_mesh = & theMesh;
// check if proxy mesh already computed
TopExp_Explorer exp( theShape, TopAbs_SOLID );
if ( !exp.More() )
- return error("No SOLID's in theShape", 0), _error;
+ return error("No SOLID's in theShape"), _error;
if ( _ViscousListener::GetSolidMesh( _mesh, exp.Current(), /*toCreate=*/false))
return SMESH_ComputeErrorPtr(); // everything already computed
+ PyDump debugDump;
+
// TODO: ignore already computed SOLIDs
if ( !findSolidsWithLayers())
return _error;
allSolids(i),
/*toCreate=*/true);
_sdVec.push_back( _SolidData( allSolids(i), viscHyp, proxyMesh ));
- _sdVec.back()._index = _sdVec.size()-1; // debug
+ _sdVec.back()._index = getMeshDS()->ShapeToIndex( allSolids(i));
}
}
if ( _sdVec.empty() )
break;
}
default:
- return error("Not yet supported case", &_sdVec[i]);
+ return error("Not yet supported case", _sdVec[i]._index);
}
}
}
for ( set<TGeomID>::iterator id = faceIds.begin(); id != faceIds.end(); ++id )
{
SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( *id );
- if ( !smDS ) return error(SMESH_Comment("Not meshed face ") << *id, &data );
+ if ( !smDS ) return error(SMESH_Comment("Not meshed face ") << *id, data._index );
const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( *id ));
- StdMeshers_ProxyMesh::SubMesh* proxySub =
+ SMESH_ProxyMesh::SubMesh* proxySub =
data._proxyMesh->getFaceSubM( F, /*create=*/true);
SMDS_ElemIteratorPtr eIt = smDS->GetElements();
break; // _LayerEdge is shared by two _SolidData's
const SMDS_MeshNode* & n = data._edges[i]->_2neibors->_nodes[j];
if (( n2e = data._n2eMap.find( n )) == data._n2eMap.end() )
- return error("_LayerEdge not found by src node", &data);
+ return error("_LayerEdge not found by src node", data._index);
n = (*n2e).second->_nodes.back();
data._edges[i]->_2neibors->_edges[j] = n2e->second;
}
edge._normal += geomNorm.XYZ();
}
if ( totalNbFaces == 0 )
- return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), &data);
+ return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index);
edge._normal /= totalNbFaces;
break;
}
default:
- return error(SMESH_Comment("Invalid shape position of node ")<<node,&data);
+ return error(SMESH_Comment("Invalid shape position of node ")<<node, data._index);
}
}
double normSize = edge._normal.SquareModulus();
if ( normSize < numeric_limits<double>::min() )
- return error(SMESH_Comment("Bad normal at node ")<< node->GetID(), &data );
+ return error(SMESH_Comment("Bad normal at node ")<< node->GetID(), data._index );
edge._normal /= sqrt( normSize );
edgeSM = getMeshDS()->MeshElements( shapeInd );
if ( !edgeSM || edgeSM->NbElements() == 0 )
- return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, &data);
+ return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, data._index);
}
int iN = 0;
n2 = 0;
( iN++ ? n2 : n1 ) = nNeibor;
}
if ( !n2 )
- return error(SMESH_Comment("Wrongly meshed EDGE ") << shapeInd, &data);
+ return error(SMESH_Comment("Wrongly meshed EDGE ") << shapeInd, data._index);
return true;
}
}
if (nbSteps == 0 )
- return error("failed at the very first inflation step", &data);
+ return error("failed at the very first inflation step", data._index);
return true;
}
// neiborEdge = data._edges[i-di];
// }
// if ( !neiborEdge )
-// return error("updateNormals(): neighbor _LayerEdge not found", &data);
+// return error("updateNormals(): neighbor _LayerEdge not found", data._index);
_LayerEdge* neiborEdge = edge->_2neibors->_edges[j];
TmpMeshFaceOnEdge* f = new TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID );
// TODO: make quadratic prisms and polyhedrons(?)
+ helper.SetElementsOnShape(true);
+
TopExp_Explorer exp( data._solid, TopAbs_FACE );
for ( ; exp.More(); exp.Next() )
{
(*nnVec[2])[iZ], (*nnVec[3])[iZ]);
break;
default:
- return error("Not supported type of element", &data);
+ return error("Not supported type of element", data._index);
}
}
}
// by StdMeshers_QuadToTriaAdaptor
if ( SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( s2s->second ))
{
- StdMeshers_ProxyMesh::SubMesh* proxySub =
+ SMESH_ProxyMesh::SubMesh* proxySub =
data._proxyMesh->getFaceSubM( TopoDS::Face( s2s->second ), /*create=*/true);
SMDS_ElemIteratorPtr fIt = smDS->GetElements();
while ( fIt->more() )
dumpFunctionEnd();
}
if ( badNb > 0 )
- return error(SMESH_Comment("Can't shrink 2D mesh on face ") << f2sd->first, 0 );
+ return error(SMESH_Comment("Can't shrink 2D mesh on face ") << f2sd->first );
}
// No wrongly shaped faces remain; final smooth. Set node XYZ
for ( int st = 3; st; --st )
TopoDS_Edge E = TopoDS::Edge( edge._sWOL);
SMESHDS_SubMesh* edgeSM = getMeshDS()->MeshElements( E );
if ( !edgeSM || edgeSM->NbElements() == 0 )
- return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E ), 0);
+ return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
const SMDS_MeshNode* n2 = 0;
SMDS_ElemIteratorPtr eIt = srcNode->GetInverseElementIterator(SMDSAbs_Edge);
if ( n2 == srcNode ) n2 = e->GetNode( 1 );
}
if ( !n2 )
- return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E ), 0);
+ return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
double uSrc = helper.GetNodeU( E, srcNode, n2 );
double uTgt = helper.GetNodeU( E, tgtNode, srcNode );
else
sm = data._proxyMesh->getFaceSubM( TopoDS::Face(F), /*create=*/true );
if ( !sm )
- return error("error in addBoundaryElements()", &data);
+ return error("error in addBoundaryElements()", data._index);
// Make faces
const int dj1 = reverse ? 0 : 1;
#include "SMESH_StdMeshers.hxx"
#include "SMESH_Hypothesis.hxx"
-#include "StdMeshers_ProxyMesh.hxx"
+#include "SMESH_ProxyMesh.hxx"
#include <vector>
double GetStretchFactor() const { return _stretchFactor; }
// Computes temporary 2D mesh to be used by 3D algorithm.
- // Return StdMeshers_ProxyMesh for each SOLID in theShape
- StdMeshers_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh,
- const TopoDS_Shape& theShape) const;
+ // Return SMESH_ProxyMesh for each SOLID in theShape
+ SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ const bool toMakeN2NMap=false) const;
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);