+namespace {
+
+ //=============================================================================
+ /*!
+ * \brief Mesh to apply modifications for preview purposes
+ */
+ //=============================================================================
+
+ struct TPreviewMesh: public SMESH_Mesh
+ {
+ SMDSAbs_ElementType myPreviewType; // type to show
+ //!< Constructor
+ TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
+ _isShapeToMesh = _id =_studyId =_idDoc = 0;
+ _myMeshDS = new SMESHDS_Mesh( _id, true );
+ myPreviewType = previewElements;
+ }
+ //!< Destructor
+ virtual ~TPreviewMesh() { delete _myMeshDS; }
+ //!< Copy a set of elements
+ void Copy(const TIDSortedElemSet & theElements,
+ TIDSortedElemSet& theCopyElements,
+ SMDSAbs_ElementType theSelectType = SMDSAbs_All,
+ SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
+ {
+ // loop on theIDsOfElements
+ TIDSortedElemSet::const_iterator eIt = theElements.begin();
+ for ( ; eIt != theElements.end(); ++eIt )
+ {
+ const SMDS_MeshElement* anElem = *eIt;
+ if ( !anElem ) continue;
+ SMDSAbs_ElementType type = anElem->GetType();
+ if ( type == theAvoidType ||
+ ( theSelectType != SMDSAbs_All && type != theSelectType ))
+ continue;
+
+ if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
+ theCopyElements.insert( theCopyElements.end(), anElemCopy );
+ }
+ }
+ //!< Copy an element
+ SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
+ {
+ // copy element nodes
+ int anElemNbNodes = anElem->NbNodes();
+ vector< int > anElemNodesID( anElemNbNodes ) ;
+ SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
+ for ( int i = 0; itElemNodes->more(); i++)
+ {
+ const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
+ Copy( anElemNode );
+ anElemNodesID[i] = anElemNode->GetID();
+ }
+
+ // creates a corresponding element on copied nodes
+ SMDS_MeshElement* anElemCopy = 0;
+ if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
+ {
+ const SMDS_PolyhedralVolumeOfNodes* ph =
+ dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+ if ( ph )
+ anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
+ (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+ }
+ else {
+ anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
+ anElem->GetType(),
+ anElem->IsPoly() );
+ }
+ return anElemCopy;
+ }
+ //!< Copy a node
+ SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
+ {
+ return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
+ anElemNode->GetID());
+ }
+ };// struct TPreviewMesh
+
+ static SMESH_NodeSearcher * myNodeSearcher = 0;
+
+ //=============================================================================
+ /*!
+ * \brief Deleter of myNodeSearcher at any compute event occured
+ */
+ //=============================================================================
+
+ struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
+ {
+ SMESH_Mesh* myMesh;
+ //!< Constructor
+ TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
+ myMesh(0) {}
+ //!< Delete myNodeSearcher
+ static void Delete()
+ {
+ if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
+ }
+ typedef map < int, SMESH_subMesh * > TDependsOnMap;
+ //!< The meshod called by submesh: do my main job
+ void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
+ SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
+ {
+ if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
+ Delete();
+ Unset( sm->GetFather() );
+ }
+ }
+ //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
+ void Set(SMESH_Mesh* mesh)
+ {
+ if ( myMesh && myMesh != mesh ) {
+ Delete();
+ Unset( myMesh );
+ }
+ myMesh = mesh;
+ if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+ const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+ TDependsOnMap::const_iterator sm;
+ for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+ sm->second->SetEventListener( this, 0, sm->second );
+ }
+ }
+ //!< delete self from all submeshes
+ void Unset(SMESH_Mesh* mesh)
+ {
+ if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+ const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+ TDependsOnMap::const_iterator sm;
+ for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+ sm->second->DeleteEventListener( this );
+ }
+ }
+ };
+}
+