From: uhz Date: Mon, 16 Apr 2018 08:57:55 +0000 (+0200) Subject: Revert "23418: [OCC] Mesh: Minimization of memory usage of SMESH" X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=7f69bf0122b3be1c986dace03f53a78f50d021ad;p=modules%2Fsmesh.git Revert "23418: [OCC] Mesh: Minimization of memory usage of SMESH" This reverts commit 4c16067d4281f56bd07d3f92fb63fff9c0c1d169. --- diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 1ccd96f99..b1279a659 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -28,6 +28,8 @@ #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_GroupBase.hxx" #include "SMESHDS_GroupOnFilter.hxx" @@ -251,7 +253,26 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, theRes.setElement( anElem ); // Get nodes of the element - SMDS_NodeIteratorPtr anIter= anElem->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter; + + if ( anElem->IsQuadratic() ) { + switch ( anElem->GetType() ) { + case SMDSAbs_Edge: + anIter = dynamic_cast + (anElem)->interlacedNodesElemIterator(); + break; + case SMDSAbs_Face: + anIter = dynamic_cast + (anElem)->interlacedNodesElemIterator(); + break; + default: + anIter = anElem->nodesIterator(); + } + } + else { + anIter = anElem->nodesIterator(); + } + if ( anIter ) { SMESH_NodeXYZ p; while( anIter->more() ) { @@ -750,8 +771,8 @@ double AspectRatio::GetValue( long theId ) if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD ) { // issue 21723 - vtkUnstructuredGrid* grid = const_cast( myMesh )->GetGrid(); - if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() )) + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid(); + if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() )) aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell )); } else @@ -994,8 +1015,8 @@ double AspectRatio3D::GetValue( long theId ) // Action from CoTech | ACTION 31.3: // EURIWARE BO: Homogenize the formulas used to calculate the Controls in SMESH to fit with // those of ParaView. The library used by ParaView for those calculations can be reused in SMESH. - vtkUnstructuredGrid* grid = const_cast( myMesh )->GetGrid(); - if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() )) + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid(); + if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() )) aVal = Round( vtkMeshQuality::TetAspectRatio( avtkCell )); } else @@ -1014,7 +1035,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) int nbNodes = P.size(); - if( myCurrElement->IsQuadratic() ) { + if(myCurrElement->IsQuadratic()) { if(nbNodes==10) nbNodes=4; // quadratic tetrahedron else if(nbNodes==13) nbNodes=5; // quadratic pyramid else if(nbNodes==15) nbNodes=6; // quadratic pentahedron @@ -1806,33 +1827,35 @@ bool Length2D::Value::operator<(const Length2D::Value& x) const void Length2D::GetValues(TValues& theValues) { TValues aValues; - for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) - { + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + for(; anIter->more(); ){ const SMDS_MeshFace* anElem = anIter->next(); - if ( anElem->IsQuadratic() ) - { + + if(anElem->IsQuadratic()) { + const SMDS_VtkFace* F = + dynamic_cast(anElem); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); long aNodeId[4] = { 0,0,0,0 }; gp_Pnt P[4]; double aLength = 0; - if ( anIter->more() ) - { - const SMDS_MeshNode* aNode = anIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); + const SMDS_MeshElement* aNode; + if(anIter->more()){ + aNode = anIter->next(); + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode; + P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z()); aNodeId[0] = aNodeId[1] = aNode->GetID(); aLength = 0; } - for ( ; anIter->more(); ) - { - const SMDS_MeshNode* N1 = anIter->next(); - P[2] = SMESH_NodeXYZ( N1 ); + for(; anIter->more(); ){ + const SMDS_MeshNode* N1 = static_cast (anIter->next()); + P[2] = gp_Pnt(N1->X(),N1->Y(),N1->Z()); aNodeId[2] = N1->GetID(); aLength = P[1].Distance(P[2]); if(!anIter->more()) break; - const SMDS_MeshNode* N2 = anIter->next(); - P[3] = SMESH_NodeXYZ( N2 ); + const SMDS_MeshNode* N2 = static_cast (anIter->next()); + P[3] = gp_Pnt(N2->X(),N2->Y(),N2->Z()); aNodeId[3] = N2->GetID(); aLength += P[2].Distance(P[3]); Value aValue1(aLength,aNodeId[1],aNodeId[2]); @@ -1849,28 +1872,28 @@ void Length2D::GetValues(TValues& theValues) theValues.insert(aValue2); } else { - SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); long aNodeId[2] = {0,0}; gp_Pnt P[3]; double aLength; const SMDS_MeshElement* aNode; - if ( aNodesIter->more()) - { + if(aNodesIter->more()){ aNode = aNodesIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode; + P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z()); aNodeId[0] = aNodeId[1] = aNode->GetID(); aLength = 0; } - for( ; aNodesIter->more(); ) - { + for(; aNodesIter->more(); ){ aNode = aNodesIter->next(); + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode; long anId = aNode->GetID(); - - P[2] = SMESH_NodeXYZ( aNode ); - + + P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z()); + aLength = P[1].Distance(P[2]); - + Value aValue(aLength,aNodeId[1],anId); aNodeId[1] = anId; P[1] = P[2]; @@ -1924,7 +1947,8 @@ double Deflection2D::GetValue( const TSequenceOfXYZ& P ) { gc += P(i+1); - if ( SMDS_FacePositionPtr fPos = P.getElement()->GetNode( i )->GetPosition() ) + if ( const SMDS_FacePosition* fPos = dynamic_cast + ( P.getElement()->GetNode( i )->GetPosition() )) { uv.ChangeCoord(1) += fPos->GetUParameter(); uv.ChangeCoord(2) += fPos->GetVParameter(); @@ -2100,24 +2124,59 @@ bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) cons void MultiConnection2D::GetValues(MValues& theValues) { if ( !myMesh ) return; - for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) - { - const SMDS_MeshFace* anElem = anIter->next(); - SMDS_NodeIteratorPtr aNodesIter = anElem->interlacedNodesIterator(); + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + for(; anIter->more(); ){ + const SMDS_MeshFace* anElem = anIter->next(); + SMDS_ElemIteratorPtr aNodesIter; + if ( anElem->IsQuadratic() ) + aNodesIter = dynamic_cast + (anElem)->interlacedNodesElemIterator(); + else + aNodesIter = anElem->nodesIterator(); + long aNodeId[3] = {0,0,0}; - const SMDS_MeshNode* aNode1 = anElem->GetNode( anElem->NbNodes() - 1 ); + //int aNbConnects=0; + const SMDS_MeshNode* aNode0; + const SMDS_MeshNode* aNode1; const SMDS_MeshNode* aNode2; - for ( ; aNodesIter->more(); ) - { - aNode2 = aNodesIter->next(); - - Value aValue ( aNode1->GetID(), aNode2->GetID() ); - MValues::iterator aItr = theValues.insert( std::make_pair( aValue, 0 )).first; - aItr->second++; + if(aNodesIter->more()){ + aNode0 = (SMDS_MeshNode*) aNodesIter->next(); + aNode1 = aNode0; + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode1; + aNodeId[0] = aNodeId[1] = aNodes->GetID(); + } + for(; aNodesIter->more(); ) { + aNode2 = (SMDS_MeshNode*) aNodesIter->next(); + long anId = aNode2->GetID(); + aNodeId[2] = anId; + + Value aValue(aNodeId[1],aNodeId[2]); + MValues::iterator aItr = theValues.find(aValue); + if (aItr != theValues.end()){ + aItr->second += 1; + //aNbConnects = nb; + } + else { + theValues[aValue] = 1; + //aNbConnects = 1; + } + //cout << "NodeIds: "<nodesIterator(); + nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true ); for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Y(); if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble), "CoordinateY", &coords[0], &iC) != CG_OK ) return addMessage( cg_get_error(), /*fatal = */true ); // Z - nIt = myMesh->nodesIterator(); + nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true ); for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Z(); if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble), "CoordinateZ", &coords[0], &iC) != CG_OK ) return addMessage( cg_get_error(), /*fatal = */true ); // store CGNS ids of nodes - nIt = myMesh->nodesIterator(); + nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true ); for ( int i = 0; nIt->more(); ++i ) { const SMDS_MeshElement* n = nIt->next(); diff --git a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx index 403dad4f5..7ab288f86 100644 --- a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx @@ -117,7 +117,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() } SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); - const SMDS_MeshVolume* v; + const SMDS_VtkVolume* v; while(itVolumes->more()) { const SMDS_MeshElement * elem = itVolumes->next(); @@ -125,7 +125,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() { fprintf(aFileId, "%d %d ", elem->GetID(), 500+elem->NbNodes()); - if (( v = myMesh->DownCast< SMDS_MeshVolume >( elem ))) + if (( v = dynamic_cast< const SMDS_VtkVolume*>( elem ))) { std::vector quant = v->GetQuantities(); if ( !quant.empty() ) @@ -146,7 +146,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() fprintf(aFileId, "\n"); } - + fclose(aFileId); return aResult; diff --git a/src/DriverGMF/DriverGMF_Read.cxx b/src/DriverGMF/DriverGMF_Read.cxx index 420b1495b..54edf6a9c 100644 --- a/src/DriverGMF/DriverGMF_Read.cxx +++ b/src/DriverGMF/DriverGMF_Read.cxx @@ -444,9 +444,6 @@ Driver_Mesh::Status DriverGMF_Read::Perform() } } - myMesh->Modified(); - myMesh->CompactMesh(); - return status; } diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx index a31488e4a..a11ba4860 100644 --- a/src/DriverMED/DriverMED_Family.cxx +++ b/src/DriverMED/DriverMED_Family.cxx @@ -574,21 +574,3 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by, common->myType = myType; } } - -//================================================================================ -/*! - * \brief Return a number of elements of a given type - */ -//================================================================================ - -size_t DriverMED_Family::NbElements( SMDSAbs_ElementType theType ) const -{ - if ( myTypes.size() < 2 ) - return myElements.size(); - - int nb = 0; - for ( ElementsSet::iterator e = myElements.begin(); e != myElements.end(); ++e ) - nb += ( theType == (*e)->GetType() ); - - return nb; -} diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h index 97157a2a3..c71ea7254 100644 --- a/src/DriverMED/DriverMED_Family.h +++ b/src/DriverMED/DriverMED_Family.h @@ -119,11 +119,9 @@ class MESHDRIVERMED_EXPORT DriverMED_Family bool MemberOf(std::string theGroupName) const; - int GetGroupAttributVal() const; + int GetGroupAttributVal() const; void SetGroupAttributVal( int theValue); - size_t NbElements( SMDSAbs_ElementType ) const; - private: //! Initialize the tool by SMESHDS_GroupBase void Init (SMESHDS_GroupBase* group); diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 14a648c8a..000316955 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -273,7 +273,7 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() if ( anIsElemNum && !aBallInfo->myElemNum->empty() ) maxID = *std::max_element( aBallInfo->myElemNum->begin(), aBallInfo->myElemNum->end() ); - myMesh->GetGrid()->AllocateDiameters( maxID ); // performance optimization + myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization // create balls SMDS_MeshElement* anElement; @@ -1038,6 +1038,8 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() aResult = addMessage( "Unknown exception", /*isFatal=*/true ); } #endif + if (myMesh) + myMesh->compactMesh(); // Mantis issue 0020483 if (aResult == DRS_OK && isDescConn) { @@ -1135,14 +1137,6 @@ void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup) if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( aGroupName ))) { - size_t groupSize = 0; - for ( size_t i = 0; i < famVecPtr->size(); ++i ) - { - DriverMED_FamilyPtr aFamily = (*famVecPtr)[i]; - groupSize += aFamily->NbElements( theGroup->GetType() ); - } - theGroup->SMDSGroup().Reserve( groupSize ); - for ( size_t i = 0; i < famVecPtr->size(); ++i ) { DriverMED_FamilyPtr aFamily = (*famVecPtr)[i]; diff --git a/src/DriverMED/DriverMED_W_Field.cxx b/src/DriverMED/DriverMED_W_Field.cxx index 8317ae96b..57e8edf19 100644 --- a/src/DriverMED/DriverMED_W_Field.cxx +++ b/src/DriverMED/DriverMED_W_Field.cxx @@ -33,6 +33,7 @@ #include "MED_Wrapper.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshElement.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Mesh.hxx" @@ -100,7 +101,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh * mesh, for ( int iG = 0; iG < SMDSEntity_Last; ++iG ) { SMDSAbs_EntityType geom = (SMDSAbs_EntityType) iG; - SMDSAbs_ElementType t = SMDS_MeshCell::ElemType( geom ); + SMDSAbs_ElementType t = SMDS_MeshCell::toSmdsType( geom ); if ( t != _elemType ) continue; nbElems = mesh->GetMeshInfo().NbElements( geom ); diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index c33517ca0..75ebf667a 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -31,7 +31,9 @@ #include "MED_Factory.hxx" #include "MED_Utilities.hxx" #include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Mesh.hxx" @@ -358,6 +360,10 @@ namespace Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() { Status aResult = DRS_OK; + if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) { + INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!"); + return DRS_FAIL; + } try { //MESSAGE("Perform - myFile : "<next(); aBounds[0] = min(aBounds[0],aNode->X()); aBounds[1] = max(aBounds[1],aNode->X()); - + aBounds[2] = min(aBounds[2],aNode->Y()); aBounds[3] = max(aBounds[3],aNode->Y()); @@ -448,7 +454,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() } } - SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); + SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true); switch ( aSpaceDimension ) { case 3: aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName)); @@ -851,7 +857,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // Treat POLYEDREs // ---------------- - else if ( aElemTypeData->_geomType == ePOLYEDRE ) + else if (aElemTypeData->_geomType == ePOLYEDRE ) { elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA ); @@ -859,8 +865,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // Count nb of nodes while ( elemIterator->more() ) { const SMDS_MeshElement* anElem = elemIterator->next(); - nbPolyhedronNodes += anElem->NbNodes(); - nbPolyhedronFaces += anElem->NbFaces(); + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); + if ( !aPolyedre ) continue; + nbPolyhedronNodes += aPolyedre->NbNodes(); + nbPolyhedronFaces += aPolyedre->NbFaces(); if ( ++iElem == aElemTypeData->_nbElems ) break; } @@ -885,8 +893,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() TInt iFace = 0, iNode = 0; while ( elemIterator->more() ) { - const SMDS_MeshElement* anElem = elemIterator->next(); - const SMDS_MeshVolume *aPolyedre = myMesh->DownCast< SMDS_MeshVolume >( anElem ); + const SMDS_MeshElement* anElem = elemIterator->next(); + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); if ( !aPolyedre ) continue; // index TInt aNbFaces = aPolyedre->NbFaces(); diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h index 9c24099b4..a9539b9e8 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h @@ -40,7 +40,6 @@ class SMESHDS_Mesh; class SMESHDS_GroupBase; class SMESHDS_SubMesh; -class SMDS_MeshElement; class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh { diff --git a/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx b/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx index f1e1ea6ac..ae7e48cca 100644 --- a/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx +++ b/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx @@ -142,9 +142,6 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform() else aResult = readBinary( file ); - myMesh->Modified(); - myMesh->CompactMesh(); - return aResult; } diff --git a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx index 10f7567f0..27576a613 100644 --- a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx @@ -93,11 +93,11 @@ namespace DriverUNV_R_SMDS_Mesh::~DriverUNV_R_SMDS_Mesh() { - TGroupNamesMap::iterator grp2name = myGroupNames.begin(); - for ( ; grp2name != myGroupNames.end(); ++grp2name ) - delete grp2name->first; + if (myGroup != 0) + delete myGroup; } + Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() { Kernel_Utils::Localizer loc; @@ -137,7 +137,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() } } // Move nodes to SI unit system - const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ]; + const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ]; if ( lenFactor != 1. ) { TDataSet::iterator nodeIter = aDataSet2411.begin(), nodeEnd; @@ -187,23 +187,23 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() else if(IsFace(aRec.fe_descriptor_id)) { //MESSAGE("add face " << aRec.label); switch(aRec.fe_descriptor_id){ - case 41: // Plane Stress Linear Triangle - case 51: // Plane Strain Linear Triangle - case 61: // Plate Linear Triangle - case 74: // Membrane Linear Triangle - case 81: // Axisymetric Solid Linear Triangle - case 91: // Thin Shell Linear Triangle + case 41: // Plane Stress Linear Triangle + case 51: // Plane Strain Linear Triangle + case 61: // Plate Linear Triangle + case 74: // Membrane Linear Triangle + case 81: // Axisymetric Solid Linear Triangle + case 91: // Thin Shell Linear Triangle anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], aRec.label); break; - case 42: // Plane Stress Parabolic Triangle - case 52: // Plane Strain Parabolic Triangle - case 62: // Plate Parabolic Triangle - case 72: // Membrane Parabolic Triangle - case 82: // Axisymetric Solid Parabolic Triangle + case 42: // Plane Stress Parabolic Triangle + case 52: // Plane Strain Parabolic Triangle + case 62: // Plate Parabolic Triangle + case 72: // Membrane Parabolic Triangle + case 82: // Axisymetric Solid Parabolic Triangle case 92: // Thin Shell Parabolic Triangle if ( aRec.node_labels.size() == 7 ) anElement = myMesh->AddFaceWithID(aRec.node_labels[0], @@ -224,12 +224,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.label); break; - case 44: // Plane Stress Linear Quadrilateral - case 54: // Plane Strain Linear Quadrilateral - case 64: // Plate Linear Quadrilateral - case 71: // Membrane Linear Quadrilateral + case 44: // Plane Stress Linear Quadrilateral + case 54: // Plane Strain Linear Quadrilateral + case 64: // Plate Linear Quadrilateral + case 71: // Membrane Linear Quadrilateral case 84: // Axisymetric Solid Linear Quadrilateral - case 94: // Thin Shell Linear Quadrilateral + case 94: // Thin Shell Linear Quadrilateral anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], @@ -237,12 +237,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.label); break; - case 45: // Plane Stress Parabolic Quadrilateral - case 55: // Plane Strain Parabolic Quadrilateral - case 65: // Plate Parabolic Quadrilateral - case 75: // Membrane Parabolic Quadrilateral - case 85: // Axisymetric Solid Parabolic Quadrilateral - case 95: // Thin Shell Parabolic Quadrilateral + case 45: // Plane Stress Parabolic Quadrilateral + case 55: // Plane Strain Parabolic Quadrilateral + case 65: // Plate Parabolic Quadrilateral + case 75: // Membrane Parabolic Quadrilateral + case 85: // Axisymetric Solid Parabolic Quadrilateral + case 95: // Thin Shell Parabolic Quadrilateral if ( aRec.node_labels.size() == 9 ) anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[2], @@ -295,7 +295,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[7], aRec.label); break; - + case 112: // Solid Linear Prism - PRISM6 anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], @@ -305,7 +305,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[4], aRec.label); break; - + case 113: // Solid Quadratic Prism - PRISM15 anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[4], @@ -328,7 +328,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[7], aRec.label); break; - + case 115: // Solid Linear Brick - HEX8 anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[3], @@ -396,63 +396,101 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() } } { - using namespace UNV2417; + using namespace UNV2417; TDataSet aDataSet2417; UNV2417::Read(in_stream,aDataSet2417); if(MYDEBUG) MESSAGE("Perform - aDataSet2417.size() = "< 0) - { + if (aDataSet2417.size() > 0) { + myGroup = new SMDS_MeshGroup(myMesh); TDataSet::const_iterator anIter = aDataSet2417.begin(); - for ( ; anIter != aDataSet2417.end(); anIter++ ) - { + for(; anIter != aDataSet2417.end(); anIter++){ + const TGroupId& aLabel = anIter->first; const TRecord& aRec = anIter->second; - int aNodesNb = aRec.NodeList.size(); - int aElementsNb = aRec.ElementList.size(); + + int aNodesNb = aRec.NodeList.size(); + int aElementsNb = aRec.ElementList.size(); bool useSuffix = ((aNodesNb > 0) && (aElementsNb > 0)); - if ( aNodesNb > 0 ) - { - SMDS_MeshGroup* aNodesGroup = new SMDS_MeshGroup( myMesh ); + int i; + if (aNodesNb > 0) { + SMDS_MeshGroup* aNodesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Node); std::string aGrName = (useSuffix) ? aRec.GroupName + "_Nodes" : aRec.GroupName; int i = aGrName.find( "\r" ); if (i > 0) aGrName.erase (i, 2); - myGroupNames.insert( std::make_pair( aNodesGroup, aGrName )); + myGroupNames.insert(TGroupNamesMap::value_type(aNodesGroup, aGrName)); + myGroupId.insert(TGroupIdMap::value_type(aNodesGroup, aLabel)); - for ( int i = 0; i < aNodesNb; i++ ) - if ( const SMDS_MeshNode* aNode = myMesh->FindNode( aRec.NodeList[i] )) - aNodesGroup->Add( aNode ); + for (i = 0; i < aNodesNb; i++) { + const SMDS_MeshNode* aNode = myMesh->FindNode(aRec.NodeList[i]); + if (aNode) + aNodesGroup->Add(aNode); + } } - if ( aElementsNb > 0 ) - { - std::vector< SMDS_MeshGroup* > aGroupVec( SMDSAbs_NbElementTypes, (SMDS_MeshGroup*)0 ); - const char* aSuffix[] = { "", "", "_Edges", "_Faces", "_Volumes", "_0D", "_Balls" }; + if (aElementsNb > 0){ + SMDS_MeshGroup* aEdgesGroup = 0; + SMDS_MeshGroup* aFacesGroup = 0; + SMDS_MeshGroup* aVolumeGroup = 0; bool createdGroup = false; - for ( int i = 0; i < aElementsNb; i++) - { - const SMDS_MeshElement* aElement = myMesh->FindElement( aRec.ElementList[i] ); - if ( !aElement ) continue; - - SMDS_MeshGroup * & aGroup = aGroupVec[ aElement->GetType() ]; - if ( !aGroup ) - { - aGroup = new SMDS_MeshGroup( myMesh ); - if (!useSuffix && createdGroup) useSuffix = true; - std::string aGrName = aRec.GroupName; - int i = aGrName.find( "\r" ); - if ( i > 0 ) - aGrName.erase (i, 2); - if ( useSuffix ) - aGrName += aSuffix[ aElement->GetType() ]; - myGroupNames.insert( std::make_pair( aGroup, aGrName )); - createdGroup = true; - } - aGroup->Add(aElement); + + for (i = 0; i < aElementsNb; i++) { + const SMDS_MeshElement* aElement = myMesh->FindElement(aRec.ElementList[i]); + if (aElement) { + switch (aElement->GetType()) { + + case SMDSAbs_Edge: + if (!aEdgesGroup) { + aEdgesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Edge); + if (!useSuffix && createdGroup) useSuffix = true; + std::string aEdgesGrName = (useSuffix) ? aRec.GroupName + "_Edges" : aRec.GroupName; + int i = aEdgesGrName.find( "\r" ); + if (i > 0) + aEdgesGrName.erase (i, 2); + myGroupNames.insert(TGroupNamesMap::value_type(aEdgesGroup, aEdgesGrName)); + myGroupId.insert(TGroupIdMap::value_type(aEdgesGroup, aLabel)); + createdGroup = true; + } + aEdgesGroup->Add(aElement); + break; + + case SMDSAbs_Face: + if (!aFacesGroup) { + aFacesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Face); + if (!useSuffix && createdGroup) useSuffix = true; + std::string aFacesGrName = (useSuffix) ? aRec.GroupName + "_Faces" : aRec.GroupName; + int i = aFacesGrName.find( "\r" ); + if (i > 0) + aFacesGrName.erase (i, 2); + myGroupNames.insert(TGroupNamesMap::value_type(aFacesGroup, aFacesGrName)); + myGroupId.insert(TGroupIdMap::value_type(aFacesGroup, aLabel)); + createdGroup = true; + } + aFacesGroup->Add(aElement); + break; + + case SMDSAbs_Volume: + if (!aVolumeGroup) { + aVolumeGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Volume); + if (!useSuffix && createdGroup) useSuffix = true; + std::string aVolumeGrName = (useSuffix) ? aRec.GroupName + "_Volumes" : aRec.GroupName; + int i = aVolumeGrName.find( "\r" ); + if (i > 0) + aVolumeGrName.erase (i, 2); + myGroupNames.insert(TGroupNamesMap::value_type(aVolumeGroup, aVolumeGrName)); + myGroupId.insert(TGroupIdMap::value_type(aVolumeGroup, aLabel)); + createdGroup = true; + } + aVolumeGroup->Add(aElement); + break; + + default:; + } + } } } } } - } + } } catch(const std::exception& exc){ INFOS("Follow exception was cought:\n\t"<Modified(); - myMesh->CompactMesh(); - } + myMesh->compactMesh(); return aResult; } diff --git a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.h b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.h index 42de629ca..4f7407dbb 100644 --- a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.h +++ b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.h @@ -30,22 +30,32 @@ #include +class SMDS_Mesh; class SMDS_MeshGroup; + +typedef std::map TGroupNamesMap; +typedef std::map TGroupIdMap; + typedef std::map TGroupNamesMap; +typedef std::map TGroupIdMap; class MESHDRIVERUNV_EXPORT DriverUNV_R_SMDS_Mesh: public Driver_SMDS_Mesh { public: - DriverUNV_R_SMDS_Mesh():Driver_SMDS_Mesh() {}; + DriverUNV_R_SMDS_Mesh():Driver_SMDS_Mesh(),myGroup(0) {}; ~DriverUNV_R_SMDS_Mesh(); - + virtual Status Perform(); - TGroupNamesMap& GetGroupNamesMap() { return myGroupNames; } + const SMDS_MeshGroup* GetGroup() const { return myGroup;} + const TGroupNamesMap& GetGroupNamesMap() const { return myGroupNames; } + const TGroupIdMap& GetGroupIdMap() const { return myGroupId; } private: + SMDS_MeshGroup* myGroup; TGroupNamesMap myGroupNames; + TGroupIdMap myGroupId; }; #endif diff --git a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx index 02ec7588b..d8bca84a0 100644 --- a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx @@ -25,6 +25,9 @@ #include "DriverUNV_W_SMDS_Mesh.h" #include "SMDS_Mesh.hxx" +#include "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMESHDS_GroupBase.hxx" #include "utilities.h" diff --git a/src/DriverUNV/UNV2417_Structure.hxx b/src/DriverUNV/UNV2417_Structure.hxx index 183c0e4dc..c2868486b 100644 --- a/src/DriverUNV/UNV2417_Structure.hxx +++ b/src/DriverUNV/UNV2417_Structure.hxx @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include namespace UNV2417{ @@ -34,9 +34,9 @@ namespace UNV2417{ typedef std::vector TListOfId; // Nodal connectivitiesList of Id struct TRecord{ - std::string GroupName; - TListOfId NodeList; - TListOfId ElementList; + std::string GroupName; + TListOfId NodeList; + TListOfId ElementList; }; typedef int TGroupId; // type of element label diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 3f64bf4ab..a1a69ff3f 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -31,6 +31,7 @@ #include "SMDS_BallElement.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshCell.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_Script.hxx" #include "SMESH_Actor.h" @@ -80,6 +81,54 @@ static int MYDEBUGWITHFILES = 0; Class : SMESH_VisualObjDef Description : Base class for all mesh objects to be visuilised */ + +//================================================================================= +// function : getCellType +// purpose : Get type of VTK cell +//================================================================================= +// static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, +// const bool thePoly, +// const int theNbNodes ) +// { +// switch( theType ) +// { +// case SMDSAbs_0DElement: return VTK_VERTEX; + +// case SMDSAbs_Ball: return VTK_POLY_VERTEX; + +// case SMDSAbs_Edge: +// if( theNbNodes == 2 ) return VTK_LINE; +// else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE; +// else return VTK_EMPTY_CELL; + +// case SMDSAbs_Face : +// if (thePoly && theNbNodes>2 ) return VTK_POLYGON; +// else if ( theNbNodes == 3 ) return VTK_TRIANGLE; +// else if ( theNbNodes == 4 ) return VTK_QUAD; +// else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE; +// else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD; +// else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD; +// else if ( theNbNodes == 7 ) return VTK_BIQUADRATIC_TRIANGLE; +// else return VTK_EMPTY_CELL; + +// case SMDSAbs_Volume: +// if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET; +// else if ( theNbNodes == 4 ) return VTK_TETRA; +// else if ( theNbNodes == 5 ) return VTK_PYRAMID; +// else if ( theNbNodes == 6 ) return VTK_WEDGE; +// else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON; +// else if ( theNbNodes == 12 ) return VTK_HEXAGONAL_PRISM; +// else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA; +// else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON; +// else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON; +// else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE; +// else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET; +// else return VTK_EMPTY_CELL; + +// default: return VTK_EMPTY_CELL; +// } +// } + //================================================================================= // functions : SMESH_VisualObjDef // purpose : Constructor @@ -129,7 +178,7 @@ vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID ) if( this->GetMesh() ) { aNode = this->GetMesh()->FindNode(theObjID); } - return aNode ? aNode->GetVtkID() : -1; + return aNode ? aNode->getVtkId() : -1; } vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID ) @@ -139,7 +188,7 @@ vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID ) TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID); return i == myVTK2SMDSElems.end() ? -1 : i->second; } - return this->GetMesh()->FromVtkToSmds(theVTKID); + return this->GetMesh()->fromVtkToSmds(theVTKID); } vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID ) @@ -154,7 +203,7 @@ vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID ) if ( this->GetMesh() ) e = this->GetMesh()->FindElement(theObjID); - return e ? e->GetVtkID() : -1; + return e ? e->getVtkId() : -1; } //================================================================================= @@ -231,15 +280,15 @@ void SMESH_VisualObjDef::buildPrs(bool buildGrid) else { myLocalGrid = false; - if (!GetMesh()->IsCompacted()) + if (!GetMesh()->isCompacted()) { NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh() if ( MYDEBUG ) MESSAGE("*** buildPrs ==> compactMesh!"); - GetMesh()->CompactMesh(); + GetMesh()->compactMesh(); if ( SMESHDS_Mesh* m = dynamic_cast( GetMesh() )) // IPAL53915 m->GetScript()->SetModified(false); // drop IsModified set in compactMesh() } - vtkUnstructuredGrid *theGrid = GetMesh()->GetGrid(); + vtkUnstructuredGrid *theGrid = GetMesh()->getGrid(); updateEntitiesFlags(); myGrid->ShallowCopy(theGrid); //MESSAGE(myGrid->GetReferenceCount()); @@ -346,16 +395,17 @@ void SMESH_VisualObjDef::buildElemPrs() if((*anIter)->GetEntityType() != SMDSEntity_Polyhedra && (*anIter)->GetEntityType() != SMDSEntity_Quad_Polyhedra) { aCellsSize += (*anIter)->NbNodes() + 1; - } + } // Special case for the VTK_POLYHEDRON: // itsinput cellArray is of special format. - // [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] + // [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...] else { - if ( const SMDS_MeshVolume* ph = SMDS_Mesh::DownCast( *anIter )) { + if( const SMDS_VtkVolume* ph = dynamic_cast(*anIter) ) { int nbFaces = ph->NbFaces(); aCellsSize += (1 + ph->NbFaces()); - for( int i = 1; i <= nbFaces; i++ ) + for( int i = 1; i <= nbFaces; i++ ) { aCellsSize += ph->NbFaceNodes(i); + } } } } @@ -417,14 +467,16 @@ void SMESH_VisualObjDef::buildElemPrs() if (aType == SMDSAbs_Volume && anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE anIdList->Reset(); - if ( const SMDS_MeshVolume* ph = SMDS_Mesh::DownCast( anElem )) { + if ( const SMDS_VtkVolume* ph = dynamic_cast(anElem) ) { int nbFaces = ph->NbFaces(); anIdList->InsertNextId(nbFaces); for( int i = 1; i <= nbFaces; i++ ) { anIdList->InsertNextId(ph->NbFaceNodes(i)); for(int j = 1; j <= ph->NbFaceNodes(i); j++) { - if ( const SMDS_MeshNode* n = ph->GetFaceNode( i, j )) - anIdList->InsertNextId( mySMDS2VTKNodes[ n->GetID() ]); + const SMDS_MeshNode* n = ph->GetFaceNode(i,j); + if(n) { + anIdList->InsertNextId(mySMDS2VTKNodes[n->GetID()]); + } } } } @@ -452,8 +504,11 @@ void SMESH_VisualObjDef::buildElemPrs() //Store diameters of the balls if(aScalars) { double aDiam = 0; - if (const SMDS_BallElement* ball = SMDS_Mesh::DownCast(anElem) ) - aDiam = ball->GetDiameter(); + if(aType == SMDSAbs_Ball) { + if (const SMDS_BallElement* ball = dynamic_cast(anElem) ) { + aDiam = ball->GetDiameter(); + } + } aScalars->SetTuple(aCurId,&aDiam); } @@ -518,14 +573,14 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId, vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid() { - if ( !myLocalGrid && !GetMesh()->IsCompacted() ) + if ( !myLocalGrid && !GetMesh()->isCompacted() ) { - NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in CompactMesh() - GetMesh()->CompactMesh(); + NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh() + GetMesh()->compactMesh(); if ( SMESHDS_Mesh* m = dynamic_cast( GetMesh() )) // IPAL53915 - m->GetScript()->SetModified(false); // drop IsModified set in CompactMesh() + m->GetScript()->SetModified(false); // drop IsModified set in compactMesh() updateEntitiesFlags(); - vtkUnstructuredGrid *theGrid = GetMesh()->GetGrid(); + vtkUnstructuredGrid *theGrid = GetMesh()->getGrid(); myGrid->ShallowCopy(theGrid); } return myGrid; diff --git a/src/SMDS/CMakeLists.txt b/src/SMDS/CMakeLists.txt index d05091e4e..e46dbf829 100644 --- a/src/SMDS/CMakeLists.txt +++ b/src/SMDS/CMakeLists.txt @@ -42,72 +42,96 @@ SET(_link_LIBRARIES # header files / no moc processing SET(SMDS_HEADERS ObjectPool.hxx + SMDS_TypeOfPosition.hxx SMDSAbs_ElementType.hxx - SMDS_BallElement.hxx - SMDS_CellOfNodes.hxx - SMDS_Downward.hxx SMDS_EdgePosition.hxx SMDS_ElemIterator.hxx - SMDS_ElementFactory.hxx - SMDS_FaceOfNodes.hxx SMDS_FacePosition.hxx - SMDS_Iterator.hxx - SMDS_IteratorOnIterators.hxx - SMDS_LinearEdge.hxx SMDS_Mesh.hxx SMDS_Mesh0DElement.hxx - SMDS_MeshCell.hxx + SMDS_LinearEdge.hxx SMDS_MeshEdge.hxx SMDS_MeshElement.hxx + SMDS_MeshElementIDFactory.hxx + SMDS_MeshCell.hxx SMDS_MeshFace.hxx SMDS_MeshGroup.hxx - SMDS_MeshInfo.hxx + SMDS_MeshIDFactory.hxx SMDS_MeshNode.hxx + SMDS_MeshNodeIDFactory.hxx SMDS_MeshObject.hxx SMDS_MeshVolume.hxx - SMDS_PolygonalFaceOfNodes.hxx SMDS_Position.hxx - SMDS_SetIterator.hxx SMDS_SpacePosition.hxx - SMDS_StdIterator.hxx - SMDS_TypeOfPosition.hxx - SMDS_UnstructuredGrid.hxx SMDS_VertexPosition.hxx + SMDS_Iterator.hxx + SMDS_IteratorOfElements.hxx + SMDS_VolumeOfFaces.hxx SMDS_VolumeOfNodes.hxx - SMDS_VolumeTool.hxx + SMDS_VtkEdge.hxx + SMDS_VtkFace.hxx + SMDS_VtkVolume.hxx SMDS_VtkCellIterator.hxx - SMDS_ElementHolder.hxx + SMDS_PolyhedralVolumeOfNodes.hxx + SMDS_FaceOfEdges.hxx + SMDS_FaceOfNodes.hxx + SMDS_PolygonalFaceOfNodes.hxx + SMDS_VolumeTool.hxx + SMDS_QuadraticEdge.hxx + SMDS_QuadraticFaceOfNodes.hxx + SMDS_QuadraticVolumeOfNodes.hxx + SMDS_SetIterator.hxx SMESH_SMDS.hxx - chrono.hxx - ) + SMDS_MeshInfo.hxx + SMDS_UnstructuredGrid.hxx + SMDS_Downward.hxx + SMDS_StdIterator.hxx + SMDS_IteratorOnIterators.hxx + SMDS_BallElement.hxx +) # --- sources --- # sources / static SET(SMDS_SOURCES - SMDS_BallElement.cxx - SMDS_Downward.cxx - SMDS_CellOfNodes.cxx - SMDS_ElementFactory.cxx - SMDS_FaceOfNodes.cxx - SMDS_FacePosition.cxx - SMDS_LinearEdge.cxx - SMDS_MemoryLimit.cxx - SMDS_Mesh.cxx - SMDS_MeshCell.cxx + chrono.cxx + SMDS_MeshObject.cxx SMDS_MeshElement.cxx - SMDS_MeshGroup.cxx + SMDS_MeshCell.cxx + SMDS_Position.cxx + SMDS_EdgePosition.cxx + SMDS_FacePosition.cxx + SMDS_SpacePosition.cxx + SMDS_VertexPosition.cxx SMDS_MeshNode.cxx - SMDS_MeshObject.cxx + SMDS_Mesh0DElement.cxx + SMDS_LinearEdge.cxx + SMDS_MeshEdge.cxx + SMDS_MeshFace.cxx SMDS_MeshVolume.cxx - SMDS_PolygonalFaceOfNodes.cxx - SMDS_SpacePosition.cxx - SMDS_UnstructuredGrid.cxx + SMDS_MeshNodeIDFactory.cxx + SMDS_MeshElementIDFactory.cxx + SMDS_MeshGroup.cxx + SMDS_MeshIDFactory.cxx + SMDS_Mesh.cxx + SMDS_IteratorOfElements.cxx + SMDS_VolumeOfFaces.cxx SMDS_VolumeOfNodes.cxx - SMDS_VolumeTool.cxx + SMDS_VtkEdge.cxx + SMDS_VtkFace.cxx + SMDS_VtkVolume.cxx SMDS_VtkCellIterator.cxx - SMDS_ElementHolder.cxx - chrono.cxx + SMDS_PolyhedralVolumeOfNodes.cxx + SMDS_FaceOfEdges.cxx + SMDS_FaceOfNodes.cxx + SMDS_PolygonalFaceOfNodes.cxx + SMDS_VolumeTool.cxx + SMDS_QuadraticEdge.cxx + SMDS_QuadraticFaceOfNodes.cxx + SMDS_QuadraticVolumeOfNodes.cxx + SMDS_UnstructuredGrid.cxx + SMDS_Downward.cxx + SMDS_BallElement.cxx ) # bin programs diff --git a/src/SMDS/Notes b/src/SMDS/Notes new file mode 100644 index 000000000..830ffb5ae --- /dev/null +++ b/src/SMDS/Notes @@ -0,0 +1,235 @@ +--> Branche V6_main + +Problemes en cours +================== +- a faire ++ en cours, OK mais perfectible +* OK + ++ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK + creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident) +- inversion d'un volume (tetra): exception +- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente) ++ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?) + ==> purge systematique noeuds et cellules en trop dans compactage grid. ++ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif +- affichage des noeuds apres changement lineaire <--> quadratique à l'IHM : pas pris en compte, alors que maillage OK, + mais script OK + ==> cassé apres mode embedded ou elimination noeuds en trop ? +- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire) +- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1 + +A tester, non pris en compte +============================ +- engine standalone +- polyedres (attendre vtk) + + +=============================== Hypothese de refonte de l'API de SMDS + +n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid. +2987 usages de SMDS_MeshNodes +810 SMDS_MeshElement +... +==> en dernier ressort, lourd +================================================================================ + +Essai a API SMDS a peu pres constante +===================================== + +SMDS_Mesh + static vector _meshList; --> retrouver un SMDS_Mesh + vtkUnstructuredGrid* myGrid; + + vector myNodes; --> meme index que dans le pointSet de myGrid + vector myCells; --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk) + + + +SMDS_MeshElement + int myID; --> index dans la structure geree par SMDS_Mesh + int myMeshId; --> pour retrouver SMDS_Mesh* dans _meshList + int myShapeId; --> pour retrouver la subShape + + +SMDS_MeshNode: SMDS_MeshElement + SMDS_PositionPtr myPosition; --> A REVOIR : objet position dans la shape geom + ##vector myInverseElements; --> SUPPRIME : pour retrouver les elements, vtkCellLinks + + +SMDS_MeshCell: SMDS_MeshElement --> generique pour tous les elements (cells) + int myVtkID --> A SUPPRIMER + +SMDS_MeshVolume: SMDS_MeshCell + +SMDS_VolumeOfNodes: SMDS_MeshVolume --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool + const SMDS_MeshNode **myNodes; --> Couteux + int myNbNodes; --> "" + +SMDS_VolumeVtkNodes: SMDS_MeshVolume --> Utiliser systematiquement dans SMDS, + --> IMPLEMENTER. + + +SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory + vector myIDElements; // index = ID client, value = ID vtk --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory + vector myVtkIndex; // index = ID vtk, value = ID client --> A REPORTER dans SMDS_Mesh + + + + +========= TODO ============ + +enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory. + +ajouter ID dans SMDS_Mesh::createTriangle +verifier ID dans SMDS_Mesh::Find*OrCreate + +=================================================== +occupation memoire cube 100*100*100 sans affichage +NOTES: +- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes + avec une mesure externe globale(recherche du passage en swap du process). +- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?), + mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap. + + +Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo +------------------------------------- +Total (incl. mmap): +system bytes = 43757568 +in use bytes = 32909584 = 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 464670720 +in use bytes = 463105120 = 463M +max mmap regions = 47 +max mmap bytes = 28188672 + +Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M +----------------------------------- + +Total (incl. mmap): +system bytes = 52133888 +in use bytes = 41340320 : 41M +max mmap regions = 72 +max mmap bytes = 24625152 +---- +Total (incl. mmap): +system bytes = 520560640 +in use bytes = 518735584 : 512M +max mmap regions = 88 +max mmap bytes = 198385664 + +idem avec pool SMDS_MeshNodes --> 483 -33 = 450M +----------------------------- +Total (incl. mmap): +system bytes = 43696128 +in use bytes = 32915184 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 484806656 +in use bytes = 482980992 : 483M +max mmap regions = 58 +max mmap bytes = 184557568 + +idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx) +----------------------------------------- + +Total (incl. mmap): +system bytes = 43200512 +in use bytes = 32908576 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 478068736 +in use bytes = 475144400 : 475M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement SMDS_PositionPtr: (boost::shared_ptr --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position) +------------------------------------------------------------------------------------ +Total (incl. mmap): +system bytes = 45408256 +in use bytes = 35097680 : 35M +max mmap regions = 47 +max mmap bytes = 18116608 +---- +Total (incl. mmap): +system bytes = 438935552 +in use bytes = 436116560 : 436M +max mmap regions = 65 +max mmap bytes = 186437632 + +simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition) +---------------------------------------------------- +Total (incl. mmap): +system bytes = 42582016 +in use bytes = 32883552 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 421728256 +in use bytes = 418378000 : 418M +max mmap regions = 58 +max mmap bytes = 183640064 + +sizeof(SMDS_MeshElement) 16 +sizeof(SMDS_MeshNode) 24 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M +--------------------------------------------- + +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 --> on retrouve bien les 8M +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 43192320 +in use bytes = 32681088 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 429334528 +in use bytes = 426424576 : 426M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M +---------------------------------------------------------- +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 45404160 +in use bytes = 35132160 --> 35M +max mmap regions = 49 +max mmap bytes = 17723392 +---- +Total (incl. mmap): +system bytes = 349831168 +in use bytes = 346885424 --> 347M +max mmap regions = 73 +max mmap bytes = 204148736 + +Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire: +Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits) +Le meme avec V5.1.3 --> 14 Go (swap) + diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx index d7eea28c3..ef514b353 100644 --- a/src/SMDS/ObjectPool.hxx +++ b/src/SMDS/ObjectPool.hxx @@ -28,9 +28,9 @@ namespace { // assure deallocation of memory of a vector - template void clearVector(Y & v ) + template void clearVector(std::vector& v ) { - Y emptyVec; v.swap( emptyVec ); + std::vector emptyVec; v.swap( emptyVec ); } } diff --git a/src/SMDS/SMDS_BallElement.cxx b/src/SMDS/SMDS_BallElement.cxx index 7a10f79d3..fd3859681 100644 --- a/src/SMDS/SMDS_BallElement.cxx +++ b/src/SMDS/SMDS_BallElement.cxx @@ -24,24 +24,78 @@ #include "SMDS_BallElement.hxx" +#include "SMDS_ElemIterator.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_VtkCellIterator.hxx" -void SMDS_BallElement::init(const SMDS_MeshNode * node, double diameter ) +SMDS_BallElement::SMDS_BallElement() { - int nodeVtkID = node->GetVtkID(); - int vtkID = getGrid()->InsertNextLinkedCell( toVtkType( SMDSEntity_Ball ), 1, &nodeVtkID ); - setVtkID( vtkID ); - getGrid()->SetBallDiameter( GetVtkID(), diameter ); + SMDS_MeshCell::init(); +} + +SMDS_BallElement::SMDS_BallElement (const SMDS_MeshNode * node, double diameter) +{ + init( node->getVtkId(), diameter, SMDS_Mesh::_meshList[ node->getMeshId() ] ); +} + +SMDS_BallElement::SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh) +{ + init( nodeId, diameter, mesh ); +} + +void SMDS_BallElement::init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh) +{ + SMDS_MeshCell::init(); + myMeshId = mesh->getMeshId(); + myVtkID = mesh->getGrid()->InsertNextLinkedCell( GetVtkType(), 1, &nodeId ); + mesh->getGrid()->SetBallDiameter( myVtkID, diameter ); + mesh->setMyModified(); } double SMDS_BallElement::GetDiameter() const { - return getGrid()->GetBallDiameter( GetVtkID() ); + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetBallDiameter( myVtkID ); } void SMDS_BallElement::SetDiameter(double diameter) { - getGrid()->SetBallDiameter( GetVtkID(), diameter ); - GetMesh()->setMyModified(); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->SetBallDiameter( myVtkID, diameter ); +} + +bool SMDS_BallElement::ChangeNode (const SMDS_MeshNode * node) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + pts[0] = node->getVtkId(); + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +void SMDS_BallElement::Print (std::ostream & OS) const +{ + OS << "ball<" << GetID() << "> : "; } + +const SMDS_MeshNode* SMDS_BallElement::GetNode (const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ 0 ]); +} + +SMDS_ElemIteratorPtr SMDS_BallElement::elementsIterator (SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + diff --git a/src/SMDS/SMDS_BallElement.hxx b/src/SMDS/SMDS_BallElement.hxx index 4e7c6346e..c62034de7 100644 --- a/src/SMDS/SMDS_BallElement.hxx +++ b/src/SMDS/SMDS_BallElement.hxx @@ -27,23 +27,34 @@ #include "SMESH_SMDS.hxx" #include "SMDS_MeshCell.hxx" -/*! - * \brief Ball element. This type is not allocated. - * It is only used as function argument type to provide more clear semantic - * and to provide API specific to ball element - */ +#include + class SMDS_EXPORT SMDS_BallElement: public SMDS_MeshCell { - void init(const SMDS_MeshNode * node, double diameter); - - friend class SMDS_Mesh; - public: - + SMDS_BallElement(); + SMDS_BallElement (const SMDS_MeshNode * node, double diameter); + SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh); + void init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh); double GetDiameter() const; - void SetDiameter(double diameter); - - static SMDSAbs_ElementType Type() { return SMDSAbs_Ball; } + void SetDiameter(double diameter); + bool ChangeNode (const SMDS_MeshNode * node); + + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) { return ChangeNode( nodes[0] ); } + virtual void Print (std::ostream & OS) const; + + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Ball; } + virtual vtkIdType GetVtkType() const { return VTK_POLY_VERTEX; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Ball; } + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_BALL; } + virtual int NbNodes() const { return 1; } + virtual int NbEdges() const { return 0; } + virtual int NbFaces() const { return 0; } + virtual const SMDS_MeshNode* GetNode (const int ind) const; + + protected: + SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; }; #endif diff --git a/src/SMDS/SMDS_CellOfNodes.cxx b/src/SMDS/SMDS_CellOfNodes.cxx deleted file mode 100644 index bea007ff0..000000000 --- a/src/SMDS/SMDS_CellOfNodes.cxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 -// - -// SMESH SMDS : implementation of Salome mesh data structure -// - -#include "SMDS_CellOfNodes.hxx" - -SMDS_CellOfNodes::SMDS_CellOfNodes( int id, int shapeID ) - : myID( id ) -{ - setShapeID( shapeID ); -} - -void SMDS_CellOfNodes::setID(const int id) -{ - myID = id; -} - -int SMDS_CellOfNodes::GetID() const -{ - return myID; -} - -void SMDS_CellOfNodes::setShapeID( const int shapeID ) -{ - myShapeID = ( shapeID << BITS_SHIFT ) | ( myShapeID & BIT_IS_MARKED ); -} - -int SMDS_CellOfNodes::GetShapeID() const -{ - return myShapeID >> BITS_SHIFT; -} - -void SMDS_CellOfNodes::setIsMarked( bool is ) const -{ - const_cast< SMDS_CellOfNodes* >( this )->myShapeID = ( myShapeID & ~BIT_IS_MARKED ) | is; -} - -bool SMDS_CellOfNodes::isMarked() const -{ - return myShapeID & BIT_IS_MARKED; -} diff --git a/src/SMDS/SMDS_CellOfNodes.hxx b/src/SMDS/SMDS_CellOfNodes.hxx deleted file mode 100644 index 4880d0746..000000000 --- a/src/SMDS/SMDS_CellOfNodes.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 -// - -// SMESH SMDS : implementation of Salome mesh data structure -// File : SMDS_CellOfNodes.hxx -// Module : SMESH -// -#ifndef _SMDS_CellOfNodes_HeaderFile -#define _SMDS_CellOfNodes_HeaderFile - -#include "SMESH_SMDS.hxx" - -#include "SMDS_MeshElement.hxx" - -// ============================================================ -/*! - * \brief Base class for elements of not contained in the mesh - */ -// ============================================================ - - -class SMDS_EXPORT SMDS_CellOfNodes : public SMDS_MeshElement -{ -public: - - virtual int GetID() const; - virtual int GetShapeID() const; - - virtual void setIsMarked( bool is ) const; - virtual bool isMarked() const; - - virtual VTKCellType GetVtkType() const { return VTK_EMPTY_CELL; } - - protected: - - SMDS_CellOfNodes( int id = -1, int shapeID = 0); - - virtual void setID( const int id); - virtual void setShapeID( const int shapeID ); - - int myID; - int myShapeID; - - enum Bits { // use the 1st right bit of myShapeId to set/unset a mark - BIT_IS_MARKED = 1, - BITS_SHIFT = 1 - }; -}; -#endif diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx index 1955fa892..c4ead4dac 100644 --- a/src/SMDS/SMDS_Downward.cxx +++ b/src/SMDS/SMDS_Downward.cxx @@ -1145,7 +1145,7 @@ void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector& o return; } } - MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -1253,7 +1253,7 @@ void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -1387,7 +1387,7 @@ void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector& return; } } - MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -1531,7 +1531,7 @@ void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -1694,7 +1694,7 @@ void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector& o return; } } - MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -1845,7 +1845,7 @@ void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } @@ -2000,7 +2000,7 @@ void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector& or return; } } - MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]); @@ -2132,7 +2132,7 @@ void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector return; } } - MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); } diff --git a/src/SMDS/SMDS_EdgePosition.cxx b/src/SMDS/SMDS_EdgePosition.cxx new file mode 100644 index 000000000..9ac728d64 --- /dev/null +++ b/src/SMDS/SMDS_EdgePosition.cxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_EdgePosition.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#include "SMDS_EdgePosition.hxx" + +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_EdgePosition +//purpose : +//======================================================================= + +SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam) +{ + //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter); +} + +/** +*/ +SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const +{ + //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition"); + return SMDS_TOP_EDGE; +} + +void SMDS_EdgePosition::SetUParameter(double aUparam) +{ + //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam); + myUParameter = aUparam; +} + +//======================================================================= +//function : GetUParameter +//purpose : +//======================================================================= + +double SMDS_EdgePosition::GetUParameter() const +{ + //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter); + return myUParameter; +} diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx index e2c9cf19e..f0870e970 100644 --- a/src/SMDS/SMDS_EdgePosition.hxx +++ b/src/SMDS/SMDS_EdgePosition.hxx @@ -31,19 +31,18 @@ #include "SMDS_Position.hxx" -class SMDS_EXPORT SMDS_EdgePosition : public SMDS_Position +class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position { - public: - SMDS_EdgePosition(const double aUParam=0) : myUParameter( aUParam ) {} - virtual SMDS_TypeOfPosition GetTypeOfPosition() const { return SMDS_TOP_EDGE; } - virtual void SetUParameter(double aUparam) { myUParameter = aUparam; } - virtual double GetUParameter() const { return myUParameter; } - virtual const double* GetParameters() const { return &myUParameter; } + public: + SMDS_EdgePosition(const double aUParam=0); + SMDS_TypeOfPosition GetTypeOfPosition() const; + void SetUParameter(double aUparam); + double GetUParameter() const; - private: + private: - double myUParameter; + double myUParameter; }; diff --git a/src/SMDS/SMDS_ElementFactory.cxx b/src/SMDS/SMDS_ElementFactory.cxx deleted file mode 100644 index a6d61e849..000000000 --- a/src/SMDS/SMDS_ElementFactory.cxx +++ /dev/null @@ -1,880 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 : SMDS_ElementFactory.cxx -// Module : SMESH -// - -#include "SMDS_ElementFactory.hxx" - -#include "ObjectPool.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" -#include "SMDS_Mesh.hxx" -#include "SMDS_SpacePosition.hxx" -#include "SMDS_VertexPosition.hxx" - -namespace -{ - // nb of elements allocated by SMDS_ElementChunk at once - const int theChunkSize = 1024; - - const int theDefaultShapeDim = 3; - - // classes allowing to modify parameters of SMDS_Position stored in SMDS_ElementFactory - - struct _EdgePosition : public SMDS_EdgePosition - { - TParam* myUParameter; - - _EdgePosition( TParam* aUParam ) : myUParameter( aUParam ) - { SMDS_EdgePosition::SetUParameter( aUParam[0]); } - virtual void SetUParameter(double aUparam) - { *myUParameter = (TParam) aUparam; SMDS_EdgePosition::SetUParameter( aUparam ); } - }; - - struct _FacePosition : public SMDS_FacePosition - { - TParam* myParameter; - - _FacePosition(TParam* aParam) : myParameter( aParam ) - { SMDS_FacePosition::SetParameters( aParam[0], aParam[1] ); } - virtual void SetUParameter(double aUparam) - { myParameter[0] = (TParam) aUparam; SMDS_FacePosition::SetUParameter( aUparam ); } - virtual void SetVParameter(double aVparam) - { myParameter[1] = (TParam) aVparam; SMDS_FacePosition::SetVParameter( aVparam ); } - virtual void SetParameters(double aU, double aV) - { myParameter[0] = aU; myParameter[1] = aV; SMDS_FacePosition::SetParameters( aU, aV ); } - }; -} - -//================================================================================ -/*! - * \brief Create a factory of cells or nodes in a given mesh - */ -//================================================================================ - -SMDS_ElementFactory::SMDS_ElementFactory( SMDS_Mesh* mesh, const bool isNodal ) - : myIsNodal( isNodal ), myMesh( mesh ), myNbUsedElements( 0 ) -{ -} - -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SMDS_ElementFactory::~SMDS_ElementFactory() -{ - myChunksWithUnused.clear(); - myChunks.clear(); -} - -//================================================================================ -/*! - * \brief Return a number of elements in a chunk - * \return int - chunk size - */ -//================================================================================ - -int SMDS_ElementFactory::ChunkSize() -{ - return theChunkSize; -} - -//================================================================================ -/*! - * \brief Return minimal ID of a non-used element - * \return int - minimal element ID - */ -//================================================================================ - -int SMDS_ElementFactory::GetFreeID() -{ - if ( myChunksWithUnused.empty() ) - { - int id0 = myChunks.size() * theChunkSize + 1; - myChunks.push_back( new SMDS_ElementChunk( this, id0 )); - } - SMDS_ElementChunk * chunk = (*myChunksWithUnused.begin()); - return chunk->GetUnusedID(); -} - -//================================================================================ -/*! - * \brief Return maximal ID of an used element - * \return int - element ID - */ -//================================================================================ - -int SMDS_ElementFactory::GetMaxID() -{ - int id = 0; - TIndexRanges usedRanges; - for ( int i = myChunks.size() - 1; i >= 0; --i ) - if ( myChunks[i].GetUsedRanges().GetIndices( true, usedRanges )) - { - int index = usedRanges.back().second-1; - id = myChunks[i].Get1stID() + index; - break; - } - return id; -} - -//================================================================================ -/*! - * \brief Return minimal ID of an used element - * \return int - element ID - */ -//================================================================================ - -int SMDS_ElementFactory::GetMinID() -{ - int id = 0; - TIndexRanges usedRanges; - for ( size_t i = 0; i < myChunks.size(); ++i ) - if ( myChunks[i].GetUsedRanges().GetIndices( true, usedRanges )) - { - int index = usedRanges[0].first; - id = myChunks[i].Get1stID() + index; - break; - } - return id; -} - -//================================================================================ -/*! - * \brief Return an element by ID. NULL if the element with the given ID is already used - * \param [in] id - element ID - * \return SMDS_MeshElement* - element pointer - */ -//================================================================================ - -SMDS_MeshElement* SMDS_ElementFactory::NewElement( const int id ) -{ - int iChunk = ( id - 1 ) / theChunkSize; - int index = ( id - 1 ) % theChunkSize; - while ((int) myChunks.size() <= iChunk ) - { - int id0 = myChunks.size() * theChunkSize + 1; - myChunks.push_back( new SMDS_ElementChunk( this, id0 )); - } - SMDS_MeshElement* e = myChunks[iChunk].Element( index ); - if ( !e->IsNull() ) - return 0; // element with given ID already exists - - myChunks[iChunk].UseElement( index ); - ++myNbUsedElements; - - e->myHolder = & myChunks[iChunk]; - - myMesh->setMyModified(); - - return e; -} - -//================================================================================ -/*! - * \brief Return an used element by ID. NULL if the element with the given ID is not yet used - * \param [in] id - element ID - * \return const SMDS_MeshElement* - element pointer - */ -//================================================================================ - -const SMDS_MeshElement* SMDS_ElementFactory::FindElement( const int id ) const -{ - if ( id > 0 ) - { - int iChunk = ( id - 1 ) / theChunkSize; - int index = ( id - 1 ) % theChunkSize; - if ( iChunk < (int) myChunks.size() ) - { - const SMDS_MeshElement* e = myChunks[iChunk].Element( index ); - return e->IsNull() ? 0 : e; - } - } - return 0; -} - -//================================================================================ -/*! - * \brief Return an SMDS ID by a Vtk one - * \param [inout] vtkID - Vtk ID - * \return int - SMDS ID - */ -//================================================================================ - -int SMDS_ElementFactory::FromVtkToSmds( vtkIdType vtkID ) -{ - if ( vtkID >= 0 && vtkID < (vtkIdType)mySmdsIDs.size() ) - return mySmdsIDs[vtkID] + 1; - return vtkID + 1; -} - -//================================================================================ -/*! - * \brief Mark the element as non-used - * \param [in] e - element - */ -//================================================================================ - -void SMDS_ElementFactory::Free( const SMDS_MeshElement* e ) -{ - if ( !myVtkIDs.empty() ) - { - size_t id = e->GetID() - 1; - size_t vtkID = e->GetVtkID(); - if ( id < myVtkIDs.size() ) - myVtkIDs[ id ] = -1; - if ( vtkID < mySmdsIDs.size() ) - mySmdsIDs[ vtkID ] = -1; - } - e->myHolder->Free( e ); - const_cast< SMDS_MeshElement*>( e )->myHolder = 0; - --myNbUsedElements; - - myMesh->setMyModified(); -} - -//================================================================================ -/*! - * \brief De-allocate all elements - */ -//================================================================================ - -void SMDS_ElementFactory::Clear() -{ - myChunksWithUnused.clear(); - clearVector( myChunks ); - clearVector( myVtkIDs ); - clearVector( mySmdsIDs ); - myNbUsedElements = 0; -} - -//================================================================================ -/*! - * \brief Remove unused elements located not at the end of the last chunk. - * Minimize allocated memory - * \param [out] theVtkIDsNewToOld - theVtkIDsNewToOld[ new VtkID ] = old VtkID - */ -//================================================================================ - -void SMDS_ElementFactory::Compact( std::vector& theVtkIDsNewToOld ) -{ - int newNbCells = NbUsedElements(); - int maxCellID = GetMaxID(); - int newNbChunks = newNbCells / theChunkSize + bool ( newNbCells % theChunkSize ); - - theVtkIDsNewToOld.resize( newNbCells ); - - if ( newNbCells == 0 ) // empty mesh - { - clearVector( myChunks ); - } - else if ( newNbCells == maxCellID ) // no holes - { - int newID, minLastID = std::min( myVtkIDs.size(), theVtkIDsNewToOld.size() ); - for ( newID = 0; newID < minLastID; ++newID ) - theVtkIDsNewToOld[ newID ] = myVtkIDs[ newID ]; - for ( ; newID < newNbCells; ++newID ) - theVtkIDsNewToOld[ newID ] = newID; - } - else // there are holes in SMDS IDs - { - int newVtkID = 0; // same as new smds ID (-1) - for ( int oldID = 1; oldID <= maxCellID; ++oldID ) // smds IDs - { - const SMDS_MeshElement* oldElem = FindElement( oldID ); - if ( !oldElem ) continue; - theVtkIDsNewToOld[ newVtkID++ ] = oldElem->GetVtkID(); // now newVtkID == new smds ID - if ( oldID != newVtkID ) - { - const SMDS_MeshElement* newElem = FindElement( newVtkID ); - if ( !newElem ) - newElem = NewElement( newVtkID ); - if ( int shapeID = oldElem->GetShapeID() ) - const_cast< SMDS_MeshElement* >( newElem )->setShapeID( shapeID ); - if ( oldID > newNbCells ) - Free( oldElem ); - } - } - } - myChunks.resize( newNbChunks ); - - myChunksWithUnused.clear(); - if ( !myChunks.empty() && myChunks.back().GetUsedRanges().Size() > 1 ) - myChunksWithUnused.insert( & myChunks.back() ); - - for ( size_t i = 0; i < myChunks.size(); ++i ) - myChunks[i].Compact(); - - clearVector( myVtkIDs ); - clearVector( mySmdsIDs ); -} - - -//================================================================================ -/*! - * \brief Return true if Compact() will change IDs of elements - */ -//================================================================================ - -bool SMDS_ElementFactory::CompactChangePointers() -{ - // there can be VTK_EMPTY_CELL's in the VTK grid as well as "holes" in SMDS numeration - return ( NbUsedElements() != GetMaxID() ); -} - -//================================================================================ -/*! - * \brief Create a factory of nodes in a given mesh - */ -//================================================================================ - -SMDS_NodeFactory::SMDS_NodeFactory( SMDS_Mesh* mesh ) - : SMDS_ElementFactory( mesh, /*isNodal=*/true ) -{ -} - -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SMDS_NodeFactory::~SMDS_NodeFactory() -{ - Clear(); -} - -//================================================================================ -/*! - * \brief Remove unused nodes located not at the end of the last chunk. - * Minimize allocated memory - * \param [out] theVtkIDsOldToNew - vector storing change of vtk IDs - */ -//================================================================================ - -void SMDS_NodeFactory::Compact( std::vector& theVtkIDsOldToNew ) -{ - // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes" - // in the chunks. So we remove holes and report relocation in theVtkIDsOldToNew: - // theVtkIDsOldToNew[ old VtkID ] = new VtkID - - int oldNbNodes = myMesh->GetGrid()->GetNumberOfPoints(); - int newNbNodes = NbUsedElements(); - int newNbChunks = newNbNodes / theChunkSize + bool ( newNbNodes % theChunkSize ); - int maxNodeID = GetMaxID(); - - theVtkIDsOldToNew.resize( oldNbNodes, -1 ); - - if ( newNbNodes == 0 ) // empty mesh - { - clearVector( myChunks ); - } - else if ( maxNodeID > newNbNodes ) // there are holes - { - size_t newID = 0; - for ( size_t oldID = 0; oldID < theVtkIDsOldToNew.size(); ++oldID ) - { - const SMDS_MeshElement* oldNode = FindNode( oldID+1 ); - if ( !oldNode ) - continue; - theVtkIDsOldToNew[ oldID ] = newID; - if ( oldID != newID ) - { - const SMDS_MeshElement* newNode = FindElement( newID+1 ); - if ( !newNode ) - newNode = NewElement( newID+1 ); - int shapeID = oldNode->GetShapeID(); - int shapeDim = GetShapeDim( shapeID ); - int iChunk = newID / theChunkSize; - myChunks[ iChunk ].SetShapeID( newNode, shapeID ); - if ( shapeDim == 2 || shapeDim == 1 ) - { - int iChunkOld = oldID / theChunkSize; - TParam* oldPos = myChunks[ iChunkOld ].GetPositionPtr( oldNode ); - TParam* newPos = myChunks[ iChunk ].GetPositionPtr( newNode, /*allocate=*/true ); - if ( oldPos ) - { - newPos[0] = oldPos[0]; - newPos[1] = oldPos[1]; - } - } - if ( oldNode->GetID() > newNbNodes ) - Free( oldNode ); - } - ++newID; - } - } - else // no holes - { - for ( int i = 0; i < newNbNodes; ++i ) - theVtkIDsOldToNew[ i ] = i; - } - myChunks.resize( newNbChunks ); - - myChunksWithUnused.clear(); - if ( !myChunks.empty() && myChunks.back().GetUsedRanges().Size() > 1 ) - myChunksWithUnused.insert( & myChunks.back() ); - - for ( size_t i = 0; i < myChunks.size(); ++i ) - myChunks[i].Compact(); - - ASSERT( newNbNodes == GetMaxID() ); - ASSERT( newNbNodes == NbUsedElements() ); -} - -//================================================================================ -/*! - * \brief Return true if Compact() will change IDs of elements - */ -//================================================================================ - -bool SMDS_NodeFactory::CompactChangePointers() -{ - // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes" in SMDS numeration - return ( NbUsedElements() != GetMaxID() ); -} - -//================================================================================ -/*! - * \brief De-allocate all nodes - */ -//================================================================================ - -void SMDS_NodeFactory::Clear() -{ - SMDS_ElementFactory::Clear(); -} - -//================================================================================ -/*! - * \brief Set a total number of sub-shapes in the main shape - */ -//================================================================================ - -void SMDS_NodeFactory::SetNbShapes( size_t nbShapes ) -{ - clearVector( myShapeDim ); - myShapeDim.resize( nbShapes+1, theDefaultShapeDim ); -} - -//================================================================================ -/*! - * \brief Return a dimension of a shape - */ -//================================================================================ - -int SMDS_NodeFactory::GetShapeDim( int shapeID ) const -{ - return shapeID < (int)myShapeDim.size() ? myShapeDim[ shapeID ] : theDefaultShapeDim; -} - -//================================================================================ -/*! - * \brief Set a dimension of a shape - */ -//================================================================================ - -void SMDS_NodeFactory::SetShapeDim( int shapeID, int dim ) -{ - if ( shapeID >= (int)myShapeDim.size() ) - myShapeDim.resize( shapeID + 10, theDefaultShapeDim ); - myShapeDim[ shapeID ] = dim; -} - -//================================================================================ -/*! - * \brief SMDS_ElementChunk constructor - * \param [in] factory - the factory - * \param [in] id0 - ID of the 1st element - */ -//================================================================================ - -SMDS_ElementChunk::SMDS_ElementChunk( SMDS_ElementFactory* factory, int id0 ): - myFactory( factory ), - my1stID( id0 ), - myMinSubID( std::numeric_limits::max() ), - myMaxSubID( 0 ) -{ - if ( !myFactory ) - return; - if ( myFactory->myIsNodal ) - myElements = new SMDS_MeshNode[ theChunkSize ]; - else - myElements = new SMDS_MeshCell[ theChunkSize ]; - - myUsedRanges.mySet.reserve(2); - mySubIDRanges.mySet.insert( _ShapeIDRange( 0, 0 )); - myUsedRanges.mySet.insert( _UsedRange( 0, false )); - myFactory->myChunksWithUnused.insert( this ); -} - -//================================================================================ -/*! - * \brief SMDS_ElementChunk destructor - */ -//================================================================================ - -SMDS_ElementChunk::~SMDS_ElementChunk() -{ - delete [] myElements; - myFactory->myChunksWithUnused.erase( this ); -} - -//================================================================================ -/*! - * \brief Mark an element as used - */ -//================================================================================ - -void SMDS_ElementChunk::UseElement( const int index ) -{ - myUsedRanges.SetValue( index, true ); - if ( myUsedRanges.Size() == 1 ) // all elements used - myFactory->myChunksWithUnused.erase( this ); -} - -//================================================================================ -/*! - * \brief Return ID of the first non-used element - */ -//================================================================================ - -int SMDS_ElementChunk::GetUnusedID() const -{ - TUsedRangeSet::set_iterator r = myUsedRanges.mySet.begin(); - for ( ; r != myUsedRanges.mySet.end(); ++r ) - if ( !IsUsed( *r )) - break; - - return my1stID + r->my1st; -} - -//================================================================================ -/*! - * \brief Mark an element as non-used - */ -//================================================================================ - -void SMDS_ElementChunk::Free( const SMDS_MeshElement* e ) -{ - bool hasHoles = ( myUsedRanges.Size() > 1 ); - myUsedRanges.SetValue( Index( e ), false ); - SetShapeID( e, 0 ); // sub-mesh must do it? - SetIsMarked( e, false ); - if ( !hasHoles ) - myFactory->myChunksWithUnused.insert( this ); - - if ( myUsedRanges.Size() == 1 ) - { - clearVector( myMarkedSet ); - clearVector( myPositions ); - } -} - -//================================================================================ -/*! - * \brief Return an SMDS ID of an element - */ -//================================================================================ - -int SMDS_ElementChunk::GetID( const SMDS_MeshElement* e ) const -{ - return my1stID + Index( e ); -} - -//================================================================================ -/*! - * \brief Set a Vtk ID of an element - */ -//================================================================================ - -void SMDS_ElementChunk::SetVTKID( const SMDS_MeshElement* e, const vtkIdType vtkID ) -{ - if ( e->GetID() - 1 != vtkID ) - { - if ((int) myFactory->myVtkIDs.size() <= e->GetID() - 1 ) - { - size_t i = myFactory->myVtkIDs.size(); - myFactory->myVtkIDs.resize( e->GetID() + 100 ); - for ( ; i < myFactory->myVtkIDs.size(); ++i ) - myFactory->myVtkIDs[i] = i; - } - myFactory->myVtkIDs[ e->GetID() - 1 ] = vtkID; - - if ((vtkIdType) myFactory->mySmdsIDs.size() <= vtkID ) - { - size_t i = myFactory->mySmdsIDs.size(); - myFactory->mySmdsIDs.resize( vtkID + 100 ); - for ( ; i < myFactory->mySmdsIDs.size(); ++i ) - myFactory->mySmdsIDs[i] = i; - } - myFactory->mySmdsIDs[ vtkID ] = e->GetID() - 1; - } -} - -//================================================================================ -/*! - * \brief Return a Vtk ID of an element - */ -//================================================================================ - -int SMDS_ElementChunk::GetVtkID( const SMDS_MeshElement* e ) const -{ - size_t dfltVtkID = e->GetID() - 1; - return ( dfltVtkID < myFactory->myVtkIDs.size() ) ? myFactory->myVtkIDs[ dfltVtkID ] : dfltVtkID; -} - -//================================================================================ -/*! - * \brief Return ID of a shape an element is assigned to - */ -//================================================================================ - -int SMDS_ElementChunk::GetShapeID( const SMDS_MeshElement* e ) const -{ - return mySubIDRanges.GetValue( Index( e )); -} - -//================================================================================ -/*! - * \brief Set ID of a shape an element is assigned to - */ -//================================================================================ - -void SMDS_ElementChunk::SetShapeID( const SMDS_MeshElement* e, int shapeID ) const -{ - const size_t nbRanges = mySubIDRanges.Size(); - - SMDS_ElementChunk* me = const_cast( this ); - int oldShapeID = me->mySubIDRanges.SetValue( Index( e ), shapeID ); - if ( oldShapeID == shapeID ) return; - - if ( const SMDS_MeshNode* n = dynamic_cast< const SMDS_MeshNode* >( e )) - if ( TParam* uv = me->GetPositionPtr( n )) - { - uv[0] = 0.; - uv[1] = 0.; - } - // update min/max - if (( nbRanges > mySubIDRanges.Size() ) && - ( myMinSubID == oldShapeID || myMaxSubID == oldShapeID )) - { - me->myMinSubID = ( std::numeric_limits::max() ); - me->myMaxSubID = 0; - TSubIDRangeSet::set_iterator it; - for ( it = mySubIDRanges.mySet.begin(); it < mySubIDRanges.mySet.end(); ++it ) - if ( it->myValue > 0 ) - { - me->myMinSubID = std::min( myMinSubID, it->myValue ); - me->myMaxSubID = std::max( myMaxSubID, it->myValue ); - } - } - else if ( shapeID > 0 ) - { - me->myMinSubID = std::min( myMinSubID, shapeID ); - me->myMaxSubID = std::max( myMaxSubID, shapeID ); - } -} - -//================================================================================ -/*! - * \brief Set isMarked flag of an element - */ -//================================================================================ - -bool SMDS_ElementChunk::IsMarked( const SMDS_MeshElement* e ) const -{ - return ( !myMarkedSet.empty() && myMarkedSet[ Index( e )]); -} - -//================================================================================ -/*! - * \brief Return isMarked flag of an element - */ -//================================================================================ - -void SMDS_ElementChunk::SetIsMarked( const SMDS_MeshElement* e, bool is ) -{ - if ( !is && myMarkedSet.empty() ) return; - if ( myMarkedSet.empty() ) myMarkedSet.resize( theChunkSize, false ); - myMarkedSet[ Index( e )] = is; -} - -//================================================================================ -/*! - * \brief Return SMDS_Position of a node on a shape - */ -//================================================================================ - -SMDS_PositionPtr SMDS_ElementChunk::GetPosition( const SMDS_MeshNode* n ) const -{ - int shapeID = GetShapeID( n ); - int shapeDim = static_cast< SMDS_NodeFactory* >( myFactory )->GetShapeDim( shapeID ); - - SMDS_ElementChunk* me = const_cast< SMDS_ElementChunk* >( this ); - - switch ( shapeDim ) { - case 2: - { - return SMDS_PositionPtr( new _FacePosition( me->GetPositionPtr( n ))); - } - case 1: - { - return SMDS_PositionPtr( new _EdgePosition( me->GetPositionPtr( n ))); - } - case 0: - return SMDS_VertexPosition::StaticPosition(); - } - - return SMDS_SpacePosition::originSpacePosition(); -} - -//================================================================================ -/*! - * \brief Set SMDS_Position of a node on a shape - */ -//================================================================================ - -void SMDS_ElementChunk::SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID ) -{ - int shapeDim = pos ? pos->GetDim() : theDefaultShapeDim; - if ( shapeID < 1 ) - { - if ( shapeDim == theDefaultShapeDim ) - return; - shapeID = GetShapeID( n ); - if ( shapeID < 1 ) - throw SALOME_Exception("SetPosition() No shape ID provided"); - } - - static_cast< SMDS_NodeFactory* >( myFactory )->SetShapeDim( shapeID, shapeDim ); - - switch ( shapeDim ) { - case 2: - { - TParam* uv = GetPositionPtr( n, /*allocate=*/true ); - uv[0] = (TParam) pos->GetParameters()[0]; - uv[1] = (TParam) pos->GetParameters()[1]; - break; - } - case 1: - { - GetPositionPtr( n, /*allocate=*/true )[0] = (TParam) pos->GetParameters()[0]; - break; - } - } -} - -//================================================================================ -/*! - * \brief Return pointer to on-shape-parameters of a node - */ -//================================================================================ - -TParam* SMDS_ElementChunk::GetPositionPtr( const SMDS_MeshElement* n, bool allocate ) -{ - if ( myPositions.empty() && !allocate ) - return 0; - - myPositions.resize( theChunkSize * 2 ); - return myPositions.data() + 2 * Index( n ); -} - -//================================================================================ -/*! - * \brief Minimize allocated memory - */ -//================================================================================ - -void SMDS_ElementChunk::Compact() -{ - mySubIDRanges.mySet.shrink_to_fit(); - if ( myUsedRanges.mySet.capacity() > 2 ) - myUsedRanges.mySet.shrink_to_fit(); - - clearVector( myMarkedSet ); - - if ( !myPositions.empty() ) - { - // look for the last position that must be kept - TSubIDRangeSet::set_t::reverse_iterator it; - for ( it = mySubIDRanges.mySet.rbegin(); it != mySubIDRanges.mySet.rend(); ++it ) - { - int shapeDim = static_cast< SMDS_NodeFactory* >( myFactory )->GetShapeDim( it->myValue ); - if ( shapeDim == 1 || shapeDim == 2 ) - break; - } - if ( it == mySubIDRanges.mySet.rend() ) - { - clearVector( myPositions ); - } - else if ( it != mySubIDRanges.mySet.rbegin() ) - { - int nbNodes = (it-1)->my1st; - myPositions.resize( nbNodes * 2 ); - std::vector newPos( myPositions.begin(), myPositions.end() ); - myPositions.swap( newPos ); - } - } -} - -//================================================================================ -/*! - * \brief Print some data for debug purposes - */ -//================================================================================ - -void SMDS_ElementChunk::Dump() const -{ - std::cout << "1stID: " << my1stID << std::endl; - - std::cout << "SubID min/max: " << myMinSubID << ", " << myMaxSubID << std::endl; - std::cout << "SubIDRanges: " << mySubIDRanges.Size() << " "; - { - TSubIDRangeSet::set_iterator i = mySubIDRanges.mySet.begin(); - for ( int cnt = 0; i != mySubIDRanges.mySet.end(); ++i, ++cnt ) - std::cout << "|" << cnt << " - (" << i->my1st << ", " << i->myValue << ") "; - std::cout << std::endl; - } - { - std::cout << "UsedRanges: " << myUsedRanges.Size() << " "; - TUsedRangeSet::set_iterator i = myUsedRanges.mySet.begin(); - for ( int cnt = 0; i != myUsedRanges.mySet.end(); ++i, ++cnt ) - std::cout << cnt << " - (" << i->my1st << ", " << i->myValue << ") "; - std::cout << std::endl; - } -} - -//================================================================================ -/*! - * \brief Compare SMDS_ElementChunk's - */ -//================================================================================ - -bool _ChunkCompare::operator () (const SMDS_ElementChunk* e1, const SMDS_ElementChunk* e2) const -{ - return e1->Get1stID() < e2->Get1stID(); -} - diff --git a/src/SMDS/SMDS_ElementFactory.hxx b/src/SMDS/SMDS_ElementFactory.hxx deleted file mode 100644 index b25b635c8..000000000 --- a/src/SMDS/SMDS_ElementFactory.hxx +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 : SMDS_ElementFactory.hxx -// Module : SMESH -// -#ifndef _SMDS_ElementFactory_HeaderFile -#define _SMDS_ElementFactory_HeaderFile - -#include "SMDS_MeshCell.hxx" -#include "SMDS_Position.hxx" - -#include - -#include -#include -#include -#include -#include - -#include - -#include - -class SMDS_ElementChunk; -class SMDS_Mesh; -class SMDS_MeshCell; -class SMDS_MeshNode; - -struct _ChunkCompare { - bool operator () (const SMDS_ElementChunk* c1, const SMDS_ElementChunk* c2) const; -}; -typedef boost::ptr_vector TChunkVector; -typedef std::set TChunkPtrSet; - -//------------------------------------------------------------------------------------ -/*! - * \brief Allocate SMDS_MeshElement's (SMDS_MeshCell's or SMDS_MeshNode's ) - * and bind some attributes to elements: - * element ID, element VTK ID, sub-mesh ID, position on shape. - * - * Elements are allocated by chunks, so there are used and non-used elements - */ -class SMDS_ElementFactory -{ -protected: - bool myIsNodal; // what to allocate: nodes or cells - SMDS_Mesh* myMesh; - TChunkVector myChunks; // array of chunks of elements - TChunkPtrSet myChunksWithUnused; // sorted chunks having unused elements - std::vector< vtkIdType > myVtkIDs; // myVtkIDs[ smdsID-1 ] == vtkID - std::vector< int > mySmdsIDs; // mySmdsIDs[ vtkID ] == smdsID - 1 - int myNbUsedElements; // counter of elements - - friend class SMDS_ElementChunk; - -public: - - SMDS_ElementFactory( SMDS_Mesh* mesh, const bool isNodal=false ); - virtual ~SMDS_ElementFactory(); - - //! Return minimal ID of a non-used element - int GetFreeID(); - - //! Return maximal ID of an used element - int GetMaxID(); - - //! Return minimal ID of an used element - int GetMinID(); - - //! Return an element by ID. NULL if the element with the given ID is already used - SMDS_MeshElement* NewElement( const int id ); - - //! Return a SMDS_MeshCell by ID. NULL if the cell with the given ID is already used - SMDS_MeshCell* NewCell( const int id ) { return static_cast( NewElement( id )); } - - //! Return an used element by ID. NULL if the element with the given ID is not yet used - const SMDS_MeshElement* FindElement( const int id ) const; - - //! Return a number of used elements - int NbUsedElements() const { return myNbUsedElements; } - - //! Return an iterator on all element filtered using a given filter. - // nbElemsToReturn is used to optimize by stopping the iteration as soon as - // all elements satisfying filtering condition encountered. - template< class ElemIterator > - boost::shared_ptr< ElemIterator > GetIterator( SMDS_MeshElement::Filter* filter, - size_t nbElemsToReturn = -1 ); - - //! Return an iterator on all element assigned to a given shape. - // nbElemsToReturn is used to optimize by stopping the iteration as soon as - // all elements assigned to the shape encountered. - template< class ElemIterator > - boost::shared_ptr< ElemIterator > GetShapeIterator( int shapeID, size_t nbElemsToReturn ); - - //! Mark the element as non-used - void Free( const SMDS_MeshElement* ); - - //! Return an SMDS ID by a Vtk one - int FromVtkToSmds( vtkIdType vtkID ); - - //! De-allocate all elements - virtual void Clear(); - - //! Remove unused elements located not at the end of the last chunk. - // Minimize allocated memory - virtual void Compact(std::vector& idCellsOldToNew); - - //! Return true if Compact() will change IDs of elements - virtual bool CompactChangePointers(); - - //! Return a number of elements in a chunk - static int ChunkSize(); -}; - -//------------------------------------------------------------------------------------ -/*! - * \brief Allocate SMDS_MeshNode's - */ -class SMDS_NodeFactory : public SMDS_ElementFactory -{ - std::vector myShapeDim; // dimension of shapes - -public: - - SMDS_NodeFactory( SMDS_Mesh* mesh ); - ~SMDS_NodeFactory(); - - //! Return a SMDS_MeshNode by ID. NULL if the node with the given ID is already used - SMDS_MeshNode* NewNode( int id ) { return (SMDS_MeshNode*) NewElement(id); } - - //! Return an used node by ID. NULL if the node with the given ID is not yet used - const SMDS_MeshNode* FindNode( int id ) { return (const SMDS_MeshNode*) FindElement(id); } - - //! Set a total number of sub-shapes in the main shape - void SetNbShapes( size_t nbShapes ); - - //! Return a dimension of a shape - int GetShapeDim( int shapeID ) const; - - //! Set a dimension of a shape - void SetShapeDim( int shapeID, int dim ); - - //! De-allocate all nodes - virtual void Clear(); - - //! Remove unused nodes located not at the end of the last chunk. - // Minimize allocated memory - virtual void Compact(std::vector& idNodesOldToNew); - - //! Return true if Compact() will change IDs of node - virtual bool CompactChangePointers(); -}; - -//------------------------------------------------------------------------------------ -/*! - * \brief Range of elements in a chunk having the same attribute value - */ -template< typename ATTR> -struct _Range -{ - typedef ATTR attr_t; - - attr_t myValue; // common attribute value - int my1st; // index in the chunk of the 1st element - _Range( int i0 = 0, attr_t v = 0 ): myValue( v ), my1st( i0 ) {} - - bool operator < (const _Range& other) const { return my1st < other.my1st; } -}; - -typedef std::vector< std::pair< int, int > > TIndexRanges; - -//------------------------------------------------------------------------------------ -/*! - * \brief Sorted set of ranges - */ -template< class RANGE > -struct _RangeSet -{ - typedef typename RANGE::attr_t attr_t; - typedef boost::container::flat_set< RANGE > set_t; - typedef typename set_t::const_iterator set_iterator; - - set_t mySet; - - _RangeSet() { mySet.insert( RANGE( 0, 0 )); } - - /*! - * \brief Return a number of ranges - */ - size_t Size() const { return mySet.size(); } - - /*! - * \brief Return a mutable _Range::my1st of a range pointed by an iterator - */ - int& First( set_iterator rangePtr ) { return const_cast< int& >( rangePtr->my1st ); } - - /*! - * \brief Return a number of elements in a range pointed by an iterator - */ - size_t Size( set_iterator rangePtr ) const - { - int next1st = - ( rangePtr + 1 == mySet.end() ) ? SMDS_ElementFactory::ChunkSize() : ( rangePtr + 1 )->my1st; - return next1st - rangePtr->my1st; - } - - /*! - * \brief Return ranges of indices (from,to) of elements having a given value - */ - bool GetIndices( const attr_t theValue, TIndexRanges & theIndices, - const attr_t* theMinValue = 0, const attr_t* theMaxValue = 0) const - { - bool isFound = false; - - if ( sizeof( attr_t ) == sizeof( int ) && theMinValue ) - if ( theValue < *theMinValue || theValue > *theMaxValue ) - return isFound; - - for ( set_iterator it = mySet.begin(); it < mySet.end(); ++it ) - { - if ( it->myValue == theValue ) - { - theIndices.push_back( std::make_pair( it->my1st, it->my1st + Size( it ))); - isFound = true; - ++it; // the next range value differs from theValue - } - } - return isFound; - } - - /*! - * \brief Return value of an element attribute - * \param [in] theIndex - element index - * \return attr_t - attribute value - */ - attr_t GetValue( int theIndex ) const - { - set_iterator r = mySet.upper_bound( theIndex ) - 1; - return r->myValue; - } - - /*! - * \brief Change value of an element attribute - * \param [in] theIndex - element index - * \param [in] theValue - attribute value - * \return attr_t - previous value - */ - attr_t SetValue( int theIndex, attr_t theValue ) - { - set_iterator rNext = mySet.upper_bound( theIndex ); - set_iterator r = rNext - 1; - int rSize = Size( r ); // range size - attr_t rValue = r->myValue; - if ( rValue == theValue ) - return rValue; // it happens while compacting - - if ( r->my1st == theIndex ) // theIndex is the first in the range - { - bool joinPrev = // can join theIndex to the previous range - ( r->my1st > 0 && ( r-1 )->myValue == theValue ); - - if ( rSize == 1 ) - { - bool joinNext = // can join to the next range - ( rNext != mySet.end() && rNext->myValue == theValue ); - - if ( joinPrev ) - { - if ( joinNext ) // && joinPrev - { - mySet.erase( r, r + 2 ); - } - else // joinPrev && !joinNext - { - mySet.erase( r ); - } - } - else - { - if ( joinNext ) // && !joinPrev - { - r = mySet.erase( r ); // then r points to the next range - First( r )--; - } - else // !joinPrev && !joinNext - { - const_cast< attr_t & >( r->myValue ) = theValue; - } - } - } - else // if rSize > 1 - { - if ( joinPrev ) - { - First( r )++; - } - else - { - r = mySet.insert( r, RANGE( theIndex + 1, rValue )) - 1; - const_cast< attr_t & >( r->myValue ) = theValue; - } - } - } - else if ( r->my1st + rSize - 1 == theIndex ) // theIndex is last in the range - { - if ( rNext != mySet.end() && rNext->myValue == theValue ) // join to the next - { - First( rNext )--; - } - else - { - mySet.insert( r, RANGE( theIndex, theValue )); - } - } - else // theIndex in the middle of the range - { - r = mySet.insert( r, RANGE( theIndex, theValue )); - r = mySet.insert( r, RANGE( theIndex + 1, rValue )); - } - return rValue; - } -}; // struct _RangeSet - - -typedef _Range< int > _ShapeIDRange; // sub-mesh ID range -typedef _Range< bool > _UsedRange; // range of used elements - -typedef _RangeSet< _ShapeIDRange > TSubIDRangeSet; -typedef _RangeSet< _UsedRange > TUsedRangeSet; -typedef boost::dynamic_bitset<> TBitSet; -typedef float TParam; - -//------------------------------------------------------------------------------------ -/*! - * \brief Allocate SMDS_MeshElement's (SMDS_MeshCell's or SMDS_MeshNode's ) - * and bind some attributes to elements: - * element ID, sub-shape ID, isMarked flag, parameters on shape - */ -class SMDS_ElementChunk -{ - SMDS_ElementFactory* myFactory; // holder of this chunk - SMDS_MeshElement* myElements; // array of elements - int my1stID; // ID of myElements[0] - TBitSet myMarkedSet; // mark some elements - TUsedRangeSet myUsedRanges; // ranges of used/unused elements - TSubIDRangeSet mySubIDRanges; // ranges of elements on the same sub-shape - int myMinSubID; // min sub-shape ID - int myMaxSubID; // max sub-shape ID - std::vector myPositions; // UV parameters on shape: 2*param_t per an element - -public: - - SMDS_ElementChunk( SMDS_ElementFactory* factory = 0, int id0 = 0 ); - ~SMDS_ElementChunk(); - - //! Return an element by an index [0,ChunkSize()] - SMDS_MeshElement* Element(int index) { return & myElements[index]; } - - //! Return an element by an index [0,ChunkSize()] - const SMDS_MeshElement* Element(int index) const { return & myElements[index]; } - - //! Return ID of the first non-used element - int GetUnusedID() const; - - //! Mark an element as used - void UseElement( const int index ); - - //! Mark an element as non-used - void Free( const SMDS_MeshElement* e ); - - //! Check if a given range holds used or non-used elements - static bool IsUsed( const _UsedRange& r ) { return r.myValue; } - - //! Return index of an element in the chunk - int Index( const SMDS_MeshElement* e ) const { return e - myElements; } - - //! Return ID of the 1st element in the chunk - int Get1stID() const { return my1stID; } - - //! Return pointer to on-shape-parameters of a node - TParam* GetPositionPtr( const SMDS_MeshElement* node, bool allocate=false ); - - //! Return ranges of used/non-used elements - const TUsedRangeSet& GetUsedRanges() const { return myUsedRanges; } - const TUsedRangeSet& GetUsedRangesMinMax( bool& min, bool& max ) const - { min = false; max = true; return myUsedRanges; } - - //! Return ranges of elements assigned to sub-shapes and min/max of sub-shape IDs - const TSubIDRangeSet& GetSubIDRangesMinMax( int& min, int& max ) const - { min = myMinSubID; max = myMaxSubID; return mySubIDRanges; } - - //! Minimize allocated memory - void Compact(); - - //! Print some data - void Dump() const; // debug - - - // Methods called by SMDS_MeshElement - - int GetID( const SMDS_MeshElement* e ) const; - - int GetVtkID( const SMDS_MeshElement* e ) const; - void SetVTKID( const SMDS_MeshElement* e, const vtkIdType id ); - - int GetShapeID( const SMDS_MeshElement* e ) const; - void SetShapeID( const SMDS_MeshElement* e, int shapeID ) const; - - bool IsMarked ( const SMDS_MeshElement* e ) const; - void SetIsMarked( const SMDS_MeshElement* e, bool is ); - - SMDS_PositionPtr GetPosition( const SMDS_MeshNode* n ) const; - void SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID ); - - SMDS_Mesh* GetMesh() { return myFactory->myMesh; } -}; - -//------------------------------------------------------------------------------------ -/*! - * \brief Iterator on elements in chunks - */ -template< class ELEM_ITERATOR, class RANGE_SET > -struct _ChunkIterator : public ELEM_ITERATOR -{ - typedef typename ELEM_ITERATOR::value_type element_type; - typedef SMDS_MeshElement::Filter* filter_ptr; - typedef typename RANGE_SET::attr_t attr_type; - typedef const RANGE_SET& (SMDS_ElementChunk::*get_rangeset_fun)(attr_type&, attr_type&) const; - - const SMDS_MeshElement* myElement; - TIndexRanges myRanges; - int myRangeIndex; - const TChunkVector& myChunks; - int myChunkIndex; - get_rangeset_fun myGetRangeSetFun; - attr_type myValue; - attr_type myMinValue; - attr_type myMaxValue; - filter_ptr myFilter; - size_t myNbElemsToReturn; - size_t myNbReturned; - - _ChunkIterator( const TChunkVector & theChunks, - get_rangeset_fun theGetRangeSetFun, - attr_type theAttrValue, - SMDS_MeshElement::Filter* theFilter, - size_t theNbElemsToReturn = -1): - myElement( 0 ), - myRangeIndex( 0 ), - myChunks( theChunks ), - myChunkIndex( -1 ), - myGetRangeSetFun( theGetRangeSetFun ), - myValue( theAttrValue ), - myFilter( theFilter ), - myNbElemsToReturn( theNbElemsToReturn ), - myNbReturned( 0 ) - { - next(); - } - ~_ChunkIterator() - { - delete myFilter; - } - - virtual bool more() - { - return myElement; - } - - virtual element_type next() - { - element_type result = (element_type) myElement; - myNbReturned += bool( result ); - - myElement = 0; - if ( myNbReturned < myNbElemsToReturn ) - while ( ! nextInRange() ) - { - if ( ++myRangeIndex >= (int)myRanges.size() ) - { - myRanges.clear(); - myRangeIndex = 0; - while ( ++myChunkIndex < (int)myChunks.size() && - !getRangeSet().GetIndices( myValue, myRanges, &myMinValue, &myMaxValue )) - ; - if ( myChunkIndex >= (int)myChunks.size() ) - break; - } - } - return result; - } - - bool nextInRange() - { - if ( myRangeIndex < (int)myRanges.size() ) - { - std::pair< int, int > & range = myRanges[ myRangeIndex ]; - while ( range.first < range.second && !myElement ) - { - myElement = myChunks[ myChunkIndex ].Element( range.first++ ); - if ( !(*myFilter)( myElement )) - myElement = 0; - } - } - return myElement; - } - - const RANGE_SET& getRangeSet() - { - return ( myChunks[ myChunkIndex ].*myGetRangeSetFun )( myMinValue, myMaxValue ); - } -}; // struct _ChunkIterator - - -template< class ElemIterator > -boost::shared_ptr< ElemIterator > -SMDS_ElementFactory::GetIterator( SMDS_MeshElement::Filter* filter, - size_t nbElemsToReturn ) -{ - typedef _ChunkIterator< ElemIterator, TUsedRangeSet > TChuckIterator; - return boost::make_shared< TChuckIterator >( myChunks, - & SMDS_ElementChunk::GetUsedRangesMinMax, - /*isUsed=*/true, - filter, - nbElemsToReturn ); -} - -template< class ElemIterator > -boost::shared_ptr< ElemIterator > -SMDS_ElementFactory::GetShapeIterator( int shapeID, size_t nbElemsToReturn ) -{ - typedef _ChunkIterator< ElemIterator, TSubIDRangeSet > TChuckIterator; - return boost::make_shared< TChuckIterator >( myChunks, - & SMDS_ElementChunk::GetSubIDRangesMinMax, - /*shapeID=*/shapeID, - new SMDS_MeshElement::NonNullFilter(), - nbElemsToReturn ); -} - -#endif diff --git a/src/SMDS/SMDS_ElementHolder.cxx b/src/SMDS/SMDS_ElementHolder.cxx deleted file mode 100644 index 091359044..000000000 --- a/src/SMDS/SMDS_ElementHolder.cxx +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 : SMDS_ElementHolder.cxx -// Module : SMESH -// - -#include "SMDS_ElementHolder.hxx" - -#include "ObjectPool.hxx" -#include "SMDS_CellOfNodes.hxx" -#include "SMDS_Mesh.hxx" - -//======================================================================= -//function : SMDS_ElementHolder -//purpose : register self in the mesh -//======================================================================= - -SMDS_ElementHolder::SMDS_ElementHolder( const SMDS_Mesh* mesh ) - : myMesh( const_cast< SMDS_Mesh* >( mesh )) -{ - myPtrInMesh = myMesh->myElemHolders.insert( this ).first; -} - -//======================================================================= -//function : ~SMDS_ElementHolder -//purpose : un-register self from the mesh -//======================================================================= - -SMDS_ElementHolder::~SMDS_ElementHolder() -{ - myMesh->myElemHolders.erase( myPtrInMesh ); -} - -//======================================================================= -//function : beforeCompacting -//purpose : store vtkIDs of elements -//======================================================================= - -void SMDS_ElementHolder::beforeCompacting() -{ - int i = 0; - for ( SMDS_ElemIteratorPtr it = getElements(); it->more(); ++i ) - { - const SMDS_MeshElement* e = it->next(); - if ( !e ) continue; - if ( e->IsNull() && !dynamic_cast( e )) - continue; // removed element - myIsNode.push_back( e->GetType() == SMDSAbs_Node ); - if ( myMesh->Contains( e )) - { - myVtkIDs.push_back( e->GetVtkID() ); - } - else - { - myExternalElems.push_back( e ); - myVtkIDs.push_back( -1 * (int)myExternalElems.size() ); - } - } -} - -//======================================================================= -//function : restoreElements -//purpose : restore pointers to elements -//======================================================================= - -void SMDS_ElementHolder::restoreElements( const std::vector& idNodesOldToNew, - const std::vector& idCellsOldToNew ) -{ - tmpClear(); - - const SMDS_MeshElement* elem; - - std::vector< bool >::iterator isNode = myIsNode.begin(); - for ( size_t i = 0; i < myVtkIDs.size(); ++i, ++isNode ) - { - int vtkID = myVtkIDs[i]; - if ( vtkID < 0 ) - { - elem = myExternalElems[ (-vtkID)-1 ]; - } - else if ( *isNode ) - { - if ( vtkID < (int)idNodesOldToNew.size() ) - elem = myMesh->FindNodeVtk( idNodesOldToNew[ vtkID ]); - else - elem = myMesh->FindNodeVtk( vtkID ); - } - else - { - if ( vtkID < (int)idCellsOldToNew.size() ) - elem = myMesh->FindElementVtk( idCellsOldToNew[ vtkID ]); - else - elem = myMesh->FindElementVtk( vtkID ); - } - if ( elem ) - add( elem ); - } - clearVector( myExternalElems ); - clearVector( myVtkIDs ); - clearVector( myIsNode ); - - compact(); -} diff --git a/src/SMDS/SMDS_ElementHolder.hxx b/src/SMDS/SMDS_ElementHolder.hxx deleted file mode 100644 index f05774b11..000000000 --- a/src/SMDS/SMDS_ElementHolder.hxx +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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, or (at your option) any later version. -// -// 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 : SMDS_ElementHolder.hxx -// Module : SMESH -// -#ifndef _SMDS_ElementHolder_HeaderFile -#define _SMDS_ElementHolder_HeaderFile - -#include "SMESH_SMDS.hxx" - -#include "SMDS_ElemIterator.hxx" - -#include -#include - -class SMDS_Mesh; -class SMDS_MeshElement; - -//------------------------------------------------------------------------------------ -/*! - * \brief Base class of object holding SMDS_MeshElement pointers. - * Registering such an object in SMDS_Mesh assures that the - * pointers remain valid after compacting the mesh - */ -class SMDS_EXPORT SMDS_ElementHolder -{ - public: - - //! register self in the mesh - SMDS_ElementHolder( const SMDS_Mesh* mesh ); - - //! un-register self from the mesh - virtual ~SMDS_ElementHolder(); - - - protected: - - //!< the descendant object return its elements just before the mesh compacting - virtual SMDS_ElemIteratorPtr getElements() = 0; - - //!< the descendant object temporary remove its elements - virtual void tmpClear() = 0; - - //!< the descendant object re-add its elements after the mesh compacting - virtual void add( const SMDS_MeshElement* element ) = 0; - - //!< the descendant squeeze its element storage after re-adding elements - virtual void compact() = 0; - - //!< allow the descendant treat its elements before mesh clearing - virtual void clear() {} - - SMDS_Mesh* myMesh; - - - private: // methods called by SMDS_Mesh - - friend class SMDS_Mesh; - - //! store vtkIDs of elements - void beforeCompacting(); - - //! restore pointers to elements - void restoreElements( const std::vector& idNodessOldToNew, - const std::vector& idCellsOldToNew ); - - - std::vector myExternalElems; //!< elements not contained in the mesh - std::vector< int > myVtkIDs; //!< vtk IDs of elements - std::vector< bool > myIsNode; - std::set< SMDS_ElementHolder* >::iterator myPtrInMesh; -}; - -#endif diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx new file mode 100644 index 000000000..67ff4f6d1 --- /dev/null +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -0,0 +1,196 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_FaceOfEdges.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= + +int SMDS_FaceOfEdges::NbEdges() const +{ + return myNbEdges; +} + +int SMDS_FaceOfEdges::NbFaces() const +{ + return 1; +} +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_FaceOfEdges::Print(ostream & OS) const +{ + OS << "face <" << GetID() << " > : "; + int i; + for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ","; + OS << myEdges[i] << ") " << endl; +} + +SMDSAbs_ElementType SMDS_FaceOfEdges::GetType() const +{ + return SMDSAbs_Face; +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator +{ + const SMDS_MeshEdge* const *mySet; + int myLength; + int index; + public: + SMDS_FaceOfEdges_MyIterator(const SMDS_MeshEdge* const *s, int l): + mySet(s),myLength(l),index(0) {} + + bool more() + { + return index set1,set2; + SMDS_ElemIteratorPtr it; + const SMDS_MeshNode * n; + + it=f1.nodesIterator(); + + while(it->more()) + { + n=static_cast(it->next()); + set1.insert(*n); + } + + delete it; + it=f2.nodesIterator(); + + while(it->more()) + { + n=static_cast(it->next()); + set2.insert(*n); + } + + delete it; + return set1NbNodes() + myEdges[1]->NbNodes() + myEdges[2]->NbNodes() + + ( myNbEdges == 4 ? myEdges[3]->NbNodes() : 0 ) - myNbEdges; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const +{ + int index = ind; + for ( int i = 0; i < myNbEdges; ++i ) { + if ( index >= myEdges[ i ]->NbNodes() ) + index -= myEdges[ i ]->NbNodes(); + else + return myEdges[ i ]->GetNode( index ); + } + return 0; +} + +SMDSAbs_EntityType SMDS_FaceOfEdges::GetEntityType() const +{ + return myNbEdges == 3 ? SMDSEntity_Triangle : SMDSEntity_Quadrangle; +} + +SMDSAbs_GeometryType SMDS_FaceOfEdges::GetGeomType() const +{ + return myNbEdges == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE; +} diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx new file mode 100644 index 000000000..8bfc1d321 --- /dev/null +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifndef _SMDS_FaceOfEdges_HeaderFile +#define _SMDS_FaceOfEdges_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshFace.hxx" +#include "SMDS_MeshEdge.hxx" +#include "SMDS_Iterator.hxx" + +#include + + +class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace +{ + public: + void Print(std::ostream & OS) const; + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + const SMDS_MeshEdge* edge2, + const SMDS_MeshEdge* edge3); + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + const SMDS_MeshEdge* edge2, + const SMDS_MeshEdge* edge3, + const SMDS_MeshEdge* edge4); + + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) {return false;} + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + + private: + const SMDS_MeshEdge* myEdges[4]; + int myNbEdges; + +}; + +#endif diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index 0b7f9acf9..dfd3b7385 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -26,15 +26,15 @@ #pragma warning(disable:4786) #endif -#include "SMDS_FaceOfNodes.hxx" - #include "SMDS_SetIterator.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_Mesh.hxx" -#include +#include "utilities.h" -#include +using namespace std; //======================================================================= //function : NbEdges @@ -43,25 +43,17 @@ int SMDS_FaceOfNodes::NbEdges() const { - return NbNodes(); + return NbNodes(); } int SMDS_FaceOfNodes::NbFaces() const { - return 1; + return 1; } int SMDS_FaceOfNodes::NbNodes() const { - return myNbNodes; -} - -int SMDS_FaceOfNodes::GetNodeIndex( const SMDS_MeshNode* node ) const -{ - for ( int i = 0; i < myNbNodes; ++i ) - if ( myNodes[i] == node ) - return i; - return -1; + return myNbNodes; } //======================================================================= @@ -71,31 +63,81 @@ int SMDS_FaceOfNodes::GetNodeIndex( const SMDS_MeshNode* node ) const void SMDS_FaceOfNodes::Print(ostream & OS) const { - OS << "face <" << GetID() << " > : "; - int i; - for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ","; - OS << myNodes[i] << ") " << endl; + OS << "face <" << GetID() << " > : "; + int i; + for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; } -SMDS_ElemIteratorPtr SMDS_FaceOfNodes::nodesIterator() const +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { - return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); -} + public: + SMDS_FaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l): + SMDS_NodeArrayElemIterator( s, & s[ l ] ) {} +}; -SMDS_NodeIteratorPtr SMDS_FaceOfNodes::nodeIterator() const +/// =================================================================== +/*! + * \brief Iterator on edges of face + */ +/// =================================================================== + +class _MyEdgeIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MyEdgeIterator(const SMDS_FaceOfNodes* face):myIndex(0) { + myElems.reserve( face->NbNodes() ); + for ( int i = 0; i < face->NbNodes(); ++i ) { + const SMDS_MeshElement* edge = + SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 )); + if ( edge ) + myElems.push_back( edge ); + } + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator( SMDSAbs_ElementType type ) const { - return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); + switch(type) + { + case SMDSAbs_Face: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this )); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr + (new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes)))); + } + return SMDS_ElemIteratorPtr(); } SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node2, const SMDS_MeshNode* node3) { - myNbNodes = 3; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=0; + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); + myNbNodes = 3; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=0; } SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, @@ -103,11 +145,12 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node3, const SMDS_MeshNode* node4) { - myNbNodes = 4; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); + myNbNodes = 4; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; } bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) diff --git a/src/SMDS/SMDS_FaceOfNodes.hxx b/src/SMDS/SMDS_FaceOfNodes.hxx index 7e25a90f5..fec0b0999 100644 --- a/src/SMDS/SMDS_FaceOfNodes.hxx +++ b/src/SMDS/SMDS_FaceOfNodes.hxx @@ -27,43 +27,46 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_CellOfNodes.hxx" +#include "SMDS_MeshFace.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Iterator.hxx" -class SMDS_EXPORT SMDS_FaceOfNodes: public SMDS_CellOfNodes -{ - public: - void Print(std::ostream & OS) const; - SMDS_FaceOfNodes(const SMDS_MeshNode* node1, - const SMDS_MeshNode* node2, - const SMDS_MeshNode* node3); - SMDS_FaceOfNodes(const SMDS_MeshNode* node1, - const SMDS_MeshNode* node2, - const SMDS_MeshNode* node3, - const SMDS_MeshNode* node4); - virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], - const int nbNodes); - virtual int NbEdges() const; - virtual int NbFaces() const; - virtual int NbNodes() const; - - virtual int NbCornerNodes() const { return NbNodes(); } - virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - - virtual bool IsPoly() const { return false; } - virtual bool IsQuadratic() const { return false; } +#include - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; +class SMDS_EXPORT SMDS_FaceOfNodes:public SMDS_MeshFace +{ + public: + void Print(std::ostream & OS) const; + SMDS_FaceOfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3); + SMDS_FaceOfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3, + const SMDS_MeshNode* node4); + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + int NbEdges() const; + int NbFaces() const; + int NbNodes() const; + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ virtual const SMDS_MeshNode* GetNode(const int ind) const; - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } virtual SMDSAbs_EntityType GetEntityType() const; virtual SMDSAbs_GeometryType GetGeomType() const; - private: - const SMDS_MeshNode* myNodes[4]; - int myNbNodes; + protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + + private: + const SMDS_MeshNode* myNodes[4]; + int myNbNodes; }; diff --git a/src/SMDS/SMDS_FacePosition.cxx b/src/SMDS/SMDS_FacePosition.cxx index 3eb3c16df..ae12dc313 100644 --- a/src/SMDS/SMDS_FacePosition.cxx +++ b/src/SMDS/SMDS_FacePosition.cxx @@ -26,62 +26,63 @@ // Module : SMESH // #include "SMDS_FacePosition.hxx" -#include "SMDS_EdgePosition.hxx" + +#include "utilities.h" + +using namespace std; //======================================================================= //function : SMDS_FacePosition -//purpose : +//purpose : //======================================================================= SMDS_FacePosition::SMDS_FacePosition(const double aUParam, const double aVParam) + : myUParameter(aUParam),myVParameter(aVParam) { - SetParameters( aUParam,aVParam ); + //MESSAGE("******************************************************** SMDS_FacePosition"); } -//======================================================================= -//function : GetTypeOfPosition -//purpose : -//======================================================================= - +/** +*/ SMDS_TypeOfPosition SMDS_FacePosition::GetTypeOfPosition() const { - return SMDS_TOP_FACE; + return SMDS_TOP_FACE; } void SMDS_FacePosition::SetUParameter(double aUparam) { - myParameter[0] = aUparam; + myUParameter = aUparam; } //======================================================================= //function : SetVParameter -//purpose : +//purpose : //======================================================================= void SMDS_FacePosition::SetVParameter(double aVparam) { - myParameter[1] = aVparam; + myVParameter = aVparam; } //======================================================================= //function : GetUParameter -//purpose : +//purpose : //======================================================================= -double SMDS_FacePosition::GetUParameter() const +double SMDS_FacePosition::GetUParameter() const { - return myParameter[0]; + return myUParameter; } //======================================================================= //function : GetVParameter -//purpose : +//purpose : //======================================================================= -double SMDS_FacePosition::GetVParameter() const +double SMDS_FacePosition::GetVParameter() const { - return myParameter[1]; + return myVParameter; } //======================================================================= @@ -91,6 +92,6 @@ double SMDS_FacePosition::GetVParameter() const void SMDS_FacePosition::SetParameters(double aUparam, double aVparam) { - myParameter[0] = aUparam; - myParameter[1] = aVparam; + myUParameter = aUparam; + myVParameter = aVparam; } diff --git a/src/SMDS/SMDS_FacePosition.hxx b/src/SMDS/SMDS_FacePosition.hxx index a36e300ad..45015887d 100644 --- a/src/SMDS/SMDS_FacePosition.hxx +++ b/src/SMDS/SMDS_FacePosition.hxx @@ -33,17 +33,18 @@ class SMDS_EXPORT SMDS_FacePosition:public SMDS_Position { - public: - SMDS_FacePosition(double aUParam=0, double aVParam=0); - SMDS_TypeOfPosition GetTypeOfPosition() const; - virtual void SetUParameter(double aUparam); - virtual void SetVParameter(double aVparam); - virtual void SetParameters(double aUparam, double aVparam); - virtual double GetUParameter() const; - virtual double GetVParameter() const; - virtual const double* GetParameters() const { return &myParameter[0]; } - private: - double myParameter[2]; + public: + SMDS_FacePosition(double aUParam=0, double aVParam=0); + SMDS_TypeOfPosition GetTypeOfPosition() const; + void SetUParameter(double aUparam); + void SetVParameter(double aVparam); + void SetParameters(double aUparam, double aVparam); + double GetUParameter() const; + double GetVParameter() const; + + private: + double myUParameter; + double myVParameter; }; #endif diff --git a/src/SMDS/SMDS_Iterator.hxx b/src/SMDS/SMDS_Iterator.hxx index 561324930..f20d7062e 100644 --- a/src/SMDS/SMDS_Iterator.hxx +++ b/src/SMDS/SMDS_Iterator.hxx @@ -25,28 +25,27 @@ #ifndef _SMDS_Iterator_HeaderFile #define _SMDS_Iterator_HeaderFile +#include "SMESH_SMDS.hxx" + /////////////////////////////////////////////////////////////////////////////// ///Abstract class for iterators ///@author Jerome Robert /////////////////////////////////////////////////////////////////////////////// template class SMDS_Iterator { -public: - - typedef VALUE value_type; - - /// Return true if and only if there are other object in this iterator - virtual bool more()=0; - - /// Return the current object and step to the next one - virtual VALUE next()=0; + public: + /// Return true if and only if there are other object in this iterator + virtual bool more()=0; + + /// Return the current object and step to the next one + virtual VALUE next()=0; - /// Delete the current element and step to the next one - virtual void remove(){} + /// Delete the current element and step to the next one + virtual void remove(){} - /// Provide virtual destructor just for case if some derived iterator - /// must have a destructor - virtual ~SMDS_Iterator(){} + /// Provide virtual destructor just for case if some derived iterator + /// must have a destructor + virtual ~SMDS_Iterator(){} }; #endif diff --git a/src/SMDS/SMDS_IteratorOfElements.cxx b/src/SMDS/SMDS_IteratorOfElements.cxx new file mode 100644 index 000000000..3d125fcfb --- /dev/null +++ b/src/SMDS/SMDS_IteratorOfElements.cxx @@ -0,0 +1,109 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_IteratorOfElements.hxx" + +bool SMDS_IteratorOfElements::subMore() +{ + if((t2Iterator.get()==NULL)||(!t2Iterator->more())) + { + if(t1Iterator->more()) + { + t2Iterator=t1Iterator->next()->elementsIterator(myType); + return subMore(); + } + else return false; + } + else return true; +} + +const SMDS_MeshElement * SMDS_IteratorOfElements::subNext() +{ + if((t2Iterator.get()==NULL)||(!t2Iterator->more())) + if(t1Iterator->more()) + t2Iterator=t1Iterator->next()->elementsIterator(myType); + return t2Iterator->next(); +} + +///////////////////////////////////////////////////////////////////////////// +/// Create an iterator which look for elements of type type which are linked +/// to the element element. it is the iterator to get connectivity of element +////////////////////////////////////////////////////////////////////////////// +SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement * element, + SMDSAbs_ElementType type, + const SMDS_ElemIteratorPtr& it) + : t1Iterator(it), + t2Iterator(SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL)), + myType(type), myElement(element), + myProxyElement(NULL) +{ + while(subMore()) + alreadyReturnedElements.insert(subNext()); + itAlreadyReturned= alreadyReturnedElements.begin(); + switch(myElement->GetType()) + { + case SMDSAbs_Node: + case SMDSAbs_Edge: myReverseIteration=true; break; + case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break; + default: myReverseIteration=false; + } +} + +bool SMDS_IteratorOfElements::more() +{ + if(myProxyElement==NULL) + { + while(itAlreadyReturned!=alreadyReturnedElements.end()) + { + myProxyElement=*itAlreadyReturned; + itAlreadyReturned++; + + if(myReverseIteration) + { + SMDS_ElemIteratorPtr it= + myProxyElement->elementsIterator(myElement->GetType()); + while(it->more()) + { + if(it->next()==myElement) return true; + } + } + else return true; + } + myProxyElement=NULL; + return false; + } + else return true; +} + +const SMDS_MeshElement * SMDS_IteratorOfElements::next() +{ + more(); + const SMDS_MeshElement *e=myProxyElement; + myProxyElement=NULL; + return e; +} diff --git a/src/SMDS/SMDS_IteratorOfElements.hxx b/src/SMDS/SMDS_IteratorOfElements.hxx new file mode 100644 index 000000000..f2d73d8c7 --- /dev/null +++ b/src/SMDS/SMDS_IteratorOfElements.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#include "SMESH_SMDS.hxx" + +#include "SMDS_Iterator.hxx" +#include "SMDS_MeshElement.hxx" +#include + + +class SMDS_EXPORT SMDS_IteratorOfElements:public SMDS_ElemIterator +{ + public: +///////////////////////////////////////////////////////////////////////////// +/// Create an iterator which look for elements of type type which are linked +/// to the element element. it is the iterator to get connectivity of element +////////////////////////////////////////////////////////////////////////////// + SMDS_IteratorOfElements(const SMDS_MeshElement * element, + SMDSAbs_ElementType type, + const SMDS_ElemIteratorPtr& it); + bool more(); + const SMDS_MeshElement * next(); + + private: + SMDS_ElemIteratorPtr t1Iterator; + SMDS_ElemIteratorPtr t2Iterator; + SMDSAbs_ElementType myType; + const SMDS_MeshElement * myElement; + const SMDS_MeshElement * myProxyElement; + bool myReverseIteration; + + std::set alreadyReturnedElements; + std::set::iterator itAlreadyReturned; + bool subMore(); + const SMDS_MeshElement * subNext(); +}; diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx index 1d58368d4..8b87a9a44 100644 --- a/src/SMDS/SMDS_LinearEdge.cxx +++ b/src/SMDS/SMDS_LinearEdge.cxx @@ -28,10 +28,11 @@ #endif #include "SMDS_LinearEdge.hxx" +#include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_SetIterator.hxx" +#include "utilities.h" -#include +using namespace std; //======================================================================= //function : SMDS_LinearEdge @@ -41,10 +42,22 @@ SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) { + //MESSAGE("SMDS_LinearEdge " << GetID()); myNodes[0] = node1; myNodes[1] = node2; } +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_LinearEdge::Print(ostream & OS) const +{ + OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] + << ") " << endl; +} + int SMDS_LinearEdge::NbNodes() const { return 2; @@ -55,29 +68,75 @@ int SMDS_LinearEdge::NbEdges() const return 1; } -int SMDS_LinearEdge::NbFaces() const +class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator { - return 0; -} + const SMDS_MeshNode * const * myNodes; + int myIndex; +public: + SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) : + myNodes(nodes), myIndex(0) + { + } -int SMDS_LinearEdge::GetNodeIndex( const SMDS_MeshNode* node ) const -{ - if ( node == myNodes[0] ) return 0; - if ( node == myNodes[1] ) return 1; - return -1; -} + bool more() + { + return myIndex < 2; + } -SMDS_ElemIteratorPtr SMDS_LinearEdge::nodesIterator() const + const SMDS_MeshElement* next() + { + myIndex++; + return myNodes[myIndex - 1]; + } +}; + +SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const { - return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); + switch (type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements(this, + type, + SMDS_ElemIteratorPtr + (new SMDS_LinearEdge_MyNodeIterator(myNodes)))); + } } -SMDS_NodeIteratorPtr SMDS_LinearEdge::nodeIterator() const +bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2) { - return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); + int id11 = e1.myNodes[0]->getVtkId(); + int id21 = e2.myNodes[0]->getVtkId(); + int id12 = e1.myNodes[1]->getVtkId(); + int id22 = e2.myNodes[1]->getVtkId(); + int tmp; + + if (id11 >= id12) + { + tmp = id11; + id11 = id12; + id12 = tmp; + } + if (id21 >= id22) + { + tmp = id21; + id21 = id22; + id22 = tmp; + } + + if (id11 < id21) + return true; + else if (id11 == id21) + return (id21 < id22); + else + return false; } -/* +/*! * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node @@ -92,9 +151,10 @@ const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const //purpose : //======================================================================= -bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) { - myNodes[0] = nodes[0]; - myNodes[1] = nodes[1]; - return nbNodes == 2; + myNodes[0] = node1; + myNodes[1] = node2; + return true; } diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx index 75d984e3f..1ac80ee8a 100644 --- a/src/SMDS/SMDS_LinearEdge.hxx +++ b/src/SMDS/SMDS_LinearEdge.hxx @@ -27,34 +27,42 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_CellOfNodes.hxx" +#include "SMDS_MeshEdge.hxx" +#include -class SMDS_EXPORT SMDS_LinearEdge: public SMDS_CellOfNodes +class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge { + public: SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + void Print(std::ostream & OS) const; - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Edge; } - virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_EDGE; } - virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Edge; } - virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); - virtual int NbNodes() const; - virtual int NbEdges() const; - virtual int NbFaces() const; - - virtual int NbCornerNodes() const { return NbNodes(); } - virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - - virtual bool IsPoly() const { return false; } - virtual bool IsQuadratic() const { return false; } - - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; + virtual SMDSAbs_EntityType GetEntityType() const + { + return SMDSEntity_Edge; + } + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) + { + return false; + } + int NbNodes() const; + int NbEdges() const; + friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2); + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ virtual const SMDS_MeshNode* GetNode(const int ind) const; protected: - const SMDS_MeshNode* myNodes[2]; + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + +protected: + const SMDS_MeshNode* myNodes[3]; }; #endif diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 1d7ba140b..40caa2c88 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -26,28 +26,35 @@ #pragma warning(disable:4786) #endif +#include "SMDS_FaceOfEdges.hxx" +#include "SMDS_FaceOfNodes.hxx" #include "SMDS_Mesh.hxx" - -#include "SMDS_ElementFactory.hxx" -#include "SMDS_ElementHolder.hxx" +#include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_QuadraticVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_VolumeOfFaces.hxx" +#include "SMDS_VolumeOfNodes.hxx" -#include +#include "utilities.h" #include -//#include -#include +#include #include +#include #include #include #include +#include #include #include - -#include +#include +using namespace std; #if !defined WIN32 && !defined __APPLE__ #include @@ -56,10 +63,10 @@ // number of added entities to check memory after #define CHECKMEMORY_INTERVAL 100000 -#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified")); - +vector SMDS_Mesh::_meshList = vector(); int SMDS_Mesh::chunkSize = 1024; + //================================================================================ /*! * \brief Raise an exception if free memory (ram+swap) too low @@ -70,7 +77,6 @@ int SMDS_Mesh::chunkSize = 1024; int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) { - return -1; #if !defined WIN32 && !defined __APPLE__ struct sysinfo si; int err = sysinfo( &si ); @@ -81,16 +87,13 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) static int limit = -1; if ( limit < 0 ) { - if ( si.totalswap == 0 ) - { - int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM - if (status >= 0 ) { - limit = WEXITSTATUS(status); - } - else { - double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2; - limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte ); - } + int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM + if (status >= 0 ) { + limit = WEXITSTATUS(status); + } + else { + double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2; + limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte ); } if ( limit < 20 ) limit = 20; @@ -103,6 +106,7 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) int freeMb = ( si.freeram * si.mem_unit ) / Mbyte + ( si.freeswap * si.mem_unit ) / Mbyte; + //cout << "freeMb = " << freeMb << " limit = " << limit << endl; if ( freeMb > limit ) return freeMb - limit; @@ -121,12 +125,29 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) /// Create a new mesh object /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh(): - myNodeFactory( new SMDS_NodeFactory( this )), - myCellFactory( new SMDS_ElementFactory( this )), + myNodePool(0), myVolumePool(0), myFacePool(0), myEdgePool(0), myBallPool(0), myParent(NULL), + myNodeIDFactory(new SMDS_MeshNodeIDFactory()), + myElementIDFactory(new SMDS_MeshElementIDFactory()), myModified(false), myModifTime(0), myCompactTime(0), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true), xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) { + myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector + myNodeIDFactory->SetMesh(this); + myElementIDFactory->SetMesh(this); + _meshList.push_back(this); + myNodePool = new ObjectPool(SMDS_Mesh::chunkSize); + myEdgePool = new ObjectPool(SMDS_Mesh::chunkSize); + myFacePool = new ObjectPool(SMDS_Mesh::chunkSize); + myVolumePool = new ObjectPool(SMDS_Mesh::chunkSize); + myBallPool = new ObjectPool(SMDS_Mesh::chunkSize); + + myNodes.clear(); + myCells.clear(); + //myCellIdSmdsToVtk.clear(); + myCellIdVtkToSmds.clear(); myGrid = SMDS_UnstructuredGrid::New(); myGrid->setSMDS_mesh(this); myGrid->Initialize(); @@ -135,13 +156,22 @@ SMDS_Mesh::SMDS_Mesh(): // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" // Use double type for storing coordinates of nodes instead of float. points->SetDataType(VTK_DOUBLE); - points->SetNumberOfPoints( 0 ); + points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/); myGrid->SetPoints( points ); points->Delete(); + //myGrid->BuildLinks(); this->Modified(); // initialize static maps in SMDS_MeshCell, to be thread-safe - SMDS_MeshCell::InitStaticMembers(); + if ( myMeshId == 0 ) + { + SMDS_MeshCell::toVtkType( SMDSEntity_Node ); + SMDS_MeshCell::toVtkOrder( SMDSEntity_Node ); + SMDS_MeshCell::reverseSmdsOrder( SMDSEntity_Node ); + SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Node ); + SMDS_MeshCell::toSmdsType( VTK_VERTEX ); + SMDS_MeshCell::fromVtkOrder( SMDSEntity_Node ); + } } /////////////////////////////////////////////////////////////////////////////// @@ -150,9 +180,15 @@ SMDS_Mesh::SMDS_Mesh(): /// (2003-09-08) of SMESH /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent): - myNodeFactory( new SMDS_NodeFactory( this )), - myCellFactory( new SMDS_ElementFactory( this )), - myParent(parent) + myNodePool(parent->myNodePool), + myVolumePool(parent->myVolumePool), + myFacePool(parent->myFacePool), + myEdgePool(parent->myEdgePool), + myBallPool(parent->myBallPool), + myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), + myElementIDFactory(parent->myElementIDFactory), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true) { } @@ -175,7 +211,7 @@ SMDS_Mesh *SMDS_Mesh::AddSubMesh() SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) { - return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() ); + return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -183,18 +219,33 @@ SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) ///@param ID : The ID of the MeshNode to create ///@return : The created node or NULL if a node with this ID already exists /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID ) +SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) { // find the MeshNode corresponding to ID - SMDS_MeshNode *node = myNodeFactory->NewNode( ID ); - if ( node ) - { - node->init( x, y, z ); + const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); + if(!node){ + if (ID < 1) + { + MESSAGE("=============> Bad Node Id: " << ID); + ID = myNodeIDFactory->GetFreeID(); + } + myNodeIDFactory->adjustMaxId(ID); + SMDS_MeshNode * node = myNodePool->getNew(); + node->init(ID, myMeshId, 0, x, y, z); + + if (ID >= (int)myNodes.size()) + { + myNodes.resize(ID+SMDS_Mesh::chunkSize, 0); +// MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize); + } + myNodes[ID] = node; + myNodeIDFactory->BindID(ID,node); myInfo.myNbNodes++; myModified = true; this->adjustBoundingBox(x, y, z); - } - return node; + return node; + }else + return NULL; } /////////////////////////////////////////////////////////////////////////////// @@ -203,7 +254,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID ) /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID) { - const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode); + SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode); if (!node) return NULL; return SMDS_Mesh::Add0DElementWithID(node, ID); } @@ -214,7 +265,7 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID) /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node) { - return SMDS_Mesh::Add0DElementWithID( node, myCellFactory->GetFreeID() ); + return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -229,26 +280,30 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I if (!n) return 0; if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - - if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_0D, /*nbNodes=*/1, n ); + //MESSAGE("Add0DElementWithID" << ID) + SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n); + if (myElementIDFactory->BindID(ID, el0d)) { + //SMDS_MeshNode *node = const_cast(n); + //node->AddInverseElement(el0d);// --- fait avec BindID + adjustmyCellsCapacity(ID); + myCells[ID] = el0d; myInfo.myNb0DElements++; - return static_cast< SMDS_Mesh0DElement*> ( cell ); + return el0d; } - return 0; + delete el0d; + return NULL; } /////////////////////////////////////////////////////////////////////////////// /// create a Ball and add it to the current Mesh /// @return : The created Ball /////////////////////////////////////////////////////////////////////////////// -SMDS_BallElement* SMDS_Mesh::AddBallWithID( int idnode, double diameter, int ID ) +SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID) { - const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode ); + SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode); if (!node) return NULL; - return SMDS_Mesh::AddBallWithID( node, diameter, ID ); + return SMDS_Mesh::AddBallWithID(node, diameter, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -257,7 +312,7 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID( int idnode, double diameter, int ID /////////////////////////////////////////////////////////////////////////////// SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter) { - return SMDS_Mesh::AddBallWithID(node, diameter, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -274,12 +329,17 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID )); - if ( ball ) + SMDS_BallElement *ball = myBallPool->getNew(); + ball->init(n->getVtkId(), diameter, this); + if (!this->registerElement(ID,ball)) { - ball->init( n, diameter ); - myInfo.myNbBalls++; + this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL); + myBallPool->destroy(ball); + return 0; } + adjustmyCellsCapacity(ID); + myCells[ID] = ball; + myInfo.myNbBalls++; return ball; } @@ -290,8 +350,8 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) { - const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1); - const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2); + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); if(!node1 || !node2) return NULL; return SMDS_Mesh::AddEdgeWithID(node1, node2, ID); } @@ -304,7 +364,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) { - return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -318,17 +378,36 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, - int ID) + int ID) { if ( !n1 || !n2 ) return 0; + SMDS_MeshEdge * edge = 0; - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 ); - myInfo.myNbEdges++; - return static_cast( cell ); - } - return 0; + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbEdges++; + +// if (edge && !registerElement(ID, edge)) +// { +// RemoveElement(edge, false); +// edge = NULL; +// } + return edge; } /////////////////////////////////////////////////////////////////////////////// @@ -340,7 +419,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -349,9 +428,9 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID) { - const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1); - const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2); - const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3); + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); if(!node1 || !node2 || !node3) return NULL; return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); } @@ -365,16 +444,14 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, int ID) { - if ( !n1 || !n2 || !n3 ) return 0; - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //MESSAGE("AddFaceWithID " << ID) + SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID); - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 ); - myInfo.myNbTriangles++; - return static_cast( cell ); - } - return 0; +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -387,7 +464,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4) { - return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -400,12 +477,12 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode4, int ID) { - const SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = myNodeFactory->FindNode(idnode1); - node2 = myNodeFactory->FindNode(idnode2); - node3 = myNodeFactory->FindNode(idnode3); - node4 = myNodeFactory->FindNode(idnode4); - if ( !node1 || !node2 || !node3 || !node4 ) return NULL; + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + if(!node1 || !node2 || !node3 || !node4) return NULL; return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); } @@ -419,16 +496,100 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - if ( !n1 || !n2 || !n3 || !n4 ) return 0; + //MESSAGE("AddFaceWithID " << ID); + SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID); + +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3) +{ + if (!hasConstructionEdges()) + return NULL; + //MESSAGE("AddFaceWithID"); + return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + if ( !e1 || !e2 || !e3 ) return 0; + + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbTriangles++; + + if (!registerElement(ID, face)) { + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4) +{ + if (!hasConstructionEdges()) + return NULL; + return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + if ( !e1 || !e2 || !e3 || !e4 ) return 0; if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadrangles++; - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if (!registerElement(ID, face)) { - cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 ); - myInfo.myNbQuadrangles++; - return static_cast( cell ); + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; } - return 0; + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -441,7 +602,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() ); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// @@ -457,11 +621,11 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode4, int ID) { - const SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = myNodeFactory->FindNode(idnode1); - node2 = myNodeFactory->FindNode(idnode2); - node3 = myNodeFactory->FindNode(idnode3); - node4 = myNodeFactory->FindNode(idnode4); + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); if(!node1 || !node2 || !node3 || !node4) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID); } @@ -478,16 +642,49 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - if ( !n1 || !n2 || !n3 || !n4 ) return 0; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4) return volume; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 ); + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; - return static_cast( cell ); } - return 0; + else if(hasConstructionEdges()) { + return NULL; + } + else { + // --- retrieve nodes ID + myNodeIds.resize(4); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK + myNodeIds[2] = n2->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbTetras++; + } + + // if (!registerElement(ID, volume)) { + // RemoveElement(volume, false); + // volume = NULL; + // } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -502,7 +699,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n5) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() ); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// @@ -520,12 +720,12 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode5, int ID) { - const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; - node1 = myNodeFactory->FindNode(idnode1); - node2 = myNodeFactory->FindNode(idnode2); - node3 = myNodeFactory->FindNode(idnode3); - node4 = myNodeFactory->FindNode(idnode4); - node5 = myNodeFactory->FindNode(idnode5); + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID); } @@ -544,16 +744,50 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, int ID) { - if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 ); + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); + SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; - return static_cast( cell ); } - return 0; + else if(hasConstructionEdges()) { + return NULL; + } + else { + // --- retrieve nodes ID + myNodeIds.resize(5); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n4->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n2->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPyramids++; + } + + // if (!registerElement(ID, volume)) { + // RemoveElement(volume, false); + // volume = NULL; + // } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -569,8 +803,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, const SMDS_MeshNode * n6) { - int ID = myCellFactory->GetFreeID(); - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// @@ -589,13 +825,14 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode6, int ID) { - const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; - node1 = myNodeFactory->FindNode(idnode1); - node2 = myNodeFactory->FindNode(idnode2); - node3 = myNodeFactory->FindNode(idnode3); - node4 = myNodeFactory->FindNode(idnode4); - node5 = myNodeFactory->FindNode(idnode5); - node6 = myNodeFactory->FindNode(idnode6); + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); } @@ -614,16 +851,52 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, int ID) { - if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 ); + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); + SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; - return static_cast( cell ); } - return 0; + else if(hasConstructionEdges()) { + return NULL; + } + else { + // --- retrieve nodes ID + myNodeIds.resize(6); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n6->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPrisms++; + } + + // if (!registerElement(ID, volume)) { + // RemoveElement(volume, false); + // volume = NULL; + // } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -644,9 +917,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n11, const SMDS_MeshNode * n12) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, - n7, n8, n9, n10, n11, n12, - myCellFactory->GetFreeID() ); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n7, n8, n9, n10, n11, n12, + ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// @@ -670,18 +946,18 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode12, int ID) { - const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1); - const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2); - const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3); - const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4); - const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5); - const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6); - const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7); - const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8); - const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9); - const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10); - const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11); - const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12); + SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9); + SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10); + SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11); + SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12); return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7, node8, node9, node10, node11, node12, ID); @@ -712,15 +988,44 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, !n7 || !n8 || !n9 || !n10 || !n11 || !n12 ) return volume; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Hexagonal_Prism, - /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 ); + if(hasConstructionFaces()) { + return NULL; + } + else if(hasConstructionEdges()) { + return NULL; + } + else { + // --- retrieve nodes ID + myNodeIds.resize(12); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n6->getVtkId(); + myNodeIds[2] = n5->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n3->getVtkId(); + myNodeIds[5] = n2->getVtkId(); + + myNodeIds[6] = n7->getVtkId(); + myNodeIds[7] = n12->getVtkId(); + myNodeIds[8] = n11->getVtkId(); + myNodeIds[9] = n10->getVtkId(); + myNodeIds[10] = n9->getVtkId(); + myNodeIds[11] = n8->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexPrism++; - return static_cast( cell ); } - return 0; + + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -738,8 +1043,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n7, const SMDS_MeshNode * n8) { - int ID = myCellFactory->GetFreeID(); - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// @@ -760,15 +1067,17 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode8, int ID) { - const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; - node1 = myNodeFactory->FindNode(idnode1); - node2 = myNodeFactory->FindNode(idnode2); - node3 = myNodeFactory->FindNode(idnode3); - node4 = myNodeFactory->FindNode(idnode4); - node5 = myNodeFactory->FindNode(idnode5); - node6 = myNodeFactory->FindNode(idnode6); - node7 = myNodeFactory->FindNode(idnode7); - node8 = myNodeFactory->FindNode(idnode8); + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8) + return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7, node8, ID); } @@ -794,28 +1103,203 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) - { - cell->init( SMDSEntity_Hexa, - /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 ); + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5); + SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); + SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexas++; - return static_cast( cell ); } - return 0; + else if(hasConstructionEdges()) { + return NULL; + } + else { + // --- retrieve nodes ID + myNodeIds.resize(8); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n4->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n2->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n8->getVtkId(); + myNodeIds[6] = n7->getVtkId(); + myNodeIds[7] = n6->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbHexas++; + } + + // if (!registerElement(ID, volume)) { + // RemoveElement(volume, false); + // volume = NULL; + // } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + if ( !f1 || !f2 || !f3 || !f4) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbTetras++; + + if (!registerElement(ID, volume)) { + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPyramids++; + + if (!registerElement(ID, volume)) { + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPrisms++; + + if (!registerElement(ID, volume)) { + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; + } + return volume; } /////////////////////////////////////////////////////////////////////////////// /// Add a polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes_ids, - const int ID) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector & nodes_ids, + const int ID) { int nbNodes = nodes_ids.size(); - std::vector nodes (nbNodes); + vector nodes (nbNodes); for (int i = 0; i < nbNodes; i++) { - nodes[i] = myNodeFactory->FindNode( nodes_ids[i] ); + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); if (!nodes[i]) return NULL; } return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); @@ -826,18 +1310,38 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* -SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nodes, - const int ID) +SMDS_Mesh::AddPolygonalFaceWithID (const vector & nodes, + const int ID) { - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshFace * face; - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if (hasConstructionEdges()) + { + return NULL; + } + else { - cell->init( SMDSEntity_Polygon, nodes ); + myNodeIds.resize( nodes.size() ); + for ( size_t i = 0; i < nodes.size(); ++i ) + myNodeIds[i] = nodes[i]->getVtkId(); + + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->initPoly(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbPolygons++; - return static_cast( cell ); } - return 0; + + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -845,21 +1349,21 @@ SMDS_Mesh::AddPolygonalFaceWithID (const std::vector & nod /// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector & nodes) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector & nodes) { - return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// /// Add a quadratic polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes_ids, - const int ID) +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector & nodes_ids, + const int ID) { - std::vector nodes( nodes_ids.size() ); + vector nodes( nodes_ids.size() ); for ( size_t i = 0; i < nodes.size(); i++) { - nodes[i] = myNodeFactory->FindNode(nodes_ids[i]); + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); if (!nodes[i]) return NULL; } return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID); @@ -870,17 +1374,36 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & n /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* -SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & nodes, - const int ID) +SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector & nodes, + const int ID) { + SMDS_MeshFace * face; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if (hasConstructionEdges()) + { + return NULL; + } + else { - cell->init( SMDSEntity_Quad_Polygon, nodes ); + myNodeIds.resize( nodes.size() ); + for ( size_t i = 0; i < nodes.size(); ++i ) + myNodeIds[i] = nodes[i]->getVtkId(); + + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->initQuadPoly(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadPolygons++; - return static_cast( cell ); } - return 0; + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -888,9 +1411,9 @@ SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector & /// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector & nodes) +SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector & nodes) { - return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -900,14 +1423,15 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector & nodes_ids, - const std::vector & quantities, - const int ID) +SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID + (const vector & nodes_ids, + const vector & quantities, + const int ID) { int nbNodes = nodes_ids.size(); - std::vector nodes (nbNodes); + vector nodes (nbNodes); for (int i = 0; i < nbNodes; i++) { - nodes[i] = myNodeFactory->FindNode(nodes_ids[i]); + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); if (!nodes[i]) return NULL; } return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); @@ -920,22 +1444,57 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector & /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* -SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes, - const std::vector & quantities, +SMDS_Mesh::AddPolyhedralVolumeWithID (const vector& nodes, + const vector & quantities, const int ID) { + SMDS_MeshVolume* volume = 0; if ( nodes.empty() || quantities.empty() ) return NULL; if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if (hasConstructionFaces()) + { + return NULL; + } + else if (hasConstructionEdges()) + { + return NULL; + } + else { - SMDS_MeshVolume* volume = static_cast( cell ); - volume->init( nodes, quantities ); + //#ifdef VTK_HAVE_POLYHEDRON + myNodeIds.resize( nodes.size() ); + for ( size_t i = 0; i < nodes.size(); ++i ) + myNodeIds[i] = nodes[i]->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->initPoly(myNodeIds, quantities, this); + if (!this->registerElement(ID, volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + //#else + // for ( int i = 0; i < nodes.size(); ++i ) + // if ( !nodes[ i ] ) return 0; + // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); + //#endif + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPolyhedrons++; - return volume; } - return 0; + + //#ifndef VTK_HAVE_POLYHEDRON + // if (!registerElement(ID, volume)) + // { + // registerElement(myElementIDFactory->GetFreeID(), volume); + // //RemoveElement(volume, false); + // //volume = NULL; + // } + //#endif + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -944,32 +1503,161 @@ SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& n /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume -(const std::vector & nodes, - const std::vector & quantities) + (const vector & nodes, + const vector & quantities) { - int ID = myCellFactory->GetFreeID(); - return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; } SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector& vtkNodeIds) { - SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); - SMDS_MeshVolume * vol = static_cast( cell ); - vol->init( vtkNodeIds ); - myInfo.add( cell ); - return vol; + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + vtkIdType aVtkType = volvtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TETRA: + myInfo.myNbTetras++; + break; + case VTK_PYRAMID: + myInfo.myNbPyramids++; + break; + case VTK_WEDGE: + myInfo.myNbPrisms++; + break; + case VTK_HEXAHEDRON: + myInfo.myNbHexas++; + break; + case VTK_QUADRATIC_TETRA: + myInfo.myNbQuadTetras++; + break; + case VTK_QUADRATIC_PYRAMID: + myInfo.myNbQuadPyramids++; + break; + case VTK_QUADRATIC_WEDGE: + myInfo.myNbQuadPrisms++; + break; + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + myInfo.myNbBiQuadPrisms++; + break; + case VTK_QUADRATIC_HEXAHEDRON: + myInfo.myNbQuadHexas++; + break; + case VTK_TRIQUADRATIC_HEXAHEDRON: + myInfo.myNbTriQuadHexas++; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + myInfo.myNbPolyhedrons++; + break; +//#endif + default: + myInfo.myNbPolyhedrons++; + break; + } + return volvtk; } SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector& vtkNodeIds) { - SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() ); - SMDS_MeshFace * f = static_cast( cell ); - f->init( vtkNodeIds ); - myInfo.add( cell ); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID); + if (f == NULL) myElementIDFactory->ReleaseID(ID); return f; } -//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = facevtk; + vtkIdType aVtkType = facevtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TRIANGLE: + myInfo.myNbTriangles++; + break; + case VTK_QUAD: + myInfo.myNbQuadrangles++; + break; + case VTK_QUADRATIC_TRIANGLE: + myInfo.myNbQuadTriangles++; + break; + case VTK_QUADRATIC_QUAD: + myInfo.myNbQuadQuadrangles++; + break; + case VTK_BIQUADRATIC_QUAD: + myInfo.myNbBiQuadQuadrangles++; + break; + case VTK_BIQUADRATIC_TRIANGLE: + myInfo.myNbBiQuadTriangles++; + break; + case VTK_POLYGON: + myInfo.myNbPolygons++; + break; + default: + myInfo.myNbPolygons++; + } + return facevtk; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Registers element with the given ID, maintains inverse connections +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element) +{ + if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound + { + MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId()); + return false; + } + + element->myID = ID; + element->myMeshId = myMeshId; + + SMDS_MeshCell *cell = dynamic_cast(element); + MYASSERT(cell); + int vtkId = cell->getVtkId(); + if (vtkId == -1) + vtkId = myElementIDFactory->SetInVtkGrid(element); + + if (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector + { + myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1); + } + myCellIdVtkToSmds[vtkId] = ID; + + myElementIDFactory->updateMinMax(ID); + return true; +} + +//======================================================================= //function : MoveNode //purpose : //======================================================================= @@ -985,7 +1673,11 @@ void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - return myNodeFactory->FindNode( ID ); + if (ID < 1 || ID >= (int)myNodes.size()) + { + return 0; + } + return (const SMDS_MeshNode *)myNodes[ID]; } /////////////////////////////////////////////////////////////////////////////// @@ -993,12 +1685,117 @@ const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const { - return myNodeFactory->FindNode( vtkId + 1 ); + // TODO if needed use mesh->nodeIdFromVtkToSmds + if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() ) + { + MESSAGE("------------------------------------------------------------------------- "); + MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size()); + MESSAGE("------------------------------------------------------------------------- "); + return 0; + } + return (const SMDS_MeshNode *)myNodes[vtkId+1]; +} + +////////////////////////////////////////////////////////////////////////////// +///Create a triangle and add it to the current mesh. This method does not bind +///an ID to the create triangle. +////////////////////////////////////////////////////////////////////////////// +SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + int ID) +{ + if ( !node1 || !node2 || !node3) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node1); + + //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbTriangles++; + return face; + } + else + { + // --- retrieve nodes ID + myNodeIds.resize(3); + myNodeIds[0] = node1->getVtkId(); + myNodeIds[1] = node2->getVtkId(); + myNodeIds[2] = node3->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbTriangles++; + return face; + } } -const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const +//////////////////////////////////////////////////////////////////////////////// +///Create a quadrangle and add it to the current mesh. This method does not bind +///an ID to the create triangle. +//////////////////////////////////////////////////////////////////////////////// +SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + int ID) { - return myCellFactory->FindElement( FromVtkToSmds( IDelem )); + if ( !node1 || !node2 || !node3 || !node4 ) return 0; + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node4); + edge4=FindEdgeOrCreate(node4,node1); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadrangles++; + return face; + } + else + { + // --- retrieve nodes ID + myNodeIds.resize(4); + myNodeIds[0] = node1->getVtkId(); + myNodeIds[1] = node2->getVtkId(); + myNodeIds[2] = node3->getVtkId(); + myNodeIds[3] = node4->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadrangles++; + return face; + } } /////////////////////////////////////////////////////////////////////////////// @@ -1010,6 +1807,42 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) RemoveElement(node, true); } +/////////////////////////////////////////////////////////////////////////////// +/// Remove an edge and all the elements which own this edge +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d) +{ + RemoveElement(elem0d,true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove an edge and all the elements which own this edge +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) +{ + RemoveElement(edge,true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove an face and all the elements which own this face +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) +{ + RemoveElement(face, true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove a volume +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) +{ + RemoveElement(volume, true); +} + //======================================================================= //function : RemoveFromParent //purpose : @@ -1030,7 +1863,7 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) { bool found = false; - std::list::iterator itmsh=myChildren.begin(); + list::iterator itmsh=myChildren.begin(); for (; itmsh!=myChildren.end() && !found; itmsh++) { SMDS_Mesh * submesh = *itmsh; @@ -1053,27 +1886,28 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, const SMDS_MeshNode * nodes[], const int nbnodes) { - // keep current nodes of element - std::set oldNodes( element->begin_nodes(), element->end_nodes() ); + // keep current nodes of elem + set oldNodes( element->begin_nodes(), element->end_nodes() ); // change nodes bool Ok = false; - if ( SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element)) + SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element); + if (cell) + { + Ok = cell->vtkOrder(nodes, nbnodes); Ok = cell->ChangeNodes(nodes, nbnodes); + } - if ( Ok ) - setMyModified(); + if ( Ok ) { // update InverseElements - if ( Ok && GetGrid()->HasLinks() ) // update InverseElements - { - std::set::iterator it; + set::iterator it; // AddInverseElement to new nodes for ( int i = 0; i < nbnodes; i++ ) { it = oldNodes.find( nodes[i] ); if ( it == oldNodes.end() ) // new node - const_cast( nodes[i] )->AddInverseElement( element ); + const_cast( nodes[i] )->AddInverseElement( cell ); else // remove from oldNodes a node that remains in elem oldNodes.erase( it ); @@ -1082,13 +1916,84 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) { SMDS_MeshNode * n = const_cast( *it ); - n->RemoveInverseElement( element ); + n->RemoveInverseElement( cell ); } } return Ok; } +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : to change nodes of polyhedral volume +//======================================================================= +bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + const vector& nodes, + const vector & quantities) +{ + if (elem->GetType() != SMDSAbs_Volume) { + MESSAGE("WRONG ELEM TYPE"); + return false; + } + + const SMDS_VtkVolume* vol = dynamic_cast(elem); + if (!vol) { + return false; + } + + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + oldNodes.insert(itn->next()); + } + + // change nodes + // TODO remove this function + //bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + bool Ok = false; + if (!Ok) { + return false; + } + + // update InverseElements + + // AddInverseElement to new nodes + int nbnodes = nodes.size(); + set::iterator it; + for (int i = 0; i < nbnodes; i++) { + it = oldNodes.find(nodes[i]); + if (it == oldNodes.end()) { + // new node + const_cast(nodes[i])->AddInverseElement(elem); + } else { + // remove from oldNodes a node that remains in elem + oldNodes.erase(it); + } + } + + // RemoveInverseElement from the nodes removed from elem + for (it = oldNodes.begin(); it != oldNodes.end(); it++) { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement(elem); + } + + return Ok; +} + + +//======================================================================= +//function : Find0DElement +//purpose : +//======================================================================= +const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const +{ + const SMDS_MeshNode * node = FindNode(idnode); + if(node == NULL) return NULL; + return Find0DElement(node); +} + const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) { if (!node) return 0; @@ -1103,6 +2008,18 @@ const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) return toReturn; } +//======================================================================= +//function : FindBall +//purpose : +//======================================================================= + +const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const +{ + const SMDS_MeshNode * node = FindNode(idnode); + if(node == NULL) return NULL; + return FindBall(node); +} + const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) { if (!node) return 0; @@ -1116,12 +2033,49 @@ const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) return toReturn; } +//======================================================================= +//function : Find0DElementOrCreate +//purpose : +//======================================================================= +//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node) +//{ +// if (!node) return 0; +// SMDS_Mesh0DElement * toReturn = NULL; +// toReturn = const_cast(Find0DElement(node)); +// if (toReturn == NULL) { +// //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); +// toReturn = new SMDS_Mesh0DElement(node); +// my0DElements.Add(toReturn); +// myInfo.myNb0DElements++; +// } +// return toReturn; +//} + + +//======================================================================= +//function : FindEdge +//purpose : +//======================================================================= + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + if((node1==NULL)||(node2==NULL)) return NULL; + return FindEdge(node1,node2); +} + +//#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) { if ( !node1 ) return 0; const SMDS_MeshEdge * toReturn=NULL; + //PROFILER_Init(); + //PROFILER_Set(); SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge); + //PROFILER_Get(0); + //PROFILER_Set(); while(it1->more()) { const SMDS_MeshElement * e = it1->next(); if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) { @@ -1129,9 +2083,60 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, break; } } + //PROFILER_Get(1); return toReturn; } + +//======================================================================= +//function : FindEdgeOrCreate +//purpose : +//======================================================================= + +SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + if ( !node1 || !node2) return 0; + SMDS_MeshEdge * toReturn=NULL; + toReturn=const_cast(FindEdge(node1,node2)); + if(toReturn==NULL) { + if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element + adjustmyCellsCapacity(ID); + myNodeIds.resize(2); + myNodeIds[0] = node1->getVtkId(); + myNodeIds[1] = node2->getVtkId(); + + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(myNodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + toReturn = edgevtk; + myCells[ID] = toReturn; + myInfo.myNbEdges++; + } + return toReturn; +} + + +//======================================================================= +//function : FindEdge +//purpose : +//======================================================================= + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2, + int idnode3) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + return FindEdge(node1,node2,node3); +} + const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node3) @@ -1159,11 +2164,21 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, return 0; } + //======================================================================= //function : FindFace //purpose : //======================================================================= +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + return FindFace(node1, node2, node3); +} + const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3) @@ -1191,11 +2206,35 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, return 0; } +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + SMDS_MeshFace * toReturn=NULL; + toReturn = const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) { + int ID = myElementIDFactory->GetFreeID(); + toReturn = createTriangle(node1,node2,node3, ID); + } + return toReturn; +} + + //======================================================================= //function : FindFace //purpose : //======================================================================= +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + const SMDS_MeshNode * node4=FindNode(idnode4); + return FindFace(node1, node2, node3, node4); +} + const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, @@ -1225,11 +2264,39 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, return 0; } +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) +{ + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3,node4)); + if(toReturn==NULL) { + int ID = myElementIDFactory->GetFreeID(); + toReturn=createQuadrangle(node1,node2,node3,node4,ID); + } + return toReturn; +} + + //======================================================================= //function : FindFace //purpose :quadratic triangle //======================================================================= +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + return FindFace(node1, node2, node3, node4, node5, node6); +} + const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, @@ -1269,6 +2336,22 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, //purpose : quadratic quadrangle //======================================================================= +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6, + int idnode7, int idnode8) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + const SMDS_MeshNode * node7 = FindNode(idnode7); + const SMDS_MeshNode * node8 = FindNode(idnode8); + return FindFace(node1, node2, node3, node4, node5, node6, node7, node8); +} + const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, @@ -1314,7 +2397,11 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myCellFactory->FindElement( IDelem ); + if ( IDelem <= 0 || IDelem >= (int)myCells.size() ) + { + return 0; + } + return myCells[IDelem]; } //======================================================================= @@ -1322,8 +2409,19 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const //purpose : find polygon //======================================================================= +const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector& nodes_ids) const +{ + int nbnodes = nodes_ids.size(); + vector poly_nodes (nbnodes); + for (int inode = 0; inode < nbnodes; inode++) { + const SMDS_MeshNode * node = FindNode(nodes_ids[inode]); + if (node == NULL) return NULL; + poly_nodes[inode] = node; + } + return FindFace(poly_nodes); +} -const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector& nodes) +const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector& nodes) { return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face ); } @@ -1339,7 +2437,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector& nodes, +const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector& nodes, const SMDSAbs_ElementType type, const bool noMedium) { @@ -1409,6 +2507,110 @@ int SMDS_Mesh::GetElementsByNodes(const std::vector& node return foundElems.size(); } +//======================================================================= +//function : DumpNodes +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpNodes() const +{ + SMDS_NodeIteratorPtr itnode=nodesIterator(); + while(itnode->more()) ; //MESSAGE(itnode->next()); +} + +//======================================================================= +//function : Dump0DElements +//purpose : +//======================================================================= +void SMDS_Mesh::Dump0DElements() const +{ + SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement); + while(it0d->more()) ; //MESSAGE(it0d->next()); +} + +//======================================================================= +//function : DumpEdges +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpEdges() const +{ + SMDS_EdgeIteratorPtr itedge=edgesIterator(); + while(itedge->more()) ; //MESSAGE(itedge->next()); +} + +//======================================================================= +//function : DumpFaces +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpFaces() const +{ + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) ; //MESSAGE(itface->next()); +} + +//======================================================================= +//function : DumpVolumes +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpVolumes() const +{ + SMDS_VolumeIteratorPtr itvol=volumesIterator(); + while(itvol->more()) ; //MESSAGE(itvol->next()); +} + +//======================================================================= +//function : DebugStats +//purpose : +//======================================================================= + +void SMDS_Mesh::DebugStats() const +{ + MESSAGE("Debug stats of mesh : "); + + MESSAGE("===== NODES ====="<more()) + { + const SMDS_MeshNode *node = itnode->next(); + + sizeofnodes += sizeof(*node); + + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while(it->more()) + { + const SMDS_MeshElement *me = it->next(); + sizeofnodes += sizeof(me); + } + } + + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) + { + const SMDS_MeshElement *face = itface->next(); + sizeoffaces += sizeof(*face); + } + + MESSAGE("total size of node elements = " << sizeofnodes);; + MESSAGE("total size of face elements = " << sizeoffaces);; + + //#endif +} + /////////////////////////////////////////////////////////////////////////////// /// Return the number of nodes /////////////////////////////////////////////////////////////////////////////// @@ -1479,35 +2681,91 @@ int SMDS_Mesh::NbSubMesh() const /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::~SMDS_Mesh() { - std::list::iterator itc=myChildren.begin(); + list::iterator itc=myChildren.begin(); while(itc!=myChildren.end()) { delete *itc; itc++; } - delete myNodeFactory; - delete myCellFactory; - + if(myParent==NULL) + { + delete myNodeIDFactory; + delete myElementIDFactory; + } + else + { + SMDS_ElemIteratorPtr eIt = elementsIterator(); + while ( eIt->more() ) + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + { + const SMDS_MeshNode *node = itn->next(); + ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } + } myGrid->Delete(); + + delete myNodePool; + delete myVolumePool; + delete myFacePool; + delete myEdgePool; + delete myBallPool; } -//================================================================================ -/*! - * \brief Clear all data - */ -//================================================================================ +//================================================================================ +/*! + * \brief Clear all data + */ +//================================================================================ + +void SMDS_Mesh::Clear() +{ + if (myParent!=NULL) + { + SMDS_ElemIteratorPtr eIt = elementsIterator(); + while ( eIt->more() ) + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + { + const SMDS_MeshNode *node = itn->next(); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } + } + else + { + myNodeIDFactory->Clear(); + myElementIDFactory->Clear(); + } + + myVolumePool->clear(); + myFacePool->clear(); + myEdgePool->clear(); + myBallPool->clear(); -void SMDS_Mesh::Clear() -{ - std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); - for ( ; holder != myElemHolders.end(); ++holder ) - (*holder)->clear(); + clearVector( myCells ); + clearVector( myCellIdVtkToSmds ); - myNodeFactory->Clear(); - myCellFactory->Clear(); + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + { + SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next()); + node->SetPosition(SMDS_SpacePosition::originSpacePosition()); + //myNodePool->destroy(node); + } + myNodePool->clear(); + clearVector( myNodes ); - std::list::iterator itc=myChildren.begin(); + list::iterator itc=myChildren.begin(); while(itc!=myChildren.end()) (*itc)->Clear(); @@ -1531,29 +2789,182 @@ void SMDS_Mesh::Clear() myGrid->DeleteLinks(); } +/////////////////////////////////////////////////////////////////////////////// +/// Return true if this mesh create faces with edges. +/// A false returned value mean that faces are created with nodes. A concequence +/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasConstructionEdges() +{ + return myHasConstructionEdges; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return true if this mesh create volumes with faces +/// A false returned value mean that volumes are created with nodes or edges. +/// (see hasConstructionEdges) +/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be +/// unavailable. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasConstructionFaces() +{ + return myHasConstructionFaces; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return true if nodes are linked to the finit elements, they are belonging to. +/// Currently, It always return true. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasInverseElements() +{ + return myHasInverseElements; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating construction edges (see hasConstructionEdges) +/// @param b true to have construction edges, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setConstructionEdges(bool b) +{ + myHasConstructionEdges=b; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating construction faces (see hasConstructionFaces) +/// @param b true to have construction faces, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setConstructionFaces(bool b) +{ + myHasConstructionFaces=b; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating link from nodes to elements (see hasInverseElements) +/// @param b true to link nodes to elements, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setInverseElements(bool b) +{ + if(!b) MESSAGE("Error : inverseElement=false not implemented"); + myHasInverseElements=b; +} + +namespace { + + //================================================================================ + /*! + * \brief Iterator on elements in id increasing order + */ + //================================================================================ + + template + class IdSortedIterator : public SMDS_Iterator + { + SMDS_MeshElementIDFactory& myIDFact; + int myID, myMaxID, myNbFound, myTotalNb; + SMDSAbs_ElementType myType; + ELEM myElem; + + public: + IdSortedIterator(const SMDS_MeshElementIDFactory& fact, + const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!! + const int totalNb) + :myIDFact( const_cast(fact) ), + myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ), + myType( type ), + myElem(0) + { + next(); + } + bool more() + { + return myElem; + } + ELEM next() + { + ELEM current = myElem; + + for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID ) + if ((myElem = (ELEM) myIDFact.MeshElement( myID )) + && myElem->GetType() != myType ) + myElem = 0; + + myNbFound += bool(myElem); + + return current; + } + }; + + //================================================================================ + /*! + * \brief Iterator on vector of elements, possibly being resized while iteration + */ + //================================================================================ + + template > + class ElemVecIterator: public SMDS_Iterator + { + const std::vector& _vector; + size_t _index; + bool _more; + VALUE_FILTER _filter; + public: + ElemVecIterator(const std::vector& vec, + const VALUE_FILTER& filter=VALUE_FILTER() ) + :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter ) + { + if ( _more && !_filter( _vector[ _index ])) + next(); + } + virtual bool more() + { + return _more; + } + virtual RETURN_VALUE next() + { + if ( !_more ) return NULL; + VECTOR_VALUE current = _vector[ _index ]; + _more = 0; + while ( !_more && ++_index < _vector.size() ) + _more = _filter( _vector[ _index ]); + return (RETURN_VALUE) current; + } + }; +} + /////////////////////////////////////////////////////////////////////////////// /// Return an iterator on nodes of the current mesh factory /////////////////////////////////////////////////////////////////////////////// -SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const { - return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter ); + // naturally always sorted by ID + typedef ElemVecIterator TIterator; + return SMDS_NodeIteratorPtr( new TIterator(myNodes)); } SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const { - return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ), - myInfo.NbElements( type )); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type ))); } SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const { if ( type == SMDSEntity_Node ) { - return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter ); + typedef ElemVecIterator TIterator; + return SMDS_ElemIteratorPtr( new TIterator(myNodes)); } - return myCellFactory->GetIterator( new SMDS_MeshElement::EntityFilter( type ), - myInfo.NbElements( type )); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type ))); } /////////////////////////////////////////////////////////////////////////////// @@ -1561,18 +2972,20 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) c /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { - typedef SMDS_ElemIterator TIterator; + // naturally always sorted by ID switch ( type ) { case SMDSAbs_All: - return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); + return SMDS_ElemIteratorPtr (new ElemVecIterator(myCells)); case SMDSAbs_Node: - return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter ); + return SMDS_ElemIteratorPtr + ( new ElemVecIterator( myNodes )); default: - return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ), - myInfo.NbElements( type )); + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type ))); } return SMDS_ElemIteratorPtr(); } @@ -1581,113 +2994,118 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const ///Return an iterator on edges of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const { - typedef SMDS_EdgeIterator TIterator; - return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ), - myInfo.NbEdges()); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_EdgeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on faces of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const { - typedef SMDS_FaceIterator TIterator; - return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ), - myInfo.NbFaces()); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_FaceIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face ))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on volumes of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const -{ - typedef SMDS_VolumeIterator TIterator; - return - myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ), - myInfo.NbVolumes()); -} - -SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, size_t nbElemsToReturn) const -{ - return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn ); -} - -SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, size_t nbElemsToReturn) const +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const { - return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn ); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_VolumeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ))); } /////////////////////////////////////////////////////////////////////////////// /// Do intersection of sets (more than 2) /////////////////////////////////////////////////////////////////////////////// -static std::set * -intersectionOfSets( std::set vs[], int numberOfSets ) +static set * intersectionOfSets( + set vs[], int numberOfSets) { - std::set* rsetA = new std::set(vs[0]); - std::set* rsetB; + set* rsetA=new set(vs[0]); + set* rsetB; - for(int i=0; i(); - set_intersection(rsetA->begin(), rsetA->end(), - vs[i+1].begin(), vs[i+1].end(), - inserter(*rsetB, rsetB->begin())); - delete rsetA; - rsetA=rsetB; - } - return rsetA; + for(int i=0; i(); + set_intersection( + rsetA->begin(), rsetA->end(), + vs[i+1].begin(), vs[i+1].end(), + inserter(*rsetB, rsetB->begin())); + delete rsetA; + rsetA=rsetB; + } + return rsetA; } + /////////////////////////////////////////////////////////////////////////////// /// Return the list of finite elements owning the given element: elements /// containing all the nodes of the given element, for instance faces and /// volumes containing a given edge. /////////////////////////////////////////////////////////////////////////////// -static std::set * getFinitElements(const SMDS_MeshElement * element) +static set * getFinitElements(const SMDS_MeshElement * element) { int numberOfSets=element->NbNodes(); - std::set *initSet = new std::set[numberOfSets]; + set *initSet = new set[numberOfSets]; - SMDS_NodeIteratorPtr itNodes = element->nodeIterator(); + SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); int i = 0; while ( itNodes->more() ) { - const SMDS_MeshNode * n = itNodes->next(); - for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); ) - initSet[i].insert( itFe->next() ); + const SMDS_MeshElement* node = itNodes->next(); + MYASSERT(node); + const SMDS_MeshNode * n=static_cast(node); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + + while ( itFe->more() ) + { + const SMDS_MeshElement* elem = itFe->next(); + MYASSERT(elem); + initSet[i].insert(elem); + } + i++; } - std::set *retSet = intersectionOfSets( initSet, numberOfSets ); + set *retSet = intersectionOfSets( initSet, numberOfSets ); delete [] initSet; return retSet; } /////////////////////////////////////////////////////////////////////////////// -/// Return the std::list of nodes used only by the given elements +/// Return the list of nodes used only by the given elements /////////////////////////////////////////////////////////////////////////////// -static -std::set *getExclusiveNodes(std::set& elements) +static set * getExclusiveNodes(set& elements) { - std::set * toReturn = new std::set(); - std::set::iterator itElements = elements.begin(); + set * toReturn=new set(); + set::iterator itElements=elements.begin(); - while( itElements != elements.end() ) + while(itElements!=elements.end()) { - SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator(); + SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); itElements++; - while( itNodes->more() ) + while(itNodes->more()) { - const SMDS_MeshNode * n = itNodes->next(); + const SMDS_MeshNode * n=static_cast(itNodes->next()); SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); - std::set s; - while ( itFe->more() ) - s.insert( itFe->next() ); - if ( s == elements ) toReturn->insert(n); + set s; + while(itFe->more()) + s.insert(itFe->next()); + if(s==elements) toReturn->insert(n); } } return toReturn; @@ -1699,14 +3117,14 @@ std::set *getExclusiveNodes(std::set& setOfChildren, - const SMDS_MeshElement * element, - std::set& nodes) +void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren, + const SMDS_MeshElement * element, + set& nodes) { switch(element->GetType()) { case SMDSAbs_Node: - throw SALOME_Exception("Internal Error: This should not happen"); + MESSAGE("Internal Error: This should not happen"); break; case SMDSAbs_0DElement: case SMDSAbs_Ball: @@ -1738,8 +3156,28 @@ void SMDS_Mesh::addChildrenWithNodes(std::set& setOfChi break; } } + if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } } break; case SMDSAbs_Volume: + { + if(hasConstructionFaces()) + { + SMDS_ElemIteratorPtr ite=element->facesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + else if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + } case SMDSAbs_NbElementTypes: case SMDSAbs_All: break; } @@ -1750,10 +3188,10 @@ void SMDS_Mesh::addChildrenWithNodes(std::set& setOfChi ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, - const bool removenodes) + const bool removenodes) { - std::vector removedElems; - std::vector removedNodes; + list removedElems; + list removedNodes; RemoveElement( elem, removedElems, removedNodes, removenodes ); } @@ -1763,91 +3201,169 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, ///@param removedNodes to be filled with all removed nodes ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, - std::vector& removedElems, - std::vector& removedNodes, - bool removenodes) +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + list& removedElems, + list& removedNodes, + bool removenodes) { // get finite elements built on elem - std::set * s1; + set * s1; if ( (elem->GetType() == SMDSAbs_0DElement) - || (elem->GetType() == SMDSAbs_Ball) - || (elem->GetType() == SMDSAbs_Edge) - || (elem->GetType() == SMDSAbs_Face) - || (elem->GetType() == SMDSAbs_Volume) ) - { - s1 = new std::set (); - s1->insert(elem); - } + || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges()) + || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces()) + || (elem->GetType() == SMDSAbs_Volume) ) + { + s1 = new set (); + s1->insert(elem); + } else s1 = getFinitElements(elem); // get exclusive nodes (which would become free afterwards) - std::set * s2; + set * s2; if (elem->GetType() == SMDSAbs_Node) // a node is removed - { - // do not remove nodes except elem - s2 = new std::set (); - s2->insert(elem); - removenodes = true; - } + { + // do not remove nodes except elem + s2 = new set (); + s2->insert(elem); + removenodes = true; + } else s2 = getExclusiveNodes(*s1); // form the set of finite and construction elements to remove - std::set s3; - std::set::iterator it = s1->begin(); + set s3; + set::iterator it = s1->begin(); while (it != s1->end()) - { - addChildrenWithNodes(s3, *it, *s2); - s3.insert(*it); - it++; - } + { + addChildrenWithNodes(s3, *it, *s2); + s3.insert(*it); + it++; + } if (elem->GetType() != SMDSAbs_Node) s3.insert(elem); // remove finite and construction elements - for( it = s3.begin();it != s3.end(); ++it ) - { - // Remove element from of its nodes - SMDS_NodeIteratorPtr itn = (*it)->nodeIterator(); - while (itn->more()) + it = s3.begin(); + while (it != s3.end()) { - SMDS_MeshNode * n = const_cast (itn->next()); - n->RemoveInverseElement((*it)); - } - - int vtkid = (*it)->GetVtkID(); - - switch ((*it)->GetType()) { - case SMDSAbs_Node: - throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen")); - break; - case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break; - case SMDSAbs_Face: myInfo.RemoveFace(*it); break; - case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break; - case SMDSAbs_Ball: myInfo.myNbBalls--; break; - case SMDSAbs_0DElement: myInfo.myNb0DElements--; break; - case SMDSAbs_All: // avoid compilation warning - case SMDSAbs_NbElementTypes: break; - } - - myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it )); + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = (*it)->nodesIterator(); + while (itn->more()) + { + SMDS_MeshNode * n = static_cast (const_cast (itn->next())); + n->RemoveInverseElement((*it)); + } + int IdToRemove = (*it)->GetID(); + int vtkid = (*it)->getVtkId(); + switch ((*it)->GetType()) + { + case SMDSAbs_Node: + MYASSERT("Internal Error: This should not happen"); + break; + case SMDSAbs_0DElement: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ? + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + delete (*it); + break; + case SMDSAbs_Edge: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveEdge(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkEdge* vtkElem = dynamic_cast(*it)) + myEdgePool->destroy((SMDS_VtkEdge*) vtkElem); + else { + ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse + delete (*it); + } + break; + case SMDSAbs_Face: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveFace(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkFace* vtkElem = dynamic_cast(*it)) + myFacePool->destroy((SMDS_VtkFace*) vtkElem); + else { + ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse + delete (*it); + } + break; + case SMDSAbs_Volume: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveVolume(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkVolume* vtkElem = dynamic_cast(*it)) + myVolumePool->destroy((SMDS_VtkVolume*) vtkElem); + else { + ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse + delete (*it); + } + break; + case SMDSAbs_Ball: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_BallElement* vtkElem = dynamic_cast(*it)) + myBallPool->destroy(const_cast( vtkElem )); + else { + ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse + delete (*it); + } + break; - if (vtkid >= 0) - { - this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); + case SMDSAbs_All: // avoid compilation warning + case SMDSAbs_NbElementTypes: break; + } + if (vtkid >= 0) + { + this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); + } + it++; } - } // remove exclusive (free) nodes if (removenodes) { - for ( it = s2->begin(); it != s2->end(); ++it ) + it = s2->begin(); + while (it != s2->end()) { - myInfo.myNbNodes--; - myNodeFactory->Free( (*it) ); + int IdToRemove = (*it)->GetID(); + if (IdToRemove >= 0) + { + myNodes[IdToRemove] = 0; + myInfo.myNbNodes--; + } + myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId()); removedNodes.push_back((*it)); + if (const SMDS_MeshNode* vtkElem = dynamic_cast(*it)) + { + ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodePool->destroy((SMDS_MeshNode*) vtkElem); + } + else + delete (*it); + it++; } } @@ -1861,60 +3377,95 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) { - const int vtkId = elem->GetVtkID(); + int elemId = elem->GetID(); + int vtkId = elem->getVtkId(); SMDSAbs_ElementType aType = elem->GetType(); + SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem); if ( aType == SMDSAbs_Node ) { // only free node can be removed by this method - const SMDS_MeshNode* n = static_cast( elem ); + const SMDS_MeshNode* n = static_cast(todest); if ( n->NbInverseElements() == 0 ) { // free node + myNodes[elemId] = 0; myInfo.myNbNodes--; - myNodeFactory->Free( n ); - } - else - { - throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" )); + ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( 0, -1, -1 ); // avoid reuse + myNodePool->destroy(static_cast(todest)); + myNodeIDFactory->ReleaseID(elemId, vtkId); } } else { + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; + // Remove element from of its nodes - SMDS_NodeIteratorPtr itn = elem->nodeIterator(); + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); while (itn->more()) { - SMDS_MeshNode * n = const_cast(itn->next()); + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); n->RemoveInverseElement(elem); } // in meshes without descendants elements are always free switch (aType) { - case SMDSAbs_0DElement: myInfo.remove(elem); break; - case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break; - case SMDSAbs_Face: myInfo.RemoveFace(elem); break; - case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break; - case SMDSAbs_Ball: myInfo.remove(elem); break; - default: break; + case SMDSAbs_0DElement: + myCells[elemId] = 0; + myInfo.remove(elem); + delete elem; + elem = 0; + break; + case SMDSAbs_Edge: + myCells[elemId] = 0; + myInfo.RemoveEdge(elem); + myEdgePool->destroy(static_cast(todest)); + break; + case SMDSAbs_Face: + myCells[elemId] = 0; + myInfo.RemoveFace(elem); + myFacePool->destroy(static_cast(todest)); + break; + case SMDSAbs_Volume: + myCells[elemId] = 0; + myInfo.RemoveVolume(elem); + myVolumePool->destroy(static_cast(todest)); + break; + case SMDSAbs_Ball: + myCells[elemId] = 0; + myInfo.remove(elem); + myBallPool->destroy(static_cast(todest)); + break; + default: + break; } - myCellFactory->Free( elem ); + myElementIDFactory->ReleaseID(elemId, vtkId); this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); + // --- to do: keep vtkid in a list of reusable cells + + if ( elem ) + ((SMDS_MeshElement*) elem)->init( 0, -1, -1 ); // avoid reuse } } -//======================================================================= /*! * Checks if the element is present in mesh. + * Useful to determine dead pointers. */ -//======================================================================= - bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const { - if ( !elem || elem->IsNull() ) - return false; - - if ( elem->GetType() == SMDSAbs_Node ) - return ( elem == myNodeFactory->FindElement( elem->GetID() )); - - return ( elem == myCellFactory->FindElement( elem->GetID() )); + // we should not rely on validity of *elem, so iterate on containers + // of all types in the hope of finding somewhere there + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + if (elem == itn->next()) + return true; + SMDS_ElemIteratorPtr ite = elementsIterator(); + while (ite->more()) + if (elem == ite->next()) + return true; + return false; } //======================================================================= @@ -1924,7 +3475,7 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const int SMDS_Mesh::MaxNodeID() const { - return myNodeFactory->GetMaxID(); + return myNodeIDFactory->GetMaxID(); } //======================================================================= @@ -1934,7 +3485,7 @@ int SMDS_Mesh::MaxNodeID() const int SMDS_Mesh::MinNodeID() const { - return myNodeFactory->GetMinID(); + return myNodeIDFactory->GetMinID(); } //======================================================================= @@ -1944,7 +3495,7 @@ int SMDS_Mesh::MinNodeID() const int SMDS_Mesh::MaxElementID() const { - return myCellFactory->GetMaxID(); + return myElementIDFactory->GetMaxID(); } //======================================================================= @@ -1954,7 +3505,7 @@ int SMDS_Mesh::MaxElementID() const int SMDS_Mesh::MinElementID() const { - return myCellFactory->GetMinID(); + return myElementIDFactory->GetMinID(); } //======================================================================= @@ -1962,12 +3513,39 @@ int SMDS_Mesh::MinElementID() const //purpose : Renumber all nodes or elements. //======================================================================= -// void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) -// { -// if ( deltaID == 0 ) -// return; +void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +{ + if ( deltaID == 0 ) + return; -// } + SMDS_MeshNodeIDFactory * idFactory = + isNodes ? myNodeIDFactory : myElementIDFactory; + + // get existing elements in the order of ID increasing + map elemMap; + SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator(); + while ( idElemIt->more() ) { + SMDS_MeshElement* elem = const_cast(idElemIt->next()); + int id = elem->GetID(); + elemMap.insert(map::value_type(id, elem)); + } + // release their ids + map::iterator elemIt = elemMap.begin(); + idFactory->Clear(); +// for ( ; elemIt != elemMap.end(); elemIt++ ) +// { +// int id = (*elemIt).first; +// idFactory->ReleaseID( id ); +// } + // set new IDs + int ID = startID; + elemIt = elemMap.begin(); + for ( ; elemIt != elemMap.end(); elemIt++ ) + { + idFactory->BindID( ID, (*elemIt).second ); + ID += deltaID; + } +} //======================================================================= //function : GetElementType @@ -1976,13 +3554,19 @@ int SMDS_Mesh::MinElementID() const SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const { - const SMDS_MeshElement* elem = 0; + SMDS_MeshElement* elem = 0; if( iselem ) - elem = myCellFactory->FindElement( id ); + elem = myElementIDFactory->MeshElement( id ); else - elem = myNodeFactory->FindElement( id ); + elem = myNodeIDFactory->MeshElement( id ); - return elem ? elem->GetType() : SMDSAbs_All; + if( !elem ) + { + //throw SALOME_Exception(LOCALIZED ("this element isn't exist")); + return SMDSAbs_All; + } + else + return elem->GetType(); } @@ -2001,10 +3585,11 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) //======================================================================= SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) { - return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1), - myNodeFactory->FindNode(n2), - myNodeFactory->FindNode(n12), - ID); + return SMDS_Mesh::AddEdgeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + ID); } //======================================================================= @@ -2015,7 +3600,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n12) { - return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID()); + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); } //======================================================================= @@ -2025,17 +3610,36 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n12, - int ID) + int ID) { if ( !n1 || !n2 || !n12 ) return 0; - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + // --- retrieve nodes ID + myNodeIds.resize(3); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n12->getVtkId(); + + SMDS_MeshEdge * edge = 0; + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(myNodeIds, this); + if (!this->registerElement(ID,edgevtk)) { - cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 ); - myInfo.myNbQuadEdges++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; } - return 0; + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbQuadEdges++; + + // if (!registerElement(ID, edge)) { + // RemoveElement(edge, false); + // edge = NULL; + // } + return edge; + } @@ -2051,7 +3655,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n31) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, - myCellFactory->GetFreeID()); + myElementIDFactory->GetFreeID()); } //======================================================================= @@ -2061,13 +3665,14 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n12,int n23,int n31, int ID) { - return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n31), - ID); + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31), + ID); } //======================================================================= @@ -2082,16 +3687,42 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n31, int ID) { - if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0; - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0; + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else { - cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 ); + // --- retrieve nodes ID + myNodeIds.resize(6); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n12->getVtkId(); + myNodeIds[4] = n23->getVtkId(); + myNodeIds[5] = n31->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadTriangles++; - return static_cast( cell ); + + // if (!registerElement(ID, face)) { + // RemoveElement(face, false); + // face = NULL; + // } + return face; } - return 0; } @@ -2108,7 +3739,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * nCenter) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter, - myCellFactory->GetFreeID()); + myElementIDFactory->GetFreeID()); } //======================================================================= @@ -2118,14 +3749,15 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n12,int n23,int n31, int nCenter, int ID) { - return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n31), - myNodeFactory->FindNode(nCenter), - ID); + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter), + ID); } //======================================================================= @@ -2142,15 +3774,42 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, int ID) { if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0; - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else { - cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter ); + // --- retrieve nodes ID + myNodeIds.resize(7); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n12->getVtkId(); + myNodeIds[4] = n23->getVtkId(); + myNodeIds[5] = n31->getVtkId(); + myNodeIds[6] = nCenter->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbBiQuadTriangles++; - return static_cast( cell ); + + // if (!registerElement(ID, face)) { + // RemoveElement(face, false); + // face = NULL; + // } + return face; } - return 0; } @@ -2168,7 +3827,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * n41) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, - myCellFactory->GetFreeID()); + myElementIDFactory->GetFreeID()); } //======================================================================= @@ -2178,15 +3837,16 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n34,int n41, int ID) { - return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n34), - myNodeFactory->FindNode(n41), - ID); + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41), + ID); } //======================================================================= @@ -2204,15 +3864,43 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, int ID) { if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else { - cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 ); + // --- retrieve nodes ID + myNodeIds.resize(8); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n12->getVtkId(); + myNodeIds[5] = n23->getVtkId(); + myNodeIds[6] = n34->getVtkId(); + myNodeIds[7] = n41->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadQuadrangles++; - return static_cast( cell ); + + // if (!registerElement(ID, face)) { + // RemoveElement(face, false); + // face = NULL; + // } + return face; } - return 0; } //======================================================================= @@ -2230,7 +3918,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, const SMDS_MeshNode * nCenter) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter, - myCellFactory->GetFreeID()); + myElementIDFactory->GetFreeID()); } //======================================================================= @@ -2240,16 +3928,17 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n34,int n41, int nCenter, int ID) { - return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n34), - myNodeFactory->FindNode(n41), - myNodeFactory->FindNode(nCenter), - ID); + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter), + ID); } //======================================================================= @@ -2268,16 +3957,44 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, int ID) { if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0; - if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else { - cell->init( SMDSEntity_BiQuad_Quadrangle, - /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter ); + // --- retrieve nodes ID + myNodeIds.resize(9); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n12->getVtkId(); + myNodeIds[5] = n23->getVtkId(); + myNodeIds[6] = n34->getVtkId(); + myNodeIds[7] = n41->getVtkId(); + myNodeIds[8] = nCenter->getVtkId(); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(myNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbBiQuadQuadrangles++; - return static_cast( cell ); + + // if (!registerElement(ID, face)) { + // RemoveElement(face, false); + // face = NULL; + // } + return face; } - return 0; } @@ -2296,8 +4013,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, - n31, n14, n24, n34, myCellFactory->GetFreeID()); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, + n31, n14, n24, n34, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2308,17 +4028,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n31, int n14,int n24,int n34, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n31), - myNodeFactory->FindNode(n14), - myNodeFactory->FindNode(n24), - myNodeFactory->FindNode(n34), - ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + ID); } //======================================================================= @@ -2339,16 +4060,42 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, { if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + // --- retrieve nodes ID + myNodeIds.resize(10); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n3->getVtkId(); + myNodeIds[2] = n2->getVtkId(); + myNodeIds[3] = n4->getVtkId(); + + myNodeIds[4] = n31->getVtkId(); + myNodeIds[5] = n23->getVtkId(); + myNodeIds[6] = n12->getVtkId(); + + myNodeIds[7] = n14->getVtkId(); + myNodeIds[8] = n34->getVtkId(); + myNodeIds[9] = n24->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_Quad_Tetra, - /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 ); - myInfo.myNbQuadTetras++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbQuadTetras++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; } @@ -2370,8 +4117,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, - n15, n25, n35, n45, myCellFactory->GetFreeID()); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, + n15, n25, n35, n45, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2382,20 +4133,21 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int int n12,int n23,int n34,int n41, int n15,int n25,int n35,int n45, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n5) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n34), - myNodeFactory->FindNode(n41), - myNodeFactory->FindNode(n15), - myNodeFactory->FindNode(n25), - myNodeFactory->FindNode(n35), - myNodeFactory->FindNode(n45), - ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + ID); } //======================================================================= @@ -2420,16 +4172,45 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 || !n34 || !n41 || !n15 || !n25 || !n35 || !n45) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + // --- retrieve nodes ID + myNodeIds.resize(13); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n4->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n2->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + + myNodeIds[5] = n41->getVtkId(); + myNodeIds[6] = n34->getVtkId(); + myNodeIds[7] = n23->getVtkId(); + myNodeIds[8] = n12->getVtkId(); + + myNodeIds[9] = n15->getVtkId(); + myNodeIds[10] = n45->getVtkId(); + myNodeIds[11] = n35->getVtkId(); + myNodeIds[12] = n25->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_Quad_Pyramid, - /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45); - myInfo.myNbQuadPyramids++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbQuadPyramids++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; } @@ -2453,8 +4234,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, - n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID()); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2467,22 +4252,23 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n45,int n56,int n64, int n14,int n25,int n36, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n5) , - myNodeFactory->FindNode(n6) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n31), - myNodeFactory->FindNode(n45), - myNodeFactory->FindNode(n56), - myNodeFactory->FindNode(n64), - myNodeFactory->FindNode(n14), - myNodeFactory->FindNode(n25), - myNodeFactory->FindNode(n36), - ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36), + ID); } //======================================================================= @@ -2509,16 +4295,49 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + // --- retrieve nodes ID + myNodeIds.resize(15); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n6->getVtkId(); + + myNodeIds[6] = n12->getVtkId(); + myNodeIds[7] = n23->getVtkId(); + myNodeIds[8] = n31->getVtkId(); + + myNodeIds[9] = n45->getVtkId(); + myNodeIds[10] = n56->getVtkId(); + myNodeIds[11] = n64->getVtkId(); + + myNodeIds[12] = n14->getVtkId(); + myNodeIds[13] = n25->getVtkId(); + myNodeIds[14] = n36->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15, - n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 ); - myInfo.myNbQuadPrisms++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbQuadPrisms++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; } //======================================================================= @@ -2544,9 +4363,13 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2356, const SMDS_MeshNode * n1346) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, - n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, - myCellFactory->GetFreeID()); + //MESSAGE("AddVolume penta18"); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2560,25 +4383,27 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n14,int n25,int n36, int n1245, int n2356, int n1346, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) , - myNodeFactory->FindNode(n2) , - myNodeFactory->FindNode(n3) , - myNodeFactory->FindNode(n4) , - myNodeFactory->FindNode(n5) , - myNodeFactory->FindNode(n6) , - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n31), - myNodeFactory->FindNode(n45), - myNodeFactory->FindNode(n56), - myNodeFactory->FindNode(n64), - myNodeFactory->FindNode(n14), - myNodeFactory->FindNode(n25), - myNodeFactory->FindNode(n36), - myNodeFactory->FindNode(n1245), - myNodeFactory->FindNode(n2356), - myNodeFactory->FindNode(n1346), - ID); + //MESSAGE("AddVolumeWithID penta18 " << ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346), + ID); } //======================================================================= @@ -2609,16 +4434,53 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + // --- retrieve nodes ID + myNodeIds.resize(18); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n6->getVtkId(); + + myNodeIds[6] = n12->getVtkId(); + myNodeIds[7] = n23->getVtkId(); + myNodeIds[8] = n31->getVtkId(); + + myNodeIds[9] = n45->getVtkId(); + myNodeIds[10] = n56->getVtkId(); + myNodeIds[11] = n64->getVtkId(); + + myNodeIds[12] = n14->getVtkId(); + myNodeIds[13] = n25->getVtkId(); + myNodeIds[14] = n36->getVtkId(); + + myNodeIds[15] = n1245->getVtkId(); + myNodeIds[16] = n2356->getVtkId(); + myNodeIds[17] = n1346->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6, - n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 ); - myInfo.myNbBiQuadPrisms++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbBiQuadPrisms++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; } @@ -2647,9 +4509,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n37, const SMDS_MeshNode * n48) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, - n56, n67, n78, n85, n15, n26, n37, n48, - myCellFactory->GetFreeID()); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2662,27 +4527,28 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n56,int n67,int n78,int n85, int n15,int n26,int n37,int n48, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1), - myNodeFactory->FindNode(n2), - myNodeFactory->FindNode(n3), - myNodeFactory->FindNode(n4), - myNodeFactory->FindNode(n5), - myNodeFactory->FindNode(n6), - myNodeFactory->FindNode(n7), - myNodeFactory->FindNode(n8), - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n34), - myNodeFactory->FindNode(n41), - myNodeFactory->FindNode(n56), - myNodeFactory->FindNode(n67), - myNodeFactory->FindNode(n78), - myNodeFactory->FindNode(n85), - myNodeFactory->FindNode(n15), - myNodeFactory->FindNode(n26), - myNodeFactory->FindNode(n37), - myNodeFactory->FindNode(n48), - ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48), + ID); } //======================================================================= @@ -2714,16 +4580,54 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + return 0; + // creation quadratic faces - not implemented + } + // --- retrieve nodes ID + myNodeIds.resize(20); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n4->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n2->getVtkId(); + + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n8->getVtkId(); + myNodeIds[6] = n7->getVtkId(); + myNodeIds[7] = n6->getVtkId(); + + myNodeIds[8] = n41->getVtkId(); + myNodeIds[9] = n34->getVtkId(); + myNodeIds[10] = n23->getVtkId(); + myNodeIds[11] = n12->getVtkId(); + + myNodeIds[12] = n85->getVtkId(); + myNodeIds[13] = n78->getVtkId(); + myNodeIds[14] = n67->getVtkId(); + myNodeIds[15] = n56->getVtkId(); + + myNodeIds[16] = n15->getVtkId(); + myNodeIds[17] = n48->getVtkId(); + myNodeIds[18] = n37->getVtkId(); + myNodeIds[19] = n26->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8, - n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 ); - myInfo.myNbQuadHexas++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbQuadHexas++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; } //======================================================================= @@ -2758,10 +4662,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5678, const SMDS_MeshNode * nCenter) { - return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, - n56, n67, n78, n85, n15, n26, n37, n48, - n1234, n1256, n2367, n3478, n1458, n5678, nCenter, - myCellFactory->GetFreeID()); + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, + n1234, n1256, n2367, n3478, n1458, n5678, nCenter, + ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } //======================================================================= @@ -2776,39 +4684,40 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n1234,int n1256,int n2367,int n3478, int n1458,int n5678,int nCenter, int ID) { - return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1), - myNodeFactory->FindNode(n2), - myNodeFactory->FindNode(n3), - myNodeFactory->FindNode(n4), - myNodeFactory->FindNode(n5), - myNodeFactory->FindNode(n6), - myNodeFactory->FindNode(n7), - myNodeFactory->FindNode(n8), - myNodeFactory->FindNode(n12), - myNodeFactory->FindNode(n23), - myNodeFactory->FindNode(n34), - myNodeFactory->FindNode(n41), - myNodeFactory->FindNode(n56), - myNodeFactory->FindNode(n67), - myNodeFactory->FindNode(n78), - myNodeFactory->FindNode(n85), - myNodeFactory->FindNode(n15), - myNodeFactory->FindNode(n26), - myNodeFactory->FindNode(n37), - myNodeFactory->FindNode(n48), - myNodeFactory->FindNode(n1234), - myNodeFactory->FindNode(n1256), - myNodeFactory->FindNode(n2367), - myNodeFactory->FindNode(n3478), - myNodeFactory->FindNode(n1458), - myNodeFactory->FindNode(n5678), - myNodeFactory->FindNode(nCenter), - ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter), + ID); } //======================================================================= //function : AddVolumeWithID -//purpose : 2d order Hexahedrons with 27 nodes +//purpose : 2d order Hexahedrons with 20 nodes //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -2843,20 +4752,61 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 || !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter ) return 0; - if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - - if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID )) + if(hasConstructionFaces()) { + return 0; + // creation quadratic faces - not implemented + } + // --- retrieve nodes ID + myNodeIds.resize(27); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n4->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + myNodeIds[3] = n2->getVtkId(); + + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n8->getVtkId(); + myNodeIds[6] = n7->getVtkId(); + myNodeIds[7] = n6->getVtkId(); + + myNodeIds[8] = n41->getVtkId(); + myNodeIds[9] = n34->getVtkId(); + myNodeIds[10] = n23->getVtkId(); + myNodeIds[11] = n12->getVtkId(); + + myNodeIds[12] = n85->getVtkId(); + myNodeIds[13] = n78->getVtkId(); + myNodeIds[14] = n67->getVtkId(); + myNodeIds[15] = n56->getVtkId(); + + myNodeIds[16] = n15->getVtkId(); + myNodeIds[17] = n48->getVtkId(); + myNodeIds[18] = n37->getVtkId(); + myNodeIds[19] = n26->getVtkId(); + + myNodeIds[20] = n1256->getVtkId(); + myNodeIds[21] = n3478->getVtkId(); + myNodeIds[22] = n1458->getVtkId(); + myNodeIds[23] = n2367->getVtkId(); + myNodeIds[24] = n1234->getVtkId(); + myNodeIds[25] = n5678->getVtkId(); + myNodeIds[26] = nCenter->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) { - cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8, - n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48, - n1234, n1256, n2367, n3478, n1458, n5678, nCenter); - myInfo.myNbTriQuadHexas++; - return static_cast( cell ); + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; } - return 0; + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbTriQuadHexas++; + + return volvtk; } -void SMDS_Mesh::dumpGrid(std::string ficdump) +void SMDS_Mesh::dumpGrid(string ficdump) { // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); // aWriter->SetFileName(ficdump.c_str()); @@ -2867,7 +4817,7 @@ void SMDS_Mesh::dumpGrid(std::string ficdump) // } // aWriter->Delete(); ficdump = ficdump + "_connectivity"; - std::ofstream ficcon(ficdump.c_str(), ios::out); + ofstream ficcon(ficdump.c_str(), ios::out); int nbPoints = myGrid->GetNumberOfPoints(); ficcon << "-------------------------------- points " << nbPoints << endl; for (int i=0; imyCompactTime = this->myModifTime; - - bool idsChange = ( myNodeFactory->CompactChangePointers() || - myCellFactory->CompactChangePointers() ); - if ( idsChange ) - { - std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); - for ( ; holder != myElemHolders.end(); ++holder ) - (*holder)->beforeCompacting(); - } - - // remove "holes" in SMDS numeration - std::vector idNodesOldToNew, idCellsNewToOld; - myNodeFactory->Compact( idNodesOldToNew ); - myCellFactory->Compact( idCellsNewToOld ); - - // make VTK IDs correspond to SMDS IDs - int newNodeSize = myNodeFactory->NbUsedElements(); - int newCellSize = myCellFactory->NbUsedElements(); - myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize ); - - std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin(); - for ( ; holder != myElemHolders.end(); ++holder ) - if ( idsChange ) - (*holder)->restoreElements( idNodesOldToNew, idCellsNewToOld ); - else - (*holder)->compact(); - - return; } -int SMDS_Mesh::FromVtkToSmds( int vtkid ) const +int SMDS_Mesh::fromVtkToSmds(int vtkid) { - return myCellFactory->FromVtkToSmds( vtkid ); + if (vtkid >= 0 && vtkid < (int)myCellIdVtkToSmds.size()) + return myCellIdVtkToSmds[vtkid]; + throw SALOME_Exception(LOCALIZED ("vtk id out of bounds")); } +// void SMDS_Mesh::updateBoundingBox() +// { +// xmin = 0; xmax = 0; +// ymin = 0; ymax = 0; +// zmin = 0; zmax = 0; +// vtkPoints *points = myGrid->GetPoints(); +// int myNodesSize = this->myNodes.size(); +// for (int i = 0; i < myNodesSize; i++) +// { +// if (SMDS_MeshNode *n = myNodes[i]) +// { +// double coords[3]; +// points->GetPoint(n->myVtkID, coords); +// if (coords[0] < xmin) xmin = coords[0]; +// else if (coords[0] > xmax) xmax = coords[0]; +// if (coords[1] < ymin) ymin = coords[1]; +// else if (coords[1] > ymax) ymax = coords[1]; +// if (coords[2] < zmin) zmin = coords[2]; +// else if (coords[2] > zmax) zmax = coords[2]; +// } +// } +// } + double SMDS_Mesh::getMaxDim() { double dmax = 1.e-3; @@ -2967,12 +4914,7 @@ vtkMTimeType SMDS_Mesh::GetMTime() const return this->myModifTime; } -bool SMDS_Mesh::IsCompacted() -{ - return ( this->myCompactTime == this->myModifTime ); -} - -void SMDS_Mesh::setNbShapes( size_t nbShapes ) +bool SMDS_Mesh::isCompacted() { - myNodeFactory->SetNbShapes( nbShapes ); + return this->myCompactTime == this->myModifTime; } diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 38952f78c..00b31a33c 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -29,46 +29,62 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_BallElement.hxx" -#include "SMDS_ElemIterator.hxx" -#include "SMDS_Mesh0DElement.hxx" +#include "SMDS_MeshNode.hxx" #include "SMDS_MeshCell.hxx" +#include "SMDS_Mesh0DElement.hxx" #include "SMDS_MeshEdge.hxx" #include "SMDS_MeshFace.hxx" -#include "SMDS_MeshInfo.hxx" -#include "SMDS_MeshNode.hxx" #include "SMDS_MeshVolume.hxx" +#include "SMDS_MeshNodeIDFactory.hxx" +#include "SMDS_MeshElementIDFactory.hxx" +#include "SMDS_MeshInfo.hxx" +#include "SMDS_ElemIterator.hxx" +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VtkEdge.hxx" +#include "SMDS_VtkFace.hxx" +#include "SMDS_VtkVolume.hxx" +#include "ObjectPool.hxx" #include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_BallElement.hxx" +#include #include #include #include +#include +#include -class SMDS_ElementHolder; -class SMDS_ElementFactory; -class SMDS_NodeFactory; +#include "Utils_SALOME_Exception.hxx" + +#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified")); class SMDS_EXPORT SMDS_Mesh : public SMDS_MeshObject { public: + friend class SMDS_MeshIDFactory; + friend class SMDS_MeshNodeIDFactory; + friend class SMDS_MeshElementIDFactory; + friend class SMDS_MeshVolumeVtkNodes; + friend class SMDS_MeshNode; SMDS_Mesh(); + //! to retrieve this SMDS_Mesh instance from its elements (index stored in SMDS_Elements) + static std::vector _meshList; + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid - inline SMDS_UnstructuredGrid* GetGrid() { return myGrid; } + inline SMDS_UnstructuredGrid* getGrid() { return myGrid; } + inline int getMeshId() { return myMeshId; } - virtual SMDS_NodeIteratorPtr nodesIterator () const; - virtual SMDS_EdgeIteratorPtr edgesIterator () const; - virtual SMDS_FaceIteratorPtr facesIterator () const; - virtual SMDS_VolumeIteratorPtr volumesIterator() const; + virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const; - virtual SMDS_NodeIteratorPtr shapeNodesIterator (int shapeID, size_t nbElemsToReturn=-1) const; - virtual SMDS_ElemIteratorPtr shapeElementsIterator(int shapeID, size_t nbElemsToReturn=-1) const; - SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) const; SMDS_Mesh *AddSubMesh(); @@ -121,6 +137,21 @@ public: const SMDS_MeshNode * n3, const SMDS_MeshNode * n4); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3); + + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4); // 2d order triangle of 6 nodes virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, @@ -262,6 +293,38 @@ public: const SMDS_MeshNode * n7, const SMDS_MeshNode * n8); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6); // hexagonal prism virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, @@ -576,24 +639,33 @@ public: virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID (const std::vector & nodes, const std::vector & quantities, - const int ID); + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolume - (const std::vector & nodes, - const std::vector & quantities); + (const std::vector & nodes, + const std::vector & quantities); virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector& vtkNodeIds); + virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, + const int ID); + virtual SMDS_MeshFace* AddFaceFromVtkIds(const std::vector& vtkNodeIds); + virtual SMDS_MeshFace* AddFaceFromVtkIdsWithID(const std::vector& vtkNodeIds, + const int ID); virtual void MoveNode(const SMDS_MeshNode *n, double x, double y, double z); - virtual void RemoveElement(const SMDS_MeshElement * elem, - std::vector& removedElems, - std::vector& removedNodes, - const bool removenodes = false); + virtual void RemoveElement(const SMDS_MeshElement * elem, + std::list& removedElems, + std::list& removedNodes, + const bool removenodes = false); virtual void RemoveElement(const SMDS_MeshElement * elem, bool removenodes = false); virtual void RemoveNode(const SMDS_MeshNode * node); + virtual void Remove0DElement(const SMDS_Mesh0DElement * elem0d); + virtual void RemoveEdge(const SMDS_MeshEdge * edge); + virtual void RemoveFace(const SMDS_MeshFace * face); + virtual void RemoveVolume(const SMDS_MeshVolume * volume); /*! Remove only the given element and only if it is free. * Method does not work for meshes with descendants. @@ -609,23 +681,27 @@ public: bool ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes); + bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, + const std::vector& nodes, + const std::vector & quantities); - //virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); + virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. - - virtual void CompactMesh(); - bool IsCompacted(); - - template - static const ELEMTYPE* DownCast( const SMDS_MeshElement* e ) - { - return (( e && !e->IsNull() && ELEMTYPE::Type() == e->GetType() ) ? - static_cast(e) : 0 ); - } + virtual void compactMesh(); + virtual void CompactMesh() { compactMesh(); } const SMDS_MeshNode *FindNode(int idnode) const; const SMDS_MeshNode *FindNodeVtk(int idnode) const; - const SMDS_MeshElement *FindElementVtk(int IDelem) const; + const SMDS_Mesh0DElement* Find0DElement(int idnode) const; + const SMDS_BallElement* FindBall(int idnode) const; + const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; + const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4, + int idnode5, int idnode6, int idnode7, int idnode8) const; virtual const SMDS_MeshElement * FindElement(int IDelem) const; static const SMDS_Mesh0DElement* Find0DElement(const SMDS_MeshNode * n); static const SMDS_BallElement* FindBall(const SMDS_MeshNode * n); @@ -656,7 +732,8 @@ public: const SMDS_MeshNode *n7, const SMDS_MeshNode *n8); - static const SMDS_MeshFace* FindFace (const std::vector& nodes); + const SMDS_MeshFace *FindFace(const std::vector& nodes_ids) const; + static const SMDS_MeshFace* FindFace(const std::vector& nodes); static const SMDS_MeshElement* FindElement(const std::vector& nodes, const SMDSAbs_ElementType type=SMDSAbs_All, const bool noMedium=true); @@ -664,8 +741,6 @@ public: std::vector& foundElems, const SMDSAbs_ElementType type=SMDSAbs_All); - virtual bool Contains( const SMDS_MeshElement* elem ) const; - /*! * \brief Raise an exception if free memory (ram+swap) too low * \param doNotRaise - if true, suppres exception, just return free memory size @@ -689,10 +764,36 @@ public: virtual int NbVolumes() const; virtual int NbSubMesh() const; + void DumpNodes() const; + void Dump0DElements() const; + void DumpEdges() const; + void DumpFaces() const; + void DumpVolumes() const; + void DebugStats() const; + virtual ~SMDS_Mesh(); + bool hasConstructionEdges(); + bool hasConstructionFaces(); + bool hasInverseElements(); + void setConstructionEdges(bool); + void setConstructionFaces(bool); + void setInverseElements(bool); + + /*! + * Checks if the element is present in mesh. + * Useful to determine dead pointers. + * Use this function for debug purpose only! Do not check in the code + * using it even in _DEBUG_ mode + */ + bool Contains (const SMDS_MeshElement* elem) const; + + typedef std::vector SetOfNodes; + typedef std::vector SetOfCells; + + //void updateBoundingBox(); double getMaxDim(); - int FromVtkToSmds(int vtkid) const; + int fromVtkToSmds(int vtkid); void dumpGrid(std::string ficdump="dumpGrid"); static int chunkSize; @@ -702,14 +803,44 @@ public: void Modified(); vtkMTimeType GetMTime() const; + bool isCompacted(); protected: SMDS_Mesh(SMDS_Mesh * parent); + SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + int ID); + SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + int ID); + SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3); + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4); + + bool registerElement(int ID, SMDS_MeshElement * element); + void addChildrenWithNodes(std::set& setOfChildren, const SMDS_MeshElement * element, std::set& nodes); + inline void adjustmyCellsCapacity(int ID) + { + assert(ID >= 0); + myElementIDFactory->adjustMaxId(ID); + if (ID >= (int)myCells.size()) + myCells.resize(ID+SMDS_Mesh::chunkSize,0); + } + inline void adjustBoundingBox(double x, double y, double z) { if (x > xmax) xmax = x; @@ -720,29 +851,47 @@ protected: else if (z < zmin) zmin = z; } - void setNbShapes( size_t nbShapes ); - - // Fields PRIVATE + //! index of this SMDS_mesh in the static vector _meshList + int myMeshId; + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid - SMDS_UnstructuredGrid* myGrid; + SMDS_UnstructuredGrid* myGrid; //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new - SMDS_NodeFactory* myNodeFactory; - SMDS_ElementFactory* myCellFactory; + ObjectPool* myNodePool; + + //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new + ObjectPool* myVolumePool; + ObjectPool* myFacePool; + ObjectPool* myEdgePool; + ObjectPool* myBallPool; + + //! SMDS_MeshNodes refer to vtk nodes (vtk id != index in myNodes),store reference to this mesh, and sub-shape + SetOfNodes myNodes; + SetOfCells myCells; + + //! a buffer to speed up elements addition by excluding some memory allocation + std::vector myNodeIds; + + //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users + std::vector myCellIdVtkToSmds; - SMDS_Mesh * myParent; - std::list myChildren; - SMDS_MeshInfo myInfo; + SMDS_Mesh * myParent; + std::list myChildren; + SMDS_MeshNodeIDFactory * myNodeIDFactory; + SMDS_MeshElementIDFactory * myElementIDFactory; + SMDS_MeshInfo myInfo; //! any add, remove or change of node or cell - bool myModified; + bool myModified; //! use a counter to keep track of modifications - unsigned long myModifTime, myCompactTime; + unsigned long myModifTime, myCompactTime; - friend class SMDS_ElementHolder; - std::set< SMDS_ElementHolder* > myElemHolders; + bool myHasConstructionEdges; + bool myHasConstructionFaces; + bool myHasInverseElements; double xmin; double xmax; diff --git a/src/SMDS/SMDS_Mesh0DElement.cxx b/src/SMDS/SMDS_Mesh0DElement.cxx new file mode 100644 index 000000000..8ac7bcc18 --- /dev/null +++ b/src/SMDS/SMDS_Mesh0DElement.cxx @@ -0,0 +1,164 @@ +// Copyright (C) 2007-2016 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_Mesh0DElement.cxx +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_Mesh0DElement.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" + +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_Mesh0DElement +//purpose : +//======================================================================= +SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node) +{ + myNode = node; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= +void SMDS_Mesh0DElement::Print (ostream & OS) const +{ + OS << "0D Element <" << GetID() << "> : (" << myNode << ") " << endl; +} + +//======================================================================= +//function : NbNodes +//purpose : +//======================================================================= +int SMDS_Mesh0DElement::NbNodes() const +{ + return 1; +} + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= +int SMDS_Mesh0DElement::NbEdges() const +{ + return 0; +} + +//======================================================================= +//function : GetType +//purpose : +//======================================================================= +SMDSAbs_ElementType SMDS_Mesh0DElement::GetType() const +{ + return SMDSAbs_0DElement; +} + +vtkIdType SMDS_Mesh0DElement::GetVtkType() const +{ + return VTK_VERTEX; +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= +class SMDS_Mesh0DElement_MyNodeIterator: public SMDS_ElemIterator +{ + const SMDS_MeshNode * myNode; + int myIndex; + public: + SMDS_Mesh0DElement_MyNodeIterator(const SMDS_MeshNode * node): + myNode(node),myIndex(0) {} + + bool more() + { + return myIndex < 1; + } + + const SMDS_MeshElement* next() + { + myIndex++; + if (myIndex == 1) + return myNode; + return NULL; + } +}; + +SMDS_ElemIteratorPtr SMDS_Mesh0DElement::elementsIterator (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_0DElement: + return SMDS_MeshElement::elementsIterator(SMDSAbs_0DElement); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode)))); + } +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_Mesh0DElement::GetNode(const int ind) const +{ + if (ind == 0) + return myNode; + return NULL; +} + +//======================================================================= +//function : ChangeNode +//purpose : +//======================================================================= +bool SMDS_Mesh0DElement::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + if ( nbNodes == 1 ) + { + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + myNode = nodes[0]; + pts[0] = myNode->getVtkId(); + + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; + } + return false; +} diff --git a/src/SMDS/SMDS_Mesh0DElement.hxx b/src/SMDS/SMDS_Mesh0DElement.hxx index 1ba4d4b57..f4b9fa2dd 100644 --- a/src/SMDS/SMDS_Mesh0DElement.hxx +++ b/src/SMDS/SMDS_Mesh0DElement.hxx @@ -28,15 +28,28 @@ #include "SMDS_MeshCell.hxx" -/*! - * \brief 0D mesh element. This type is not allocated. - * It is only used as function argument type to provide more clear semantic. - */ +#include + class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell { public: + SMDS_Mesh0DElement (const SMDS_MeshNode * node); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual void Print (std::ostream & OS) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const {return SMDSEntity_0D;} + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_POINT; } + virtual const SMDS_MeshNode* GetNode (const int ind) const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; - static SMDSAbs_ElementType Type() { return SMDSAbs_0DElement; } + protected: + const SMDS_MeshNode* myNode; }; #endif diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx index ae6d99fad..7175ae5d4 100644 --- a/src/SMDS/SMDS_MeshCell.cxx +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -18,383 +18,21 @@ // #include "SMDS_MeshCell.hxx" +#include "utilities.h" -#include "SMDS_Mesh.hxx" -#include "SMDS_VtkCellIterator.hxx" +int SMDS_MeshCell::nbCells = 0; -#include - -#include - -#include - -#include - -namespace -{ - /*! - * \brief Cell type features - */ - struct CellProps - { - SMDSAbs_EntityType myEntity; - SMDSAbs_ElementType myType; - SMDSAbs_GeometryType myGeom; - bool myIsPoly; - int myNbCornerNodes; - int myNbNodes; - int myNbEdges; - int myNbFaces; - - CellProps() : - myEntity( SMDSEntity_Last ), myType( SMDSAbs_All ), myGeom( SMDSGeom_NONE ), - myIsPoly( 0 ), myNbCornerNodes( 0 ), - myNbNodes( 0 ), myNbEdges( 0 ), myNbFaces ( 0 ) - { - } - void Set( SMDSAbs_EntityType Entity, - SMDSAbs_ElementType Type, - SMDSAbs_GeometryType Geom, - bool IsPoly, - int NbCornerNodes, - int NbNodes, - int NbEdges, - int NbFaces) - { - myEntity = Entity; - myType = Type; - myGeom = Geom; - myIsPoly = IsPoly; - myNbCornerNodes = NbCornerNodes; - myNbNodes = NbNodes; - myNbEdges = NbEdges; - myNbFaces = NbFaces; - } - bool IsQuadratic() const { return myNbNodes > myNbCornerNodes; } - }; - - //! return vector a CellProps - const CellProps& getCellProps( VTKCellType vtkType ) - { - static std::vector< CellProps > theCellProps; - if ( theCellProps.empty() ) - { - theCellProps.resize( VTK_NUMBER_OF_CELL_TYPES ); - CellProps* p = & theCellProps[0]; - p[ VTK_VERTEX ]. - Set( SMDSEntity_0D, SMDSAbs_0DElement, SMDSGeom_POINT, - /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 ); - p[ VTK_LINE ]. - Set( SMDSEntity_Edge, SMDSAbs_Edge, SMDSGeom_EDGE, - /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/2,/*nbE=*/1,/*nbF=*/0 ); - p[ VTK_QUADRATIC_EDGE ]. - Set( SMDSEntity_Quad_Edge, SMDSAbs_Edge, SMDSGeom_EDGE, - /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/3,/*nbE=*/1,/*nbF=*/0 ); - p[ VTK_TRIANGLE ]. - Set( SMDSEntity_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, - /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/3,/*nbE=*/3,/*nbF=*/1 ); - p[ VTK_QUADRATIC_TRIANGLE ]. - Set( SMDSEntity_Quad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, - /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/6,/*nbE=*/3,/*nbF=*/1 ); - p[ VTK_BIQUADRATIC_TRIANGLE ]. - Set( SMDSEntity_BiQuad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, - /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/7,/*nbE=*/3,/*nbF=*/1 ); - p[ VTK_QUAD]. - Set( SMDSEntity_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, - /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/4,/*nbF=*/1 ); - p[ VTK_QUADRATIC_QUAD]. - Set( SMDSEntity_Quad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, - /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/8,/*nbE=*/4,/*nbF=*/1 ); - p[ VTK_BIQUADRATIC_QUAD]. - Set( SMDSEntity_BiQuad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, - /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/9,/*nbE=*/4,/*nbF=*/1 ); - p[ VTK_POLYGON ]. - Set( SMDSEntity_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON, - /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 ); - p[ VTK_QUADRATIC_POLYGON ]. - Set( SMDSEntity_Quad_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON, - /*isPoly=*/1,/*nbCN=*/-2,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 ); - p[ VTK_TETRA ]. - Set( SMDSEntity_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA, - /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/6,/*nbF=*/4 ); - p[ VTK_QUADRATIC_TETRA ]. - Set( SMDSEntity_Quad_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA, - /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/10,/*nbE=*/6,/*nbF=*/4 ); - p[ VTK_PYRAMID ]. - Set( SMDSEntity_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID, - /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/5,/*nbE=*/8,/*nbF=*/5 ); - p[ VTK_QUADRATIC_PYRAMID]. - Set( SMDSEntity_Quad_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID, - /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/13,/*nbE=*/8,/*nbF=*/5 ); - p[ VTK_HEXAHEDRON ]. - Set( SMDSEntity_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, - /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/8,/*nbE=*/12,/*nbF=*/6 ); - p[ VTK_QUADRATIC_HEXAHEDRON ]. - Set( SMDSEntity_Quad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, - /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/20,/*nbE=*/12,/*nbF=*/6 ); - p[ VTK_TRIQUADRATIC_HEXAHEDRON ]. - Set( SMDSEntity_TriQuad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, - /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/27,/*nbE=*/12,/*nbF=*/6 ); - p[ VTK_WEDGE ]. - Set( SMDSEntity_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, - /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/6,/*nbE=*/9,/*nbF=*/5 ); - p[ VTK_QUADRATIC_WEDGE ]. - Set( SMDSEntity_Quad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, - /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/15,/*nbE=*/9,/*nbF=*/5 ); - p[ VTK_BIQUADRATIC_QUADRATIC_WEDGE ]. - Set( SMDSEntity_BiQuad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, - /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/21,/*nbE=*/9,/*nbF=*/5 ); - p[ VTK_HEXAGONAL_PRISM]. - Set( SMDSEntity_Hexagonal_Prism, SMDSAbs_Volume, SMDSGeom_HEXAGONAL_PRISM, - /*isPoly=*/0,/*nbCN=*/12,/*nbN=*/12,/*nbE=*/18,/*nbF=*/8 ); - p[ VTK_POLYHEDRON ]. - Set( SMDSEntity_Polyhedra, SMDSAbs_Volume, SMDSGeom_POLYHEDRA, - /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/-1 ); - p[ VTK_POLY_VERTEX]. - Set( SMDSEntity_Ball, SMDSAbs_Ball, SMDSGeom_BALL, - /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 ); - } - return theCellProps[ vtkType ]; - - } // getCellProps() - - //! return vector a CellProps - const CellProps& getCellProps( SMDSAbs_EntityType entity ) - { - return getCellProps( SMDS_MeshCell::toVtkType( entity )); - } - -} // namespace - -void SMDS_MeshCell::InitStaticMembers() -{ - getCellProps( SMDSEntity_Ball ); - toVtkOrder( SMDSEntity_Ball ); - reverseSmdsOrder( SMDSEntity_Ball, 1 ); - interlacedSmdsOrder( SMDSEntity_Ball, 1 ); - fromVtkOrder( SMDSEntity_Ball ); -} - -void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, int theNbNodes, ... ) -{ - ASSERT( getCellProps( theEntity ).myNbNodes == theNbNodes || - getCellProps( theEntity ).myIsPoly); - - va_list vl; - va_start( vl, theNbNodes ); - - vtkIdType vtkIds[ VTK_CELL_SIZE ]; - typedef const SMDS_MeshNode* node_t; - - const std::vector& interlace = toVtkOrder( theEntity ); - if ((int) interlace.size() == theNbNodes ) - { - const SMDS_MeshNode* nodes[ VTK_CELL_SIZE ]; - for ( int i = 0; i < theNbNodes; i++ ) - nodes[i] = va_arg( vl, node_t ); - - for ( int i = 0; i < theNbNodes; i++ ) - vtkIds[i] = nodes[ interlace[i] ]->GetVtkID(); - } - else - { - for ( int i = 0; i < theNbNodes; i++ ) - vtkIds[i] = va_arg( vl, node_t )->GetVtkID(); - } - va_end( vl ); - - int vtkType = toVtkType( theEntity ); - int vtkID = getGrid()->InsertNextLinkedCell( vtkType, theNbNodes, vtkIds ); - setVtkID( vtkID ); -} - -void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, - const std::vector& nodes ) -{ - std::vector< vtkIdType > vtkIds( nodes.size() ); - for ( size_t i = 0; i < nodes.size(); ++i ) - vtkIds[i] = nodes[i]->GetVtkID(); - - int vtkType = toVtkType( theEntity ); - int vtkID = getGrid()->InsertNextLinkedCell( vtkType, nodes.size(), &vtkIds[0] ); - setVtkID( vtkID ); -} - -void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, - const std::vector& vtkNodeIds ) -{ - int vtkType = toVtkType( theEntity ); - int vtkID = getGrid()->InsertNextLinkedCell( vtkType, vtkNodeIds.size(), - const_cast< vtkIdType* > ( &vtkNodeIds[0] )); - setVtkID( vtkID ); -} - -bool SMDS_MeshCell::ChangeNodes(const SMDS_MeshNode* nodes[], const int theNbNodes) -{ - vtkIdType npts = 0; - vtkIdType* pts = 0; - getGrid()->GetCellPoints( GetVtkID(), npts, pts ); - if ( theNbNodes != npts ) - { - MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << theNbNodes); - return false; - } - const std::vector& interlace = toVtkOrder((VTKCellType) GetVtkType() ); - if ((int) interlace.size() != theNbNodes ) - for ( int i = 0; i < theNbNodes; i++ ) - { - pts[i] = nodes[i]->GetVtkID(); - } - else - for ( int i = 0; i < theNbNodes; i++ ) - { - pts[i] = nodes[ interlace[i] ]->GetVtkID(); - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -///Return The number of nodes owned by the current element -/////////////////////////////////////////////////////////////////////////////// -int SMDS_MeshCell::NbNodes() const +SMDS_MeshCell::SMDS_MeshCell() : + SMDS_MeshElement(-1) { - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbNodes(); - vtkIdType *pts, npts; - getGrid()->GetCellPoints( GetVtkID(), npts, pts ); - return npts; + nbCells++; + myVtkID = -1; } -int SMDS_MeshCell::NbFaces() const +SMDS_MeshCell::~SMDS_MeshCell() { - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbFaces(); - return getCellProps( GetVtkType() ).myNbFaces; + nbCells--; } - -int SMDS_MeshCell::NbEdges() const -{ - switch ( GetEntityType() ) - { - case SMDSEntity_Polyhedra: - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbEdges(); - case SMDSEntity_Polygon: - return NbNodes(); - case SMDSEntity_Quad_Polygon: - return NbNodes() / 2; - default:; - } - return getCellProps( GetVtkType() ).myNbEdges; -} - -int SMDS_MeshCell::NbCornerNodes() const -{ - switch ( GetEntityType() ) - { - case SMDSEntity_Polyhedra: - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbCornerNodes(); - case SMDSEntity_Polygon: - return NbNodes(); - case SMDSEntity_Quad_Polygon: - return NbNodes() / 2; - default:; - } - return getCellProps( GetVtkType() ).myNbCornerNodes; -} - -/////////////////////////////////////////////////////////////////////////////// -/// Create an iterator which iterate on nodes owned by the element. -/////////////////////////////////////////////////////////////////////////////// -SMDS_ElemIteratorPtr SMDS_MeshCell::nodesIterator() const -{ - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodesIterator(); - - return boost::make_shared< SMDS_VtkCellIterator<> >( GetMesh(), GetVtkID(), GetEntityType()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Create an iterator which iterate on nodes owned by the element. -/////////////////////////////////////////////////////////////////////////////// -SMDS_NodeIteratorPtr SMDS_MeshCell::nodeIterator() const -{ - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodeIterator(); - - return SMDS_NodeIteratorPtr - (new SMDS_VtkCellIterator( GetMesh(), GetVtkID(), GetEntityType())); -} - -SMDS_NodeIteratorPtr SMDS_MeshCell::interlacedNodesIterator() const -{ - bool canInterlace = ( GetType() == SMDSAbs_Face || GetType() == SMDSAbs_Edge ); - return canInterlace ? nodesIteratorToUNV() : nodeIterator(); -} - -SMDS_NodeIteratorPtr SMDS_MeshCell::nodesIteratorToUNV() const -{ - return SMDS_NodeIteratorPtr - (new SMDS_VtkCellIteratorToUNV( GetMesh(), GetVtkID(), GetEntityType())); -} - -SMDSAbs_ElementType SMDS_MeshCell::GetType() const -{ - return ElemType( GetEntityType() ); -} - -SMDSAbs_EntityType SMDS_MeshCell::GetEntityType() const -{ - return toSmdsType( (VTKCellType) GetVtkType() ); -} - -SMDSAbs_GeometryType SMDS_MeshCell::GetGeomType() const -{ - return getCellProps( GetVtkType() ).myGeom; -} - -VTKCellType SMDS_MeshCell::GetVtkType() const -{ - return (VTKCellType) getGrid()->GetCellType( GetVtkID() ); -} - -bool SMDS_MeshCell::IsPoly() const -{ - return getCellProps( GetVtkType() ).myIsPoly; -} - -bool SMDS_MeshCell::IsQuadratic() const -{ - return getCellProps( GetVtkType() ).IsQuadratic(); -} - -const SMDS_MeshNode* SMDS_MeshCell::GetNode(const int ind) const -{ - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNode( ind ); - - vtkIdType npts, *pts; - getGrid()->GetCellPoints( GetVtkID(), npts, pts ); - const std::vector& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( GetVtkType() )); - return GetMesh()->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ ind ]]); -} - -int SMDS_MeshCell::GetNodeIndex( const SMDS_MeshNode* node ) const -{ - if ( GetEntityType() == SMDSEntity_Polyhedra ) - return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node ); - - vtkIdType npts, *pts; - getGrid()->GetCellPoints( GetVtkID(), npts, pts ); - for ( vtkIdType i = 0; i < npts; ++i ) - if ( pts[i] == node->GetVtkID() ) - { - const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() )); - return interlace.empty() ? i : interlace[i]; - } - return -1; -} - //================================================================================ /*! * \brief Return VTKCellType corresponding to SMDSAbs_EntityType @@ -624,7 +262,7 @@ const std::vector& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17}; reverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 ); } - { + { const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); } @@ -710,7 +348,14 @@ const std::vector& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType) { - return getCellProps( vtkType ).myEntity; + static std::vector< SMDSAbs_EntityType > smdsTypes; + if ( smdsTypes.empty() ) + { + smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last ); + for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS ) + smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS ); + } + return smdsTypes[ vtkType ]; } //================================================================================ @@ -719,7 +364,7 @@ SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType) */ //================================================================================ -SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType) +SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType) { switch ( geomType ) { case SMDSGeom_POINT: return SMDSAbs_0DElement; @@ -750,45 +395,46 @@ SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType) */ //================================================================================ -SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_EntityType entityType) +SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType) { - return getCellProps( entityType ).myType; -} - -SMDSAbs_GeometryType SMDS_MeshCell::GeomType( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myGeom; -} + switch ( entityType ) { + case SMDSEntity_Node: return SMDSAbs_Node; -bool SMDS_MeshCell::IsPoly( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myIsPoly; -} + case SMDSEntity_0D: return SMDSAbs_0DElement; -bool SMDS_MeshCell::IsQuadratic( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).IsQuadratic(); -} + case SMDSEntity_Edge: + case SMDSEntity_Quad_Edge: return SMDSAbs_Edge; -int SMDS_MeshCell::NbCornerNodes( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myNbCornerNodes; -} + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + case SMDSEntity_BiQuad_Triangle: + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: return SMDSAbs_Face; + + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: + case SMDSEntity_Hexagonal_Prism: + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume; -int SMDS_MeshCell::NbNodes( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myNbNodes; -} + case SMDSEntity_Ball: return SMDSAbs_Ball; -int SMDS_MeshCell::NbEdges( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myNbEdges; + case SMDSEntity_Last:; + } + return SMDSAbs_All; } -int SMDS_MeshCell::NbFaces( SMDSAbs_EntityType entityType ) -{ - return getCellProps( entityType ).myNbFaces; -} //================================================================================ /*! diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx index 568cbbbc9..413b1265a 100644 --- a/src/SMDS/SMDS_MeshCell.hxx +++ b/src/SMDS/SMDS_MeshCell.hxx @@ -28,52 +28,17 @@ class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement { - protected: +public: + SMDS_MeshCell(); + virtual ~SMDS_MeshCell(); - void init( SMDSAbs_EntityType entityType, int nbNodes, ... ); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0; + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) { return true; } - void init( SMDSAbs_EntityType entityType, const std::vector& nodes ); - - void init( SMDSAbs_EntityType entityType, const std::vector& vtkNodeIds ); - - friend class SMDS_Mesh; - - public: - - virtual int NbEdges() const; - virtual int NbFaces() const; - virtual int NbNodes() const; - virtual int NbCornerNodes() const; - virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); - virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - virtual const SMDS_MeshNode* GetNode(const int ind) const; - - virtual SMDSAbs_ElementType GetType() const; - virtual SMDSAbs_EntityType GetEntityType() const; - virtual SMDSAbs_GeometryType GetGeomType() const; - virtual VTKCellType GetVtkType() const; - - virtual bool IsPoly() const; - virtual bool IsQuadratic() const; - - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; - virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const; - virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const; - - - static void InitStaticMembers(); - static VTKCellType toVtkType ( SMDSAbs_EntityType entityType ); - static SMDSAbs_EntityType toSmdsType ( VTKCellType vtkType ); - static SMDSAbs_ElementType ElemType ( SMDSAbs_GeometryType geomType ); - static SMDSAbs_ElementType ElemType ( SMDSAbs_EntityType entityType ); - static SMDSAbs_GeometryType GeomType ( SMDSAbs_EntityType entityType ); - static bool IsPoly ( SMDSAbs_EntityType entityType ); - static bool IsQuadratic ( SMDSAbs_EntityType entityType ); - static int NbCornerNodes( SMDSAbs_EntityType entityType ); - static int NbNodes ( SMDSAbs_EntityType entityType ); - static int NbEdges ( SMDSAbs_EntityType entityType ); - static int NbFaces ( SMDSAbs_EntityType entityType ); + static VTKCellType toVtkType (SMDSAbs_EntityType vtkType); + static SMDSAbs_EntityType toSmdsType(VTKCellType vtkType); + static SMDSAbs_ElementType toSmdsType(SMDSAbs_GeometryType geomType); + static SMDSAbs_ElementType toSmdsType(SMDSAbs_EntityType entityType); static const std::vector& toVtkOrder(VTKCellType vtkType); static const std::vector& toVtkOrder(SMDSAbs_EntityType smdsType); @@ -85,7 +50,6 @@ class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement static const std::vector& interlacedSmdsOrder(SMDSAbs_EntityType smdsType, const size_t nbNodes=0); - template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]] static void applyInterlace( const std::vector& interlace, VECT & data) { @@ -105,6 +69,15 @@ class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement data.swap( tmpData ); } + static int nbCells; + +protected: + inline void exchange(const SMDS_MeshNode* nodes[],int a, int b) + { + const SMDS_MeshNode* noda = nodes[a]; + nodes[a] = nodes[b]; + nodes[b] = noda; + } }; #endif diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx new file mode 100644 index 000000000..672adee4f --- /dev/null +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#include "SMDS_MeshEdge.hxx" + +SMDSAbs_ElementType SMDS_MeshEdge::GetType() const +{ + return SMDSAbs_Edge; +} + +vtkIdType SMDS_MeshEdge::GetVtkType() const +{ + return VTK_POLY_VERTEX; // --- must be reimplemented in derived classes +} diff --git a/src/SMDS/SMDS_MeshEdge.hxx b/src/SMDS/SMDS_MeshEdge.hxx index 462028e91..423d96241 100644 --- a/src/SMDS/SMDS_MeshEdge.hxx +++ b/src/SMDS/SMDS_MeshEdge.hxx @@ -28,16 +28,12 @@ #include "SMDS_MeshCell.hxx" -/*! - * \brief Edge mesh element. This type is not allocated. - * It is only used as function argument type to provide more clear semantic. - */ class SMDS_EXPORT SMDS_MeshEdge: public SMDS_MeshCell { + public: - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Edge; } + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_EDGE; } - - static SMDSAbs_ElementType Type() { return SMDSAbs_Edge; } }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 48221c7c6..31119a8ed 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -27,190 +27,282 @@ #endif #include "SMDS_MeshElement.hxx" - -#include "SMDS_Mesh.hxx" -#include "SMDS_ElementFactory.hxx" - +#include "SMDS_MeshNode.hxx" +#include "SMDS_MeshEdge.hxx" +#include "SMDS_MeshFace.hxx" +#include "SMDS_MeshVolume.hxx" #include "utilities.h" -//================================================================================ -/*! - * \brief Constructor of a non-used element - */ -//================================================================================ +using namespace std; -SMDS_MeshElement::SMDS_MeshElement(): myHolder(0) +SMDS_MeshElement::SMDS_MeshElement(int ID) { + init(ID); } -//================================================================================ -/*! - * \brief Check if a node is a medium node of a quadratic cell - */ -//================================================================================ - -bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const +SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, LongType shapeId) { - return !( GetNodeIndex( node ) < NbCornerNodes() ); + init(id, meshId, shapeId); } -//================================================================================ -/*! - * \brief Return true if index of node is valid (0 <= ind < NbNodes()) - * \param ind - node index - * \retval bool - index check result - */ -//================================================================================ - -bool SMDS_MeshElement::IsValidIndex(const int ind) const +void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId ) { - return ( ind>-1 && ind= NbCornerNodes() ) return ind % NbCornerNodes(); - return ind; + OS << "dump of mesh element" << endl; } -//================================================================================ -/*! - * \brief Check if a node belongs to the element - * \param node - the node to check - * \retval int - node index within the element, -1 if not found - */ -//================================================================================ +ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) +{ + ME->Print(OS); + return OS; +} -int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const +/////////////////////////////////////////////////////////////////////////////// +/// Create an iterator which iterate on nodes owned by the element. +/// This method call elementsIterator(). +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const { - SMDS_ElemIteratorPtr nIt = nodesIterator(); - for ( int i = 0; nIt->more(); ++i ) - if ( nIt->next() == node ) - return i; - return -1; + return elementsIterator(SMDSAbs_Node); } -//================================================================================ -/*! - * \brief Return ID of an element - */ -//================================================================================ +/////////////////////////////////////////////////////////////////////////////// +/// Create an iterator which iterate on edges linked with or owned by the element. +/// This method call elementsIterator(). +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const +{ + return elementsIterator(SMDSAbs_Edge); +} -int SMDS_MeshElement::GetID() const +/////////////////////////////////////////////////////////////////////////////// +/// Create an iterator which iterate on faces linked with or owned by the element. +/// This method call elementsIterator(). +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const { - return myHolder ? myHolder->GetID( this ) : -1; + return elementsIterator(SMDSAbs_Face); } -//================================================================================ -/*! - * \brief Set ID of a shape this element was generated on - */ -//================================================================================ +/////////////////////////////////////////////////////////////////////////////// +///Return The number of nodes owned by the current element +/////////////////////////////////////////////////////////////////////////////// +int SMDS_MeshElement::NbNodes() const +{ + int nbnodes=0; + SMDS_ElemIteratorPtr it=nodesIterator(); + while(it->more()) + { + it->next(); + nbnodes++; + } + return nbnodes; +} -void SMDS_MeshElement::setShapeID( const int shapeID ) const +/////////////////////////////////////////////////////////////////////////////// +///Return the number of edges owned by or linked with the current element +/////////////////////////////////////////////////////////////////////////////// +int SMDS_MeshElement::NbEdges() const { - const_cast( myHolder )->SetShapeID( this, shapeID ); + int nbedges=0; + SMDS_ElemIteratorPtr it=edgesIterator(); + while(it->more()) + { + it->next(); + nbedges++; + } + return nbedges; } -//================================================================================ -/*! - * \brief Return ID of a shape this element was generated on - */ -//================================================================================ +/////////////////////////////////////////////////////////////////////////////// +///Return the number of faces owned by or linked with the current element +/////////////////////////////////////////////////////////////////////////////// +int SMDS_MeshElement::NbFaces() const +{ + int nbfaces=0; + SMDS_ElemIteratorPtr it=facesIterator(); + while(it->more()) + { + it->next(); + nbfaces++; + } + return nbfaces; +} -int SMDS_MeshElement::GetShapeID() const +/////////////////////////////////////////////////////////////////////////////// +///Create an iterator which iterate on elements linked with the current element. +///@param type The of elements on which you want to iterate +///@return A smart pointer to iterator, you are not to take care of freeing memory +/////////////////////////////////////////////////////////////////////////////// +class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator +{ + const SMDS_MeshElement * myElement; + bool myMore; +public: + SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element): + myElement(element),myMore(true) {} + + bool more() + { + return myMore; + } + + const SMDS_MeshElement* next() + { + myMore=false; + return myElement; + } +}; + +SMDS_ElemIteratorPtr +SMDS_MeshElement::elementsIterator(SMDSAbs_ElementType type) const { - return myHolder->GetShapeID( this ); + /** @todo Check that iterator in the child classes return elements + in the same order for each different implementation (i.e: SMDS_VolumeOfNodes + and SMDS_VolumeOfFaces */ + if(type==GetType()) + return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this)); + else + { + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); + } } -//================================================================================ -/*! - * \brief Return VTK ID of this element - */ -//================================================================================ +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_NodeIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const +{ + return nodeIterator(); +} -int SMDS_MeshElement::GetVtkID() const +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_NodeIteratorPtr SMDS_MeshElement::interlacedNodesIterator() const { - return myHolder->GetVtkID( this ); + return nodeIterator(); } -//================================================================================ -/*! - * \brief Mark this element - */ -//================================================================================ +namespace +{ + //======================================================================= + //class : _MyNodeIteratorFromElemIterator + //======================================================================= + class _MyNodeIteratorFromElemIterator : public SMDS_NodeIterator + { + SMDS_ElemIteratorPtr myItr; + public: + _MyNodeIteratorFromElemIterator(SMDS_ElemIteratorPtr elemItr):myItr( elemItr ) {} + bool more() { return myItr->more(); } + const SMDS_MeshNode* next() { return static_cast< const SMDS_MeshNode*>( myItr->next() ); } + }; + //======================================================================= + //class : _MyElemIteratorFromNodeIterator + //======================================================================= + class _MyElemIteratorFromNodeIterator : public SMDS_ElemIterator + { + SMDS_NodeIteratorPtr myItr; + public: + _MyElemIteratorFromNodeIterator(SMDS_NodeIteratorPtr nodeItr): myItr( nodeItr ) {} + bool more() { return myItr->more(); } + const SMDS_MeshElement* next() { return myItr->next(); } + }; +} -void SMDS_MeshElement::setIsMarked( bool is ) const +SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const { - const_cast( myHolder )->SetIsMarked( this, is ); + return SMDS_ElemIteratorPtr + ( new _MyElemIteratorFromNodeIterator( interlacedNodesIterator() )); } -//================================================================================ -/*! - * \brief Check if this element is marked - */ -//================================================================================ +SMDS_NodeIteratorPtr SMDS_MeshElement::nodeIterator() const +{ + return SMDS_NodeIteratorPtr + ( new _MyNodeIteratorFromElemIterator( nodesIterator() )); +} -bool SMDS_MeshElement::isMarked() const +bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) { - return myHolder->IsMarked( this ); + if(e1.GetType()!=e2.GetType()) return false; + switch(e1.GetType()) + { + case SMDSAbs_Node: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Edge: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Face: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Volume: + return static_cast(e1) < + static_cast(e2); + + default : MESSAGE("Internal Error"); + } + return false; } -//================================================================================ -/*! - * \brief Store VTK ID - */ -//================================================================================ +bool SMDS_MeshElement::IsValidIndex(const int ind) const +{ + return ( ind>-1 && indSetVTKID( this, vtkID ); + if ( ind >= 0 ) { + SMDS_ElemIteratorPtr it = nodesIterator(); + for ( int i = 0; i < ind; ++i ) + it->next(); + if ( it->more() ) + return static_cast (it->next()); + } + return 0; } -//================================================================================ -/*! - * \brief Return the mesh this element belongs to - */ -//================================================================================ +bool SMDS_MeshElement::IsQuadratic() const +{ + return false; +} -SMDS_Mesh* SMDS_MeshElement::GetMesh() const +bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const { - return const_cast( myHolder )->GetMesh(); + return false; } //================================================================================ /*! - * \brief Return a SMDS_UnstructuredGrid + * \brief Return number of nodes excluding medium ones */ //================================================================================ -SMDS_UnstructuredGrid* SMDS_MeshElement::getGrid() const +int SMDS_MeshElement::NbCornerNodes() const { - return const_cast( myHolder )->GetMesh()->GetGrid(); + return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes(); } //================================================================================ /*! - * \brief Print self + * \brief Check if a node belongs to the element + * \param node - the node to check + * \retval int - node index within the element, -1 if not found */ //================================================================================ -void SMDS_MeshElement::Print(ostream & OS) const -{ - OS << "dump of mesh element" << endl; -} - -ostream & operator <<(ostream & OS, const SMDS_MeshElement * e) +int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const { - e->Print(OS); - return OS; + SMDS_ElemIteratorPtr nIt = nodesIterator(); + for ( int i = 0; nIt->more(); ++i ) + if ( nIt->next() == node ) + return i; + return -1; } diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 63fc8cecf..4634548aa 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -32,17 +32,23 @@ #include "SMDSAbs_ElementType.hxx" #include "SMDS_MeshObject.hxx" #include "SMDS_ElemIterator.hxx" +#include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_StdIterator.hxx" +#include #include #include #include -class SMDS_ElementChunk; -class SMDS_Mesh; +//typedef unsigned short UShortType; +typedef short ShortType; +typedef int LongType; + class SMDS_MeshNode; -class SMDS_UnstructuredGrid; +class SMDS_MeshEdge; +class SMDS_MeshFace; +class SMDS_Mesh; // ============================================================ /*! @@ -55,36 +61,43 @@ class SMDS_EXPORT SMDS_MeshElement : public SMDS_MeshObject { public: - // =========================== - // Access to nodes - // =========================== - virtual SMDS_ElemIteratorPtr nodesIterator() const = 0; + SMDS_ElemIteratorPtr nodesIterator() const; + SMDS_ElemIteratorPtr edgesIterator() const; + SMDS_ElemIteratorPtr facesIterator() const; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const = 0; - virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const { return nodeIterator(); } - virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const { return nodeIterator(); } + virtual SMDS_NodeIteratorPtr nodeIterator() const; + virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const; + virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const; // std-like iteration on nodes - typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_NodeIteratorPtr > iterator; - iterator begin_nodes() const { return iterator( nodeIterator() ); } + typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_ElemIteratorPtr > iterator; + iterator begin_nodes() const { return iterator( nodesIterator() ); } iterator end_nodes() const { return iterator(); } - // =========================== - // Type of element - // =========================== - virtual int NbNodes() const = 0; - virtual int NbEdges() const = 0; - virtual int NbFaces() const = 0; + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + inline int GetID() const { return myID; } + ///Return the type of the current element virtual SMDSAbs_ElementType GetType() const = 0; virtual SMDSAbs_EntityType GetEntityType() const = 0; virtual SMDSAbs_GeometryType GetGeomType() const = 0; - virtual VTKCellType GetVtkType() const = 0; + virtual vtkIdType GetVtkType() const = 0; - virtual bool IsPoly() const = 0; - virtual bool IsQuadratic() const = 0; + virtual bool IsPoly() const { return false; } + virtual bool IsQuadratic() const; virtual bool IsMediumNode(const SMDS_MeshNode* node) const; - virtual int NbCornerNodes() const = 0; + virtual int NbCornerNodes() const; + + friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); + friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement* elem); + friend class SMDS_Mesh; + friend class SMESHDS_Mesh; + friend class SMESHDS_SubMesh; + friend class SMDS_MeshElementIDFactory; // =========================== // Access to nodes by index @@ -94,14 +107,14 @@ public: * \param ind - node index * \retval const SMDS_MeshNode* - the node */ - virtual const SMDS_MeshNode* GetNode(const int ind) const = 0; + virtual const SMDS_MeshNode* GetNode(const int ind) const; /*! * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node * - * Index is wrapped if it is out of a valid range of corner nodes + * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* GetNodeWrap(const int ind) const { return GetNode( WrappedIndex( ind )); } @@ -113,11 +126,15 @@ public: virtual bool IsValidIndex(const int ind) const; /*! - * \brief Return a valid corner node index, fixing the given one if necessary + * \brief Return a valid node index, fixing the given one if necessary * \param ind - node index * \retval int - valid node index */ - int WrappedIndex(const int ind) const; + int WrappedIndex(const int ind) const { + if ( ind < 0 ) return NbNodes() + ind % NbNodes(); + if ( ind >= NbNodes() ) return ind % NbNodes(); + return ind; + } /*! * \brief Check if a node belongs to the element @@ -126,26 +143,14 @@ public: */ virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - - virtual int GetID() const; - virtual int GetVtkID() const; - virtual int getshapeId() const { return GetShapeID(); } - virtual int GetShapeID() const; + inline ShortType getMeshId() const { return myMeshId; } + inline LongType getshapeId() const { return myShapeId >> BITS_SHIFT; } + inline int getIdInShape() const { return myIdInShape; } + inline int getVtkId() const { return myVtkID; } // mark this element; to be used in algos - virtual void setIsMarked( bool is ) const; - virtual bool isMarked() const; - - // element can be allocated but "not used" - bool IsNull() const { return myHolder == 0; } - - SMDS_Mesh* GetMesh() const; - - void Print(std::ostream & OS) const; - - friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); - friend class SMDS_ElementFactory; - friend class SMESHDS_SubMesh; + inline void setIsMarked( bool is ) const; + inline bool isMarked() const; /*! * \brief Filters of elements, to be used with SMDS_SetIterator @@ -178,20 +183,42 @@ public: bool operator()(const SMDS_MeshElement* e) const { return e && e->GetGeomType() == _type; } }; - protected: - - SMDS_MeshElement(); - - void setVtkID(const int vtkID ); - virtual void setShapeID( const int shapeID ) const; - - SMDS_UnstructuredGrid* getGrid() const; - - protected: - - SMDS_ElementChunk* myHolder; +protected: + inline void setId(int id) { myID = id; } + inline void setVtkId(int vtkId) { myVtkID = vtkId; } + inline void setIdInShape(int id) { myIdInShape = id; } + inline void setShapeId(LongType shapeId) { myShapeId = ( shapeId << BITS_SHIFT ) | ( myShapeId & BIT_IS_MARKED ); } + SMDS_MeshElement(int ID=-1); + SMDS_MeshElement(int id, ShortType meshId, LongType shapeId = 0); + virtual void init(int id = -1, ShortType meshId = -1, LongType shapeId = 0); + virtual void Print(std::ostream & OS) const; + + //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells + int myID; + //! index in vtkUnstructuredGrid + int myVtkID; + //! SMDS_Mesh identification in SMESH + ShortType myMeshId; + //! SubShape and SubMesh identification in SMESHDS; one bit is used to mark the element + LongType myShapeId; + //! Element index in SMESHDS_SubMesh vector + int myIdInShape; + + enum Bits { // use the 1st right bit of myShapeId to set/unset a mark + BIT_IS_MARKED = 1, + BITS_SHIFT = 1 + }; }; +inline void SMDS_MeshElement::setIsMarked( bool is ) const +{ + const_cast< SMDS_MeshElement* >( this )->myShapeId = ( myShapeId & ~BIT_IS_MARKED ) | is; +} +inline bool SMDS_MeshElement::isMarked() const +{ + return myShapeId & BIT_IS_MARKED; +} + // ============================================================ /*! * \brief Comparator of elements by ID for usage in std containers diff --git a/src/SMDS/SMDS_MeshElementIDFactory.cxx b/src/SMDS/SMDS_MeshElementIDFactory.cxx new file mode 100644 index 000000000..c7fc45eb6 --- /dev/null +++ b/src/SMDS/SMDS_MeshElementIDFactory.cxx @@ -0,0 +1,176 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_MeshElementIDFactory.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_MeshElementIDFactory.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include "utilities.h" + +#include "SMDS_UnstructuredGrid.hxx" +#include + +#include + +using namespace std; + +//======================================================================= +//function : SMDS_MeshElementIDFactory +//purpose : +//======================================================================= +SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory(): + SMDS_MeshNodeIDFactory() +{ +} + +int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem) +{ + // --- retrieve nodes ID + + SMDS_MeshCell *cell = dynamic_cast(elem); + assert(cell); + vector nodeIds( elem->NbNodes() ); + SMDS_ElemIteratorPtr it = elem->nodesIterator(); + for( int i = 0; it->more(); ++i ) + { + int nodeId = (static_cast(it->next()))->getVtkId(); + nodeIds[i] = nodeId; + } + + // --- insert cell in vtkUnstructuredGrid + + int typ = VTK_VERTEX; + int cellId = myMesh->getGrid()->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]); + cell->setVtkId(cellId); + return cellId; +} + +//======================================================================= +//function : BindID +//purpose : +//======================================================================= + +bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem) +{ + SetInVtkGrid(elem); + return myMesh->registerElement(ID, elem); +} + +//======================================================================= +//function : MeshElement +//purpose : +//======================================================================= +SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) +{ + if ( ID<1 || ID >= (int) myMesh->myCells.size() ) + return NULL; + const SMDS_MeshElement* elem = GetMesh()->FindElement(ID); + return (SMDS_MeshElement*)(elem); +} + +//======================================================================= +//function : GetFreeID +//purpose : +//======================================================================= + +int SMDS_MeshElementIDFactory::GetFreeID() +{ + int ID; + do { + ID = SMDS_MeshIDFactory::GetFreeID(); + } while ( MeshElement( ID )); + return ID; +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId) +{ + if (ID < 1) // TODO check case ID == O + { + MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID); + return; + } + if (vtkId >= 0) + { + assert(vtkId < (int)myMesh->myCellIdVtkToSmds.size()); + myMesh->myCellIdVtkToSmds[vtkId] = -1; + myMesh->setMyModified(); + } + SMDS_MeshIDFactory::ReleaseID(ID); + if (ID == myMax) + myMax = 0; + if (ID == myMin) + myMax = 0; +} + +//======================================================================= +//function : updateMinMax +//purpose : +//======================================================================= + +void SMDS_MeshElementIDFactory::updateMinMax() const +{ + myMin = INT_MAX; + myMax = 0; + for (size_t i = 0; i < myMesh->myCells.size(); i++) + { + if (myMesh->myCells[i]) + { + int id = myMesh->myCells[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + } + if (myMin == INT_MAX) + myMin = 0; +} + +//======================================================================= +//function : elementsIterator +//purpose : Return an iterator on elements of the factory +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const +{ + return myMesh->elementsIterator(SMDSAbs_All); +} + +void SMDS_MeshElementIDFactory::Clear() +{ + myMesh->myCellIdVtkToSmds.clear(); + myMin = myMax = 0; + SMDS_MeshIDFactory::Clear(); +} diff --git a/src/SMDS/SMDS_MeshElementIDFactory.hxx b/src/SMDS/SMDS_MeshElementIDFactory.hxx new file mode 100644 index 000000000..f75d24f5c --- /dev/null +++ b/src/SMDS/SMDS_MeshElementIDFactory.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_MeshElementIDFactory.hxx +// Module : SMESH +// +#ifndef _SMDS_MeshElementIDFactory_HeaderFile +#define _SMDS_MeshElementIDFactory_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshNodeIDFactory.hxx" + +#include + +class SMDS_MeshElement; +class SMDS_Mesh; + +class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshNodeIDFactory +{ +public: + friend class SMDS_Mesh; + + SMDS_MeshElementIDFactory(); + bool BindID(int ID, SMDS_MeshElement * elem); + int SetInVtkGrid(SMDS_MeshElement * elem); + SMDS_MeshElement * MeshElement(int ID); + virtual int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); + SMDS_ElemIteratorPtr elementsIterator() const; + virtual void Clear(); + +protected: + virtual void updateMinMax() const; + void updateMinMax(int id) const + { + if (id > myMax) myMax = id; + if (id < myMin) myMin = id; + } +}; + +#endif diff --git a/src/SMDS/SMDS_MeshFace.cxx b/src/SMDS/SMDS_MeshFace.cxx new file mode 100644 index 000000000..126945596 --- /dev/null +++ b/src/SMDS/SMDS_MeshFace.cxx @@ -0,0 +1,35 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#include "SMDS_MeshFace.hxx" + +SMDSAbs_ElementType SMDS_MeshFace::GetType() const +{ + return SMDSAbs_Face; +} + +vtkIdType SMDS_MeshFace::GetVtkType() const +{ + return VTK_POLY_LINE; // --- must be reimplemented in derived classes +} diff --git a/src/SMDS/SMDS_MeshFace.hxx b/src/SMDS/SMDS_MeshFace.hxx index 11e1f32c6..92f2f9b4f 100644 --- a/src/SMDS/SMDS_MeshFace.hxx +++ b/src/SMDS/SMDS_MeshFace.hxx @@ -31,37 +31,11 @@ #include "SMDS_MeshCell.hxx" -#include "Utils_SALOME_Exception.hxx" - -/*! - * \brief Mesh face. This type is not allocated. - * It is only used as function argument type to provide more clear semantic. - */ -class SMDS_EXPORT SMDS_MeshFace : public SMDS_MeshCell +class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshCell { - void init( const std::vector& vtkNodeIds ) - { - SMDSAbs_EntityType entity = SMDSEntity_Triangle; - switch ( vtkNodeIds.size()) - { - case 3: entity = SMDSEntity_Triangle; break; - case 4: entity = SMDSEntity_Quadrangle; break; - case 6: entity = SMDSEntity_Quad_Triangle; break; - case 8: entity = SMDSEntity_Quad_Quadrangle; break; - case 7: entity = SMDSEntity_BiQuad_Triangle; break; - case 9: entity = SMDSEntity_BiQuad_Quadrangle; break; - default: throw SALOME_Exception("wrong face nodes"); - } - SMDS_MeshCell::init( entity, vtkNodeIds ); - } - - friend class SMDS_Mesh; - - public: - - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } - - static SMDSAbs_ElementType Type() { return SMDSAbs_Face; } + public: + SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_MeshGroup.cxx b/src/SMDS/SMDS_MeshGroup.cxx index 80e7c6080..4040a3e1d 100644 --- a/src/SMDS/SMDS_MeshGroup.cxx +++ b/src/SMDS/SMDS_MeshGroup.cxx @@ -30,33 +30,89 @@ #endif #include "SMDS_MeshGroup.hxx" +#include "utilities.h" -#include "SMDS_SetIterator.hxx" -#include "ObjectPool.hxx" +using namespace std; -#include +//======================================================================= +//function : SMDS_MeshGroup +//purpose : +//======================================================================= -#include +SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh, + const SMDSAbs_ElementType theType) + :myMesh(theMesh),myType(theType), myParent(NULL), myTic(0) +{ +} //======================================================================= //function : SMDS_MeshGroup -//purpose : +//purpose : //======================================================================= -SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh, +SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent, const SMDSAbs_ElementType theType) - : SMDS_ElementHolder( theMesh ), myType(theType), myTic(0) + :myMesh(theParent->myMesh),myType(theType), myParent(theParent) { } +//======================================================================= +//function : AddSubGroup +//purpose : +//======================================================================= + +const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup + (const SMDSAbs_ElementType theType) +{ + const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType); + myChildren.insert(myChildren.end(),subgroup); + return subgroup; +} + +//======================================================================= +//function : RemoveSubGroup +//purpose : +//======================================================================= + +bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup) +{ + bool found = false; + list::iterator itgroup; + for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++) + { + const SMDS_MeshGroup* subgroup=*itgroup; + if (subgroup == theGroup) + { + found = true; + myChildren.erase(itgroup); + } + } + + return found; +} + +//======================================================================= +//function : RemoveFromParent +//purpose : +//======================================================================= + +bool SMDS_MeshGroup::RemoveFromParent() +{ + + if (myParent==NULL) return false; + else + { + return (myParent->RemoveSubGroup(this)); + } +} //======================================================================= //function : Clear -//purpose : +//purpose : //======================================================================= void SMDS_MeshGroup::Clear() { - clearVector( myElements ); + myElements.clear(); myType = SMDSAbs_All; ++myTic; } @@ -76,8 +132,8 @@ bool SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem) MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<GetType()<<"!="<::iterator found = myElements.find(theElem); if ( found != myElements.end() ) { myElements.erase(found); if (myElements.empty()) myType = SMDSAbs_All; @@ -120,38 +176,3 @@ void SMDS_MeshGroup::SetType(const SMDSAbs_ElementType theType) if (IsEmpty()) myType = theType; } - -//======================================================================= -//function : GetElements -//purpose : -//======================================================================= - -SMDS_ElemIteratorPtr SMDS_MeshGroup::GetElements() const -{ - typedef SMDS_SetIterator< const SMDS_MeshElement*, TIterator > TSetIterator; - return boost::make_shared< TSetIterator >( myElements.begin(), myElements.end() ); -} - -//======================================================================= -//function : Move contents of another group -//purpose : -//======================================================================= - -void SMDS_MeshGroup::operator=( SMDS_MeshGroup && other ) -{ - myMesh = other.myMesh; - myType = other.myType; - myElements = std::move( other.myElements ); - ++myTic; -} - -//======================================================================= -//function : tmpClear -//purpose : temporary remove its elements before mesh compacting -//======================================================================= - -void SMDS_MeshGroup::tmpClear() -{ - compact(); - myElements.clear(); -} diff --git a/src/SMDS/SMDS_MeshGroup.hxx b/src/SMDS/SMDS_MeshGroup.hxx index b605737bf..7ba1375ad 100644 --- a/src/SMDS/SMDS_MeshGroup.hxx +++ b/src/SMDS/SMDS_MeshGroup.hxx @@ -29,49 +29,65 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_ElementHolder.hxx" #include "SMDS_Mesh.hxx" #include -#include - -class SMDS_EXPORT SMDS_MeshGroup: public SMDS_MeshObject, SMDS_ElementHolder +class SMDS_EXPORT SMDS_MeshGroup:public SMDS_MeshObject { - public: - SMDS_MeshGroup(const SMDS_Mesh * theMesh, - const SMDSAbs_ElementType theType = SMDSAbs_All); - - void SetType (const SMDSAbs_ElementType theType); - void Clear(); - void Reserve(size_t nbElems) { myElements.reserve( nbElems ); } - bool Add(const SMDS_MeshElement * theElem); - bool Remove(const SMDS_MeshElement * theElem); - bool IsEmpty() const { return myElements.empty(); } - int Extent() const { return myElements.size(); } - int Tic() const { return myTic; } - bool Contains(const SMDS_MeshElement * theElem) const; - - const SMDS_Mesh* GetMesh() const { return myMesh; } - SMDSAbs_ElementType GetType() const { return myType; } - SMDS_ElemIteratorPtr GetElements() const; // WARNING: iterator becomes invalid if group changes - - void operator=( SMDS_MeshGroup && other ); - - protected: // methods of SMDS_ElementHolder - - virtual SMDS_ElemIteratorPtr getElements() { return GetElements(); } - virtual void tmpClear(); - virtual void add( const SMDS_MeshElement* element ) { Add( element ); } - virtual void compact() { myElements.shrink_to_fit(); } - - private: - - typedef boost::container::flat_set< const SMDS_MeshElement* > TElementSet; - typedef TElementSet::const_iterator TIterator; - - const SMDS_Mesh * myMesh; - SMDSAbs_ElementType myType; - TElementSet myElements; // not sorted by ID because it can contain deleted elements - int myTic; // to track changes + public: + SMDS_MeshGroup(const SMDS_Mesh * theMesh, + const SMDSAbs_ElementType theType = SMDSAbs_All); + const SMDS_MeshGroup * AddSubGroup + (const SMDSAbs_ElementType theType = SMDSAbs_All); + virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup); + virtual bool RemoveFromParent(); + + const SMDS_Mesh* GetMesh() const { return myMesh; } + + void SetType (const SMDSAbs_ElementType theType); + void Clear(); + bool Add(const SMDS_MeshElement * theElem); + bool Remove(const SMDS_MeshElement * theElem); + bool IsEmpty() const { return myElements.empty(); } + int Extent() const { return myElements.size(); } + int Tic() const { return myTic; } + + int SubGroupsNb() const { return myChildren.size(); } + + SMDSAbs_ElementType GetType() const { return myType; } + + bool Contains(const SMDS_MeshElement * theElem) const; + + void InitIterator() const + { const_cast(myIterator) = myElements.begin(); } + + bool More() const { return myIterator != myElements.end(); } + + const SMDS_MeshElement* Next() const + { return *(const_cast(myIterator))++; } + + void InitSubGroupsIterator() const + { const_cast(myGroupIterator) = myChildren.begin(); } + + bool MoreSubGroups() const { return myGroupIterator != myChildren.end(); } + + const SMDS_MeshGroup* NextSubGroup() const + { return *(const_cast(myGroupIterator))++; } + + private: + SMDS_MeshGroup(SMDS_MeshGroup* theParent, + const SMDSAbs_ElementType theType = SMDSAbs_All); + + typedef std::set::const_iterator TIterator; + typedef std::list::const_iterator TGroupIterator; + + const SMDS_Mesh * myMesh; + SMDSAbs_ElementType myType; + std::set myElements; /* - not sorted by ID because it */ + SMDS_MeshGroup * myParent; /* can contain deleted elements */ + std::list myChildren; + TIterator myIterator; + TGroupIterator myGroupIterator; + int myTic; // to track changes }; #endif diff --git a/src/SMDS/SMDS_MeshIDFactory.cxx b/src/SMDS/SMDS_MeshIDFactory.cxx new file mode 100644 index 000000000..ea74aa576 --- /dev/null +++ b/src/SMDS/SMDS_MeshIDFactory.cxx @@ -0,0 +1,113 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_MeshIDFactory.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#include "SMDS_MeshIDFactory.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_MeshIDFactory +//purpose : +//======================================================================= + +SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0), myMesh(0) +{ +} + +int SMDS_MeshIDFactory::GetFreeID() +{ + int newid; + if (myPoolOfID.empty()) + { + newid = ++myMaxID; + } + else + { + set::iterator i = myPoolOfID.begin(); + newid = *i; + myPoolOfID.erase( i ); + } + return newid; +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId) +{ + if ( ID > 0 ) + { + if ( ID < myMaxID ) + { + myPoolOfID.insert(ID); + } + else if ( ID == myMaxID ) + { + --myMaxID; + if ( !myPoolOfID.empty() ) // assure that myMaxID is not in myPoolOfID + { + set::iterator i = --myPoolOfID.end(); + while ( i != myPoolOfID.begin() && myMaxID == *i ) { + --myMaxID; --i; + } + if ( myMaxID == *i ) { + --myMaxID; // begin of myPoolOfID reached + myPoolOfID.clear(); + } + else if ( myMaxID < ID-1 ) { + myPoolOfID.erase( ++i, myPoolOfID.end() ); + } + } + } + } +} + +void SMDS_MeshIDFactory::Clear() +{ + myMaxID = 0; + myPoolOfID.clear(); +} + +void SMDS_MeshIDFactory::SetMesh(SMDS_Mesh *mesh) +{ + myMesh = mesh; +} + +SMDS_Mesh* SMDS_MeshIDFactory::GetMesh() +{ + return myMesh; +} + +void SMDS_MeshIDFactory::emptyPool(int maxId) +{ + myMaxID = maxId; + myPoolOfID.clear(); +} + diff --git a/src/SMDS/SMDS_MeshIDFactory.hxx b/src/SMDS/SMDS_MeshIDFactory.hxx new file mode 100644 index 000000000..35be69bd9 --- /dev/null +++ b/src/SMDS/SMDS_MeshIDFactory.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_MeshIDFactory.hxx +// Module : SMESH +// +#ifndef _SMDS_MeshIDFactory_HeaderFile +#define _SMDS_MeshIDFactory_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshObject.hxx" +#include + +class SMDS_Mesh; + +class SMDS_EXPORT SMDS_MeshIDFactory:public SMDS_MeshObject +{ +public: + int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); + virtual void Clear(); + + void SetMesh(SMDS_Mesh *mesh); + SMDS_Mesh* GetMesh(); + inline bool isPoolIdEmpty() { return myPoolOfID.empty(); }; + virtual void emptyPool(int maxId); + inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;}; +protected: + SMDS_MeshIDFactory(); + int myMaxID; + std::set myPoolOfID; + SMDS_Mesh *myMesh; +}; + +#endif diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index 542798277..554f0fa71 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -27,25 +27,55 @@ #endif #include "SMDS_MeshNode.hxx" - -#include "SMDS_ElementFactory.hxx" -#include "SMDS_Mesh.hxx" -#include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_Mesh.hxx" +#include -#include -#include +#include "utilities.h" +#include "Utils_SALOME_Exception.hxx" #include -#include +using namespace std; + +int SMDS_MeshNode::nbNodes =0; + +//======================================================================= +//function : SMDS_MeshNode +//purpose : +//======================================================================= +SMDS_MeshNode::SMDS_MeshNode() : + SMDS_MeshElement(-1, -1, 0), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; +} + +SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y, double z): + SMDS_MeshElement(id, meshId, shapeId), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; + init(id, meshId, shapeId, x, y ,z); +} -void SMDS_MeshNode::init(double x, double y, double z) +void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z) { - SMDS_UnstructuredGrid * grid = getGrid(); + SMDS_MeshElement::init(id, meshId, shapeId); + myVtkID = id - 1; + assert(myVtkID >= 0); + SMDS_UnstructuredGrid * grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkPoints *points = grid->GetPoints(); - points->InsertPoint( GetVtkID(), x, y, z ); + points->InsertPoint(myVtkID, x, y, z); if ( grid->HasLinks() ) - grid->GetLinks()->ResizeForPoint( GetVtkID() ); + grid->GetLinks()->ResizeForPoint( myVtkID ); +} + +SMDS_MeshNode::~SMDS_MeshNode() +{ + nbNodes--; + if ( myPosition && myPosition != SMDS_SpacePosition::originSpacePosition() ) + delete myPosition, myPosition = 0; } //======================================================================= @@ -55,8 +85,8 @@ void SMDS_MeshNode::init(double x, double y, double z) void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem) { - if ( getGrid()->HasLinks() ) - getGrid()->RemoveReferenceToCell( GetVtkID(), elem->GetVtkID()); + if ( SMDS_Mesh::_meshList[myMeshId]->getGrid()->HasLinks() ) + SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, elem->getVtkId()); } //======================================================================= @@ -66,7 +96,7 @@ void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem) void SMDS_MeshNode::Print(ostream & OS) const { - OS << "Node <" << GetID() << "> : X = " << X() << " Y = " + OS << "Node <" << myID << "> : X = " << X() << " Y = " << Y() << " Z = " << Z() << endl; } @@ -75,20 +105,23 @@ void SMDS_MeshNode::Print(ostream & OS) const //purpose : //======================================================================= -void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos, int shapeID) +void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos) { - myHolder->SetPosition( this, aPos, shapeID ); + if ( myPosition && + myPosition != SMDS_SpacePosition::originSpacePosition() && + myPosition != aPos ) + delete myPosition; + myPosition = aPos; } //======================================================================= //function : GetPosition -//purpose : Return a position of this node on shape -//warning : result is std::unique_ptr ! +//purpose : //======================================================================= -SMDS_PositionPtr SMDS_MeshNode::GetPosition() const +const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const { - return myHolder->GetPosition( this ); + return myPosition; } //======================================================================= @@ -97,120 +130,94 @@ SMDS_PositionPtr SMDS_MeshNode::GetPosition() const */ //======================================================================= -namespace +class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator { - struct InverseIterator: public SMDS_ElemIterator +private: + SMDS_Mesh* myMesh; + vtkIdType* myCells; + int myNcells; + SMDSAbs_ElementType myType; + int iter; + vector cellList; + +public: + SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) : + myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) { - const SMDS_Mesh* myMesh; - size_t myIter; - std::vector myCellList; - - InverseIterator(const SMDS_Mesh * mesh = 0, - const vtkIdType* cells = 0, - const int ncells = 0, - SMDSAbs_ElementType type = SMDSAbs_All) - : myMesh(mesh), myIter(0) + if ( ncells ) { - if ( ncells ) + cellList.reserve( ncells ); + if (type == SMDSAbs_All) { - myCellList.reserve( ncells ); - if (type == SMDSAbs_All) - { - myCellList.assign( cells, cells + ncells ); - } - else + cellList.assign( cells, cells + ncells ); + } + else + { + for (int i = 0; i < ncells; i++) { - for (int i = 0; i < ncells; i++) + int vtkId = cells[i]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) { - int vtkId = cells[i]; - int smdsId = myMesh->FromVtkToSmds( vtkId ); - const SMDS_MeshElement* elem = myMesh->FindElement( smdsId ); - if ( elem->GetType() == type ) - { - myCellList.push_back(vtkId); - } + cellList.push_back(vtkId); } } } + myCells = cellList.empty() ? 0 : &cellList[0]; + myNcells = cellList.size(); } + } - bool more() - { - return ( myIter < myCellList.size() ); - } - - const SMDS_MeshElement* next() - { - int vtkId = myCellList[ myIter++ ]; - int smdsId = myMesh->FromVtkToSmds( vtkId ); - const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); - if (!elem) - { - MESSAGE("InverseIterator problem Null element"); - throw SALOME_Exception("InverseIterator problem Null element"); - } - return elem; - } - }; - - //======================================================================= - /*! - * \brief Iterator on a node - */ - //======================================================================= - - template< class ELEM_ITERATOR > - struct Iterator : public ELEM_ITERATOR + bool more() { - typedef typename ELEM_ITERATOR::value_type element_type; - const SMDS_MeshNode* myNode; - - Iterator( const SMDS_MeshNode* n ): myNode( n ) {} + return (iter < myNcells); + } - virtual bool more() - { - return myNode; - } - virtual element_type next() + const SMDS_MeshElement* next() + { + int vtkId = myCells[iter]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (!elem) { - element_type res = static_cast( myNode ); - myNode = 0; - return res; + MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element"); + throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element"); } - }; -} + iter++; + return elem; + } +}; SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const { - if ( GetMesh()->NbElements() > 0 ) // avoid building links + if ( SMDS_Mesh::_meshList[myMeshId]->NbElements() > 0 ) // avoid building links { - vtkCellLinks::Link& l = getGrid()->GetLinks()->GetLink( GetVtkID() ); - return boost::make_shared< InverseIterator >( GetMesh(), l.cells, l.ncells, type ); + vtkCellLinks::Link& l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetLinks()->GetLink(myVtkID); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); } else { - return boost::make_shared< InverseIterator >(); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], 0, 0, type)); } } -SMDS_ElemIteratorPtr SMDS_MeshNode::nodesIterator() const -{ - return boost::make_shared< Iterator< SMDS_ElemIterator > >( this ); -} - -SMDS_NodeIteratorPtr SMDS_MeshNode::nodeIterator() const +SMDS_ElemIteratorPtr SMDS_MeshNode::elementsIterator(SMDSAbs_ElementType type) const { - return boost::make_shared< Iterator< SMDS_NodeIterator > >( this ); + if ( type == SMDSAbs_Node ) + return SMDS_MeshElement::elementsIterator( SMDSAbs_Node ); + else + return GetInverseElementIterator( type ); } -const SMDS_MeshNode* SMDS_MeshNode::GetNode(const int ind) const +int SMDS_MeshNode::NbNodes() const { - return ind == 0 ? this : 0; + return 1; } double* SMDS_MeshNode::getCoord() const { - return getGrid()->GetPoint( GetVtkID() ); + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID); } double SMDS_MeshNode::X() const @@ -239,30 +246,41 @@ double SMDS_MeshNode::Z() const void SMDS_MeshNode::GetXYZ(double xyz[3]) const { - return getGrid()->GetPoint( GetVtkID(), xyz ); + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID,xyz); } //================================================================================ -void SMDS_MeshNode::setXYZ( double x, double y, double z ) +void SMDS_MeshNode::setXYZ(double x, double y, double z) +{ + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkPoints *points = mesh->getGrid()->GetPoints(); + points->InsertPoint(myVtkID, x, y, z); + mesh->adjustBoundingBox(x, y, z); + mesh->setMyModified(); +} + +SMDSAbs_ElementType SMDS_MeshNode::GetType() const +{ + return SMDSAbs_Node; +} + +vtkIdType SMDS_MeshNode::GetVtkType() const { - vtkPoints *points = getGrid()->GetPoints(); - points->InsertPoint( GetVtkID(), x, y, z ); - //GetMesh()->adjustBoundingBox(x, y, z); - GetMesh()->setMyModified(); + return VTK_VERTEX; } //======================================================================= //function : AddInverseElement //purpose : //======================================================================= -void SMDS_MeshNode::AddInverseElement( const SMDS_MeshElement* elem ) +void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) { - SMDS_UnstructuredGrid* grid = getGrid(); + SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); if ( grid->HasLinks() ) { vtkCellLinks *Links = grid->GetLinks(); - Links->ResizeCellList( GetVtkID(), 1 ); - Links->AddCellReference( elem->GetVtkID(), GetVtkID() ); + Links->ResizeCellList(myVtkID, 1); + Links->AddCellReference(ME->getVtkId(), myVtkID); } } @@ -272,7 +290,7 @@ void SMDS_MeshNode::AddInverseElement( const SMDS_MeshElement* elem ) //======================================================================= void SMDS_MeshNode::ClearInverseElements() { - getGrid()->ResizeCellList( GetVtkID(), 0); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0); } //================================================================================ @@ -284,17 +302,17 @@ void SMDS_MeshNode::ClearInverseElements() int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const { int nb = 0; - SMDS_Mesh *mesh = GetMesh(); - if ( mesh->NbElements() > 0 ) // avoid building links + if ( SMDS_Mesh::_meshList[myMeshId]->NbElements() > 0 ) // avoid building links { - vtkCellLinks::Link& l = mesh->GetGrid()->GetLinks()->GetLink( GetVtkID() ); + vtkCellLinks::Link& l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetLinks()->GetLink(myVtkID); if ( type == SMDSAbs_All ) return l.ncells; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; for ( int i = 0; i < l.ncells; i++ ) { - const SMDS_MeshElement* elem = mesh->FindElement( mesh->FromVtkToSmds( l.cells[i] )); + const SMDS_MeshElement* elem = mesh->FindElement( mesh->fromVtkToSmds( l.cells[i] )); nb += ( elem->GetType() == type ); } } diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index b156b911c..2c8bad7be 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -31,53 +31,50 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_Position.hxx" +#include "ObjectPool.hxx" class SMDS_EXPORT SMDS_MeshNode: public SMDS_MeshElement { - public: +public: + friend class SMESHDS_Mesh; + friend class SMDS_Mesh; + friend class ObjectPool; + friend class SMDS_VtkFace; - void setXYZ(double x, double y, double z); + void Print(std::ostream & OS) const; double X() const; // ! NOT thread safe methods ! double Y() const; double Z() const; void GetXYZ(double xyz[3]) const; // thread safe getting coords - SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const; - - SMDS_PositionPtr GetPosition() const; // WARNING result is std::unique_ptr ! - void SetPosition(const SMDS_PositionPtr& aPos, int shapeID = 0 ); - - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Node; } - virtual VTKCellType GetVtkType() const { return VTK_VERTEX; } + const SMDS_PositionPtr& GetPosition() const; + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Node;} virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_NONE; } - virtual int NbNodes() const { return 1; } - virtual int NbEdges() const { return 0; } - virtual int NbFaces() const { return 0; } + virtual int NbNodes() const; - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; - virtual const SMDS_MeshNode* GetNode(const int ind) const; - - virtual bool IsPoly() const { return false; } - virtual bool IsQuadratic() const { return false; } - virtual bool IsMediumNode(const SMDS_MeshNode* node) const { return false; } - virtual int NbCornerNodes() const { return 1; } - - void Print(std::ostream & OS) const; - - private: + void SetPosition(const SMDS_PositionPtr& aPos); + void setXYZ(double x, double y, double z); - void init(double x=0, double y=0, double z=0); + static int nbNodes; +protected: + SMDS_MeshNode(); + SMDS_MeshNode(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); + virtual ~SMDS_MeshNode(); + void init(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); double* getCoord() const; - void AddInverseElement (const SMDS_MeshElement * elem); - void RemoveInverseElement(const SMDS_MeshElement * elem); + void AddInverseElement(const SMDS_MeshElement * ME); + void RemoveInverseElement(const SMDS_MeshElement * parent); void ClearInverseElements(); - friend class SMDS_Mesh; + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; +private: + SMDS_PositionPtr myPosition; }; #endif diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx new file mode 100644 index 000000000..64b7baed1 --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.cxx @@ -0,0 +1,161 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 : SMDS_MeshNodeIDFactory.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_MeshNodeIDFactory.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include +#include + +using namespace std; + +//======================================================================= +//function : SMDS_MeshNodeIDFactory +//purpose : +//======================================================================= +SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() : + SMDS_MeshIDFactory(), myMin(0), myMax(0) +{ +} + +//======================================================================= +//function : BindID +//purpose : +//======================================================================= +bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem) +{ + updateMinMax(ID); + return true; +} + +//======================================================================= +//function : MeshElement +//purpose : +//======================================================================= +SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID) +{ + // commented since myMax can be 0 after ReleaseID() +// if ((ID < 1) || (ID > myMax)) +// return NULL; + const SMDS_MeshElement* elem = GetMesh()->FindNode(ID); + return (SMDS_MeshElement*) (elem); +} + +//======================================================================= +//function : GetFreeID +//purpose : +//======================================================================= +int SMDS_MeshNodeIDFactory::GetFreeID() +{ + int ID; + do { + ID = SMDS_MeshIDFactory::GetFreeID(); + } while ( MeshElement( ID )); + return ID; +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshNodeIDFactory::ReleaseID(const int ID, int vtkId) +{ + SMDS_MeshIDFactory::ReleaseID(ID); + myMesh->setMyModified(); + if (ID == myMax) + myMax = 0; // --- force updateMinMax + if (ID == myMin) + myMax = 0; // --- force updateMinMax +} + +//======================================================================= +//function : GetMaxID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMaxID() const +{ + if (myMax == 0) + updateMinMax(); + return myMax; +} + +//======================================================================= +//function : GetMinID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMinID() const +{ + if (myMax == 0) + updateMinMax(); + return myMin; +} + +//======================================================================= +//function : updateMinMax +//purpose : +//======================================================================= + +void SMDS_MeshNodeIDFactory::updateMinMax() const +{ + myMin = INT_MAX; + myMax = 0; + for (size_t i = 0; i < myMesh->myNodes.size(); i++) + { + if (myMesh->myNodes[i]) + { + int id = myMesh->myNodes[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + } + if (myMin == INT_MAX) + myMin = 0; +} + +SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const +{ + return myMesh->elementsIterator(SMDSAbs_Node); +} + +void SMDS_MeshNodeIDFactory::Clear() +{ + myMin = myMax = 0; + SMDS_MeshIDFactory::Clear(); +} + +void SMDS_MeshNodeIDFactory::emptyPool(int maxId) +{ + SMDS_MeshIDFactory::emptyPool(maxId); + myMax = maxId; +} diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx new file mode 100644 index 000000000..80c12716b --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 : SMDS_MeshElementIDFactory.hxx +// Module : SMESH +// +#ifndef _SMDS_MeshNodeIDFactory_HeaderFile +#define _SMDS_MeshNodeIDFactory_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshIDFactory.hxx" +#include "SMDS_ElemIterator.hxx" + +#include + +class SMDS_MeshElement; + +class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory +{ +public: + SMDS_MeshNodeIDFactory(); + bool BindID(int ID, SMDS_MeshElement * elem); + SMDS_MeshElement * MeshElement(int ID); + virtual int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); + int GetMaxID() const; + int GetMinID() const; + SMDS_ElemIteratorPtr elementsIterator() const; + virtual void Clear(); + virtual void emptyPool(int maxId); + +protected: + virtual void updateMinMax() const; + void updateMinMax(int id) const + { + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + + mutable int myMin, myMax; + +}; + +#endif diff --git a/src/SMDS/SMDS_MeshVolume.cxx b/src/SMDS/SMDS_MeshVolume.cxx index 755285447..a56c119b7 100644 --- a/src/SMDS/SMDS_MeshVolume.cxx +++ b/src/SMDS/SMDS_MeshVolume.cxx @@ -25,244 +25,18 @@ // Author : Jean-Michel BOULCOURT // Module : SMESH // - #include "SMDS_MeshVolume.hxx" +//======================================================================= +//function : Print +//purpose : +//======================================================================= -#include "SMDS_Mesh.hxx" -#include "SMDS_VolumeTool.hxx" -#include "SMDS_VtkCellIterator.hxx" - -#include - -// init a polyherdon -void SMDS_MeshVolume::init( const std::vector& nodes, - const std::vector& nbNodesPerFace ) -{ - std::vector ptIds; - ptIds.reserve( nodes.size() + nbNodesPerFace.size() + 1 ); - - size_t nbFaces = nbNodesPerFace.size(); - for ( size_t iN = 0, iF = 0; iF < nbFaces; iF++ ) - { - int nf = nbNodesPerFace[iF]; - ptIds.push_back(nf); - for (int n = 0; n < nf; n++) - ptIds.push_back( nodes[ iN++ ]->GetVtkID() ); - } - - int vtkID = getGrid()->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]); - setVtkID( vtkID ); -} - -void SMDS_MeshVolume::init( const std::vector& vtkNodeIds ) -{ - SMDSAbs_EntityType aType = SMDSEntity_Tetra; - switch ( vtkNodeIds.size()) // cases are in order of usage frequency - { - case 4: aType = SMDSEntity_Tetra; break; - case 5: aType = SMDSEntity_Pyramid; break; - case 8: aType = SMDSEntity_Hexa; break; - case 6: aType = SMDSEntity_Penta; break; - case 10: aType = SMDSEntity_Quad_Tetra; break; - case 20: aType = SMDSEntity_Quad_Hexa; break; - case 13: aType = SMDSEntity_Quad_Pyramid; break; - case 27: aType = SMDSEntity_TriQuad_Hexa; break; - case 15: aType = SMDSEntity_Quad_Penta; break; - case 18: aType = SMDSEntity_BiQuad_Penta; break; - case 12: aType = SMDSEntity_Hexagonal_Prism; break; - default: throw SALOME_Exception("wrong volume nodes"); - } - SMDS_MeshCell::init( aType, vtkNodeIds ); -} - -const SMDS_MeshNode* SMDS_MeshVolume::GetNode(const int ind) const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::GetNode( ind ); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0, nbPoints = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; - if ( ind < nbPoints + nodesInFace ) - return GetMesh()->FindNodeVtk( ptIds[ ind + i ]); - nbPoints += nodesInFace; - id += (nodesInFace + 1); - } - return 0; -} -int SMDS_MeshVolume::NbNodes() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::NbNodes(); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0, nbPoints = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; - nbPoints += nodesInFace; - id += (nodesInFace + 1); - } - return nbPoints; -} - -int SMDS_MeshVolume::NbFaces() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::NbFaces(); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - return nFaces; - -} -int SMDS_MeshVolume::NbEdges() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::NbEdges(); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0, nbEdges = 0; - for (int i = 0; i < nFaces; i++) - { - int edgesInFace = ptIds[id]; - id += (edgesInFace + 1); - nbEdges += edgesInFace; - } - nbEdges = nbEdges / 2; - return nbEdges; -} - -int SMDS_MeshVolume::GetNodeIndex( const SMDS_MeshNode* node ) const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::GetNodeIndex( node ); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0; - for (int iF = 0; iF < nFaces; iF++) - { - int nodesInFace = ptIds[id]; - for ( vtkIdType i = 0; i < nodesInFace; ++i ) - if ( ptIds[id+i+1] == node->GetVtkID() ) - return id+i-iF; - id += (nodesInFace + 1); - } - return -1; -} -bool SMDS_MeshVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) -{ - return false; -} - -bool SMDS_MeshVolume::IsMediumNode(const SMDS_MeshNode* node) const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::IsMediumNode( node ); - - return false; -} - -int SMDS_MeshVolume::NbCornerNodes() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::NbCornerNodes(); - - return NbNodes(); -} - -int SMDS_MeshVolume::NbFaceNodes (const int face_ind) const +SMDSAbs_ElementType SMDS_MeshVolume::GetType() const { - if ( !IsPoly() ) - return SMDS_VolumeTool( this ).NbFaceNodes( face_ind-1 ); - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0, nbNodes = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; - id += (nodesInFace + 1); - if (i == face_ind - 1) - { - nbNodes = nodesInFace; - break; - } - } - return nbNodes; + return SMDSAbs_Volume; } -const SMDS_MeshNode* SMDS_MeshVolume::GetFaceNode (const int face_ind, const int node_ind) const +vtkIdType SMDS_MeshVolume::GetVtkType() const { - if ( !IsPoly() ) - return SMDS_VolumeTool( this ).GetFaceNodes( face_ind-1 )[ node_ind - 1 ]; - - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] - if (i == face_ind - 1) // first face is number 1 - { - if ((node_ind > 0) && (node_ind <= nodesInFace)) - return GetMesh()->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node - } - id += (nodesInFace + 1); - } - return 0; -} - -std::vector SMDS_MeshVolume::GetQuantities() const -{ - std::vector quantities; - if ( IsPoly() ) - { - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] - quantities.push_back( nodesInFace ); - id += (nodesInFace + 1); - } - } - return quantities; -} - -/////////////////////////////////////////////////////////////////////////////// -/// Create an iterator which iterate on nodes owned by the element. -/////////////////////////////////////////////////////////////////////////////// -SMDS_ElemIteratorPtr SMDS_MeshVolume::nodesIterator() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::nodesIterator(); - - return boost::make_shared< SMDS_VtkCellIteratorPolyH<> >( GetMesh(), GetVtkID(), GetEntityType()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Create an iterator which iterate on nodes owned by the element. -/////////////////////////////////////////////////////////////////////////////// -SMDS_NodeIteratorPtr SMDS_MeshVolume::nodeIterator() const -{ - if ( !IsPoly() ) - return SMDS_MeshCell::nodeIterator(); - - return boost::make_shared< SMDS_VtkCellIteratorPolyH< SMDS_NodeIterator> >( GetMesh(), GetVtkID(), GetEntityType()); + return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes } diff --git a/src/SMDS/SMDS_MeshVolume.hxx b/src/SMDS/SMDS_MeshVolume.hxx index 7a69da0a6..15887bdcd 100644 --- a/src/SMDS/SMDS_MeshVolume.hxx +++ b/src/SMDS/SMDS_MeshVolume.hxx @@ -31,42 +31,11 @@ #include "SMDS_MeshCell.hxx" -/*! - * \brief Mesh volume. This type is not allocated. - * It is only used as function argument type to provide more clear semantic - * and to provide API specific to polyherdal volume - */ -class SMDS_EXPORT SMDS_MeshVolume : public SMDS_MeshCell +class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshCell { - void init( const std::vector& nodes, - const std::vector& nbNodesPerFace ); // init a polyherdon - - void init( const std::vector& vtkNodeIds ); - - friend class SMDS_Mesh; - - public: - virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Volume; } - virtual const SMDS_MeshNode* GetNode(const int ind) const; - virtual int NbNodes() const; - virtual int NbFaces() const; - virtual int NbEdges() const; - virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); - virtual bool IsMediumNode(const SMDS_MeshNode* node) const; - virtual int NbCornerNodes() const; - - virtual SMDS_ElemIteratorPtr nodesIterator() const = 0; - virtual SMDS_NodeIteratorPtr nodeIterator() const = 0; - - // 1 <= face_ind <= NbFaces() - int NbFaceNodes (const int face_ind) const; - // 1 <= face_ind <= NbFaces() - // 1 <= node_ind <= NbFaceNodes() - const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; - - std::vector GetQuantities() const; - - static SMDSAbs_ElementType Type() { return SMDSAbs_Volume; } + + public: + SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx index 2ddc79d87..54ead2af0 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx @@ -28,20 +28,22 @@ #include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_IteratorOfElements.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_Mesh.hxx" -#include +#include "utilities.h" -#include +using namespace std; //======================================================================= //function : Constructor //purpose : //======================================================================= -SMDS_PolygonalFaceOfNodes:: -SMDS_PolygonalFaceOfNodes (const std::vector& nodes) +SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes + (const std::vector& nodes) { + //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes"); myNodes = nodes; } @@ -52,40 +54,41 @@ SMDS_PolygonalFaceOfNodes (const std::vector& nodes) SMDSAbs_ElementType SMDS_PolygonalFaceOfNodes::GetType() const { return SMDSAbs_Face; + //return SMDSAbs_PolygonalFace; } //======================================================================= //function : ChangeNodes //purpose : //======================================================================= -// bool SMDS_PolygonalFaceOfNodes::ChangeNodes (std::vector nodes) -// { -// if (nodes.size() < 3) -// return false; +bool SMDS_PolygonalFaceOfNodes::ChangeNodes (std::vector nodes) +{ + if (nodes.size() < 3) + return false; -// myNodes = nodes; + myNodes = nodes; -// return true; -// } + return true; +} //======================================================================= //function : ChangeNodes //purpose : to support the same interface, as SMDS_FaceOfNodes //======================================================================= -// bool SMDS_PolygonalFaceOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[], -// const int nbNodes) -// { -// if (nbNodes < 3) -// return false; +bool SMDS_PolygonalFaceOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes) +{ + if (nbNodes < 3) + return false; -// myNodes.resize(nbNodes); -// int i = 0; -// for (; i < nbNodes; i++) { -// myNodes[i] = nodes[i]; -// } + myNodes.resize(nbNodes); + int i = 0; + for (; i < nbNodes; i++) { + myNodes[i] = nodes[i]; + } -// return true; -// } + return true; +} //======================================================================= //function : NbNodes @@ -127,12 +130,65 @@ void SMDS_PolygonalFaceOfNodes::Print(ostream & OS) const OS << myNodes[i] << ") " << endl; } +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= +class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator +{ + public: + SMDS_PolygonalFaceOfNodes_MyIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} +}; + /// =================================================================== /*! * \brief Iterator on edges of face */ /// =================================================================== +class _MyEdgeIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MyEdgeIterator(const SMDS_MeshFace* face):myIndex(0) { + myElems.reserve( face->NbNodes() ); + for ( int i = 0; i < face->NbNodes(); ++i ) { + const SMDS_MeshElement* edge = + SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 )); + if ( edge ) + myElems.push_back( edge ); + } + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator + (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Face: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this )); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr + (new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes)))); + } + return SMDS_ElemIteratorPtr(); +} + /*! * \brief Return node by its index * \param ind - node index @@ -142,13 +198,3 @@ const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const { return myNodes[ WrappedIndex( ind )]; } - -SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::nodesIterator() const -{ - return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); -} - -SMDS_NodeIteratorPtr SMDS_PolygonalFaceOfNodes::nodeIterator() const -{ - return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); -} diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx index f06352ede..33dd39d0f 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx @@ -27,9 +27,15 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_CellOfNodes.hxx" +#include "SMDS_MeshFace.hxx" +//#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Iterator.hxx" -class SMDS_EXPORT SMDS_PolygonalFaceOfNodes : public SMDS_CellOfNodes +#include + +//class SMDS_PolygonalFaceOfNodes:public SMDS_FaceOfNodes +class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace { public: SMDS_PolygonalFaceOfNodes (const std::vector& nodes); @@ -37,10 +43,13 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes : public SMDS_CellOfNodes virtual SMDSAbs_ElementType GetType() const; virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Polygon; } virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_POLYGON; } - virtual bool IsPoly() const { return true; } - virtual bool IsQuadratic() const { return false; } - virtual bool IsMediumNode(const SMDS_MeshNode* node) const { return false; } - virtual int NbCornerNodes() const { return NbNodes(); } + virtual bool IsPoly() const { return true; }; + + bool ChangeNodes (std::vector nodes); + + bool ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes); + // to support the same interface, as SMDS_FaceOfNodes virtual int NbNodes() const; virtual int NbEdges() const; @@ -48,12 +57,15 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes : public SMDS_CellOfNodes virtual void Print (std::ostream & OS) const; + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ virtual const SMDS_MeshNode* GetNode(const int ind) const; - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; - protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; std::vector myNodes; }; diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx new file mode 100644 index 000000000..20c948ba1 --- /dev/null +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx @@ -0,0 +1,265 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_VolumeTool.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//======================================================================= +//function : Constructor +//purpose : Create a volume of many faces +//======================================================================= +SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes + (vector nodes, + vector quantities) +: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL) +{ + //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes"); + ChangeNodes(nodes, quantities); +} + +//======================================================================= +//function : GetType +//purpose : +//======================================================================= +SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const +{ +// return SMDSAbs_PolyhedralVolume; + return SMDSAbs_Volume; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= +bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const vector& nodes, + const vector& quantities) +{ + myNodesByFaces = nodes; + myQuantities = quantities; + + // Init fields of parent class, it allows to get only unique nodes(?) + + set aSet; + aSet.insert( nodes.begin(), nodes.end()); + //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes); + delete [] myNodes; + myNbNodes = aSet.size(); + myNodes = new const SMDS_MeshNode* [myNbNodes]; + set::iterator anIter = aSet.begin(); + for (int k=0; anIter != aSet.end(); anIter++, k++) + myNodes[k] = *anIter; + + return true; +} + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbNodes() const +{ + return myNodesByFaces.size(); +} + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbEdges() const +{ + int nbEdges = 0; + + for ( size_t ifa = 0; ifa < myQuantities.size(); ifa++) { + nbEdges += myQuantities[ifa]; + } + nbEdges /= 2; + + return nbEdges; +} + +//======================================================================= +//function : NbFaces +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbFaces() const +{ + return myQuantities.size(); +} + +//======================================================================= +//function : NbFaceNodes +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbFaceNodes (const int face_ind) const +{ + if (face_ind < 1 || (int)myQuantities.size() < face_ind) + return 0; + return myQuantities[face_ind - 1]; +} + +//======================================================================= +//function : GetFaceNode +//purpose : +//======================================================================= +const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetFaceNode (const int face_ind, + const int node_ind) const +{ + if (node_ind < 1 || NbFaceNodes(face_ind) < node_ind) + return NULL; + + int i, first_node = 0; + for (i = 0; i < face_ind - 1; i++) { + first_node += myQuantities[i]; + } + + return myNodesByFaces[first_node + node_ind - 1]; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= +void SMDS_PolyhedralVolumeOfNodes::Print (ostream & OS) const +{ + OS << "polyhedral volume <" << GetID() << "> : "; + + int faces_len = myQuantities.size(); + //int nodes_len = myNodesByFaces.size(); + int cur_first_node = 0; + + int i, j; + for (i = 0; i < faces_len; i++) { + OS << "face_" << i << " ("; + for (j = 0; j < myQuantities[i] - 1; j++) { + OS << myNodesByFaces[cur_first_node + j] << ","; + } + OS << myNodesByFaces[cur_first_node + j] << ") "; + cur_first_node += myQuantities[i]; + } +} + +//======================================================================= +//function : ChangeNodes +//purpose : usage disabled +//======================================================================= +bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes) +{ + return false; +} + +/// =================================================================== +/*! + * \brief Iterator on node of volume + */ +/// =================================================================== + +struct _MyIterator:public SMDS_NodeVectorElemIterator +{ + _MyIterator(const vector& nodes): + SMDS_NodeVectorElemIterator( nodes.begin(), nodes.end()) {} +}; + +/// =================================================================== +/*! + * \brief Iterator on faces or edges of volume + */ +/// =================================================================== + +class _MySubIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) { + SMDS_VolumeTool vTool(vol); + if (type == SMDSAbs_Face) + vTool.GetAllExistingFaces( myElems ); + else + vTool.GetAllExistingEdges( myElems ); + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +//================================================================================ +/*! + * \brief Return Iterator of sub elements + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Volume: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new _MyIterator(myNodesByFaces)); + case SMDSAbs_Face: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge)); + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); + } +} + +//================================================================================ +/*! + * \brief Return iterator on unique nodes + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const +{ + return SMDS_ElemIteratorPtr + (new SMDS_NodeArrayElemIterator( myNodes, & myNodes[ myNbNodes ])); +} + +//================================================================================ +/*! + * \brief Return node by its index + */ +//================================================================================ + +const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const +{ + return myNodesByFaces[ ind ]; +} diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx new file mode 100644 index 000000000..cba8a9169 --- /dev/null +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_PolyhedralVolumeOfNodes.hxx +// Module : SMESH +// +#ifndef _SMDS_PolyhedralVolumeOfNodes_HeaderFile +#define _SMDS_PolyhedralVolumeOfNodes_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_VolumeOfNodes.hxx" + +class SMDS_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes +{ + public: + SMDS_PolyhedralVolumeOfNodes (std::vector nodes, + std::vector quantities); + + //virtual ~SMDS_PolyhedralVolumeOfNodes(); + + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Polyhedra; } + virtual bool IsPoly() const { return true; }; + + bool ChangeNodes (const std::vector & nodes, + const std::vector & quantities); + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() + + const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; + // 1 <= face_ind <= NbFaces() + // 1 <= node_ind <= NbFaceNodes() + + const std::vector & GetQuanities() const { return myQuantities; } + + virtual void Print (std::ostream & OS) const; + + /*! + * \brief Return node by its index + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + /*! + * \brief Return iterator on unique nodes + */ + SMDS_ElemIteratorPtr uniqueNodesIterator() const; + /*! + * \brief Return nb of unique nodes + */ + int NbUniqueNodes() const { return myNbNodes; } + +protected: + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + + private: + // usage disabled + bool ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes); + + private: + std::vector myNodesByFaces; + std::vector myQuantities; +}; + +#endif diff --git a/src/SMDS/SMDS_Position.cxx b/src/SMDS/SMDS_Position.cxx new file mode 100644 index 000000000..e7c408f07 --- /dev/null +++ b/src/SMDS/SMDS_Position.cxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_Position.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#include "SMDS_Position.hxx" +#include "utilities.h" + +//======================================================================= +//function : SMDS_Position +//purpose : +//======================================================================= + +SMDS_Position::SMDS_Position() +{ + //MESSAGE("########################## SMDS_Position "); +} + +//======================================================================= +//function : GetDim +//purpose : +//======================================================================= + +int SMDS_Position::GetDim() const +{ +// switch ( GetTypeOfPosition() ) { +// case SMDS_TOP_UNSPEC: return -1; +// case SMDS_TOP_VERTEX: return 0; +// case SMDS_TOP_EDGE: return 1; +// case SMDS_TOP_FACE: return 2; +// case SMDS_TOP_3DSPACE: return 3; +// } + return GetTypeOfPosition(); +} + + diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx index 62c4042d3..b6976677d 100644 --- a/src/SMDS/SMDS_Position.hxx +++ b/src/SMDS/SMDS_Position.hxx @@ -30,68 +30,23 @@ #include "SMESH_SMDS.hxx" #include "SMDS_TypeOfPosition.hxx" -#include +#include -//class SMDS_Position; +class SMDS_Position; //typedef boost::shared_ptr SMDS_PositionPtr; -//typedef SMDS_Position* SMDS_PositionPtr; +typedef SMDS_Position* SMDS_PositionPtr; class SMDS_EXPORT SMDS_Position { - public: - virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; - int GetDim() const { return GetTypeOfPosition(); } - virtual const double* GetParameters() const = 0; - virtual ~SMDS_Position() {} -}; - -/*! - * \brief Replace "typedef SMDS_Position* SMDS_PositionPtr" by a smart - * pointer allowing implicit casting to derived types; e.g. - * if ( SMDS_FacePositionPtr fPos = node->GetPosition() ) - * fPos->SetUParameter(0); - */ - -template -class SMDS_EXPORT SMDS_Ptr : public std::unique_ptr< T > -{ - bool myIsOwner; - - public: - SMDS_Ptr( T * pos = (T *) 0, bool isOwner=true ): - std::unique_ptr< T >( pos ), myIsOwner( isOwner ) {} - - SMDS_Ptr( const SMDS_Ptr& from ) : myIsOwner( from.myIsOwner ) - { this->swap( const_cast( from )); } - - SMDS_Ptr& operator=( const SMDS_Ptr& from ) - { - myIsOwner = from.myIsOwner; - this->swap( const_cast( from )); - return *this; - } - - template - SMDS_Ptr( const SMDS_Ptr< Y >& base ): myIsOwner( true ) - { - if ( const T* p = dynamic_cast( base.get() )) - { - this->reset( const_cast( p )); - this->myIsOwner = base.IsOwner(); - const_cast< SMDS_Ptr< Y >& >( base ).release(); - } - } - ~SMDS_Ptr() { if ( !myIsOwner ) this->release(); } + public: + virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; + virtual int GetDim() const; + virtual ~SMDS_Position() {} - operator bool () const { return bool( this->get() ); } - bool IsOwner() const { return myIsOwner; } + protected: + SMDS_Position(); }; -class SMDS_EdgePosition; -class SMDS_FacePosition; -typedef SMDS_Ptr< SMDS_Position > SMDS_PositionPtr; -typedef SMDS_Ptr< SMDS_EdgePosition > SMDS_EdgePositionPtr; -typedef SMDS_Ptr< SMDS_FacePosition > SMDS_FacePositionPtr; #endif diff --git a/src/SMDS/SMDS_QuadraticEdge.cxx b/src/SMDS/SMDS_QuadraticEdge.cxx new file mode 100644 index 000000000..9f6cf94df --- /dev/null +++ b/src/SMDS/SMDS_QuadraticEdge.cxx @@ -0,0 +1,160 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File: SMDS_QuadraticEdge.cxx +// Created: 16.01.06 16:25:42 +// Author: Sergey KUUL +// +#include "SMDS_QuadraticEdge.hxx" + +#include "SMDS_SetIterator.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_QuadraticEdge +//purpose : +//======================================================================= + +SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12) + :SMDS_LinearEdge(node1,node2) +{ + //MESSAGE("******************************************************* SMDS_QuadraticEdge"); + myNodes[2]=node12; +} + + +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_QuadraticEdge::Print(ostream & OS) const +{ + OS << "quadratic edge <" << GetID() << "> : ( first-" << myNodes[0] + << " , last-" << myNodes[1] << " , medium-" << myNodes[2] << ") " << endl; +} + + +//======================================================================= +//function : NbNodes +//purpose : +//======================================================================= + +int SMDS_QuadraticEdge::NbNodes() const +{ + return 3; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= + +bool SMDS_QuadraticEdge::ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12) +{ + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node12; + return true; +} + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticEdge::IsMediumNode(const SMDS_MeshNode * node) const +{ + return (myNodes[2]==node); +} + +namespace +{ + //======================================================================= + //class : _MyInterlacedNodeIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeIterator: public SMDS_NodeArrayIterator + { + const SMDS_MeshNode * myNodes[3]; + public: + _MyInterlacedNodeIterator(const SMDS_MeshNode * const * nodes): + SMDS_NodeArrayIterator( myNodes, & myNodes[3] ) + { + myNodes[0] = nodes[0]; + myNodes[1] = nodes[2]; + myNodes[2] = nodes[1]; + } + }; + + //======================================================================= + //class : _MyNodeIterator + //purpose : + //======================================================================= + + class _MyNodeIterator:public SMDS_NodeArrayElemIterator + { + public: + _MyNodeIterator(const SMDS_MeshNode * const * nodes): + SMDS_NodeArrayElemIterator( nodes, & nodes[3] ) {} + }; +} + +//======================================================================= +//function : interlacedNodesIterator +//purpose : +//======================================================================= + +SMDS_NodeIteratorPtr SMDS_QuadraticEdge::interlacedNodesIterator() const +{ + return SMDS_NodeIteratorPtr (new _MyInterlacedNodeIterator (myNodes)); +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)))); + } +} diff --git a/src/SMDS/SMDS_QuadraticEdge.hxx b/src/SMDS/SMDS_QuadraticEdge.hxx new file mode 100644 index 000000000..7eeabf65a --- /dev/null +++ b/src/SMDS/SMDS_QuadraticEdge.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_QuadraticEdge.hxx +// Module : SMESH +// +#ifndef _SMDS_QuadraticEdge_HeaderFile +#define _SMDS_QuadraticEdge_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_LinearEdge.hxx" +#include + +class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge +{ + +public: + SMDS_QuadraticEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12); + + bool ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12); + + void Print(std::ostream & OS) const; + + int NbNodes() const; + + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Quad_Edge; } + + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + SMDS_NodeIteratorPtr interlacedNodesIterator() const; + +protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + +}; +#endif diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx new file mode 100644 index 000000000..49066ac82 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx @@ -0,0 +1,290 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File: SMDS_QuadraticFaceOfNodes.cxx +// Created: 16.01.06 17:12:58 +// Author: Sergey KUUL +// +#include "SMDS_QuadraticFaceOfNodes.hxx" + +#include "SMDS_SetIterator.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" + +#include "utilities.h" + +using namespace std; + + +//======================================================================= +//function : SMDS_QuadraticFaceOfNodes() +//purpose : Constructor +//======================================================================= + +SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1"); + myNodes.resize( 6 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n12; + myNodes[ 4 ] = n23; + myNodes[ 5 ] = n31; +} + + +//======================================================================= +//function : SMDS_QuadraticFaceOfNodes() +//purpose : Constructor +//======================================================================= + +SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2"); + myNodes.resize( 8 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n12; + myNodes[ 5 ] = n23; + myNodes[ 6 ] = n34; + myNodes[ 7 ] = n41; +} + + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticFaceOfNodes::IsMediumNode(const SMDS_MeshNode * node) const +{ + int i=NbNodes()/2; + for(; i : "; + int i, nbNodes = myNodes.size(); + for (i = 0; i < nbNodes - 1; i++) + OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; +} + +namespace { + + //======================================================================= + //class : _MyInterlacedNodeIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeIterator:public SMDS_NodeIterator + { + const vector& mySet; + size_t myIndex; + const int * myInterlace; + public: + _MyInterlacedNodeIterator(const vector& s, + const int * interlace): + mySet(s),myIndex(0),myInterlace(interlace) {} + + bool more() + { + return myIndex < mySet.size(); + } + + const SMDS_MeshNode* next() + { + return mySet[ myInterlace[ myIndex++ ]]; + } + }; + + //======================================================================= + //class : _MyNodeIterator + //purpose : + //======================================================================= + + class _MyNodeIterator : public SMDS_NodeVectorElemIterator + { + public: + _MyNodeIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} + }; + +} + +//======================================================================= +//function : interlacedNodesIterator +//purpose : +//======================================================================= + +SMDS_NodeIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesIterator() const +{ + static int triaInterlace [] = { 0, 3, 1, 4, 2, 5 }; + static int quadInterlace [] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + return SMDS_NodeIteratorPtr + (new _MyInterlacedNodeIterator (myNodes, myNodes.size()==6 ? triaInterlace : quadInterlace)); +} + +/// =================================================================== +/*! + * \brief Iterator on edges of face + */ +/// =================================================================== + +class _MyEdgeIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) { + myElems.reserve( face->NbNodes() ); + SMDS_NodeIteratorPtr nIt = face->interlacedNodesIterator(); + const SMDS_MeshNode* n0 = face->GetNodeWrap( -1 ); + while ( nIt->more() ) { + const SMDS_MeshNode* n1 = nIt->next(); + const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 ); + if ( edge ) + myElems.push_back( edge ); + n0 = n1; + } + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator + (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Face: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this )); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr (new _MyNodeIterator(myNodes)))); + } + return SMDS_ElemIteratorPtr(); +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_QuadraticFaceOfNodes::GetNode(const int ind) const +{ + return myNodes[ ind ]; +} + +SMDSAbs_EntityType SMDS_QuadraticFaceOfNodes::GetEntityType() const +{ + return NbNodes() == 6 ? SMDSEntity_Quad_Triangle : SMDSEntity_Quad_Quadrangle; +} diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx new file mode 100644 index 000000000..8ef0a9da8 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_QuadraticVolumeOfNodes.hxx +// Module : SMESH +// +#ifndef _SMDS_QuadraticFaceOfNodes_HeaderFile +#define _SMDS_QuadraticFaceOfNodes_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshFace.hxx" + +class SMDS_EXPORT SMDS_QuadraticFaceOfNodes:public SMDS_MeshFace +{ +public: + SMDS_QuadraticFaceOfNodes (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + + virtual SMDSAbs_EntityType GetEntityType() const; + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + virtual void Print (std::ostream & OS) const; + + SMDS_NodeIteratorPtr interlacedNodesIterator() const; + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + +protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + private: + std::vector myNodes; +}; + +#endif diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx new file mode 100644 index 000000000..0248ba86b --- /dev/null +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx @@ -0,0 +1,389 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File: SMDS_QuadraticVolumeOfNodes.cxx +// Created: 17.01.06 09:46:11 +// Author: Sergey KUUL +// +#include "SMDS_QuadraticVolumeOfNodes.hxx" + +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_VolumeTool.hxx" + +#include "utilities.h" + +using namespace std; + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor tetrahedron of 10 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); + myNodes.resize( 10 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n12; + myNodes[ 5 ] = n23; + myNodes[ 6 ] = n31; + myNodes[ 7 ] = n14; + myNodes[ 8 ] = n24; + myNodes[ 9 ] = n34; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor pyramid of 13 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); + myNodes.resize( 13 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n12; + myNodes[ 6 ] = n23; + myNodes[ 7 ] = n34; + myNodes[ 8 ] = n41; + myNodes[ 9 ] = n15; + myNodes[ 10 ] = n25; + myNodes[ 11 ] = n35; + myNodes[ 12 ] = n45; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor Pentahedron with 15 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36) +{ + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); + myNodes.resize( 15 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n6; + myNodes[ 6 ] = n12; + myNodes[ 7 ] = n23; + myNodes[ 8 ] = n31; + myNodes[ 9 ] = n45; + myNodes[ 10 ] = n56; + myNodes[ 11 ] = n64; + myNodes[ 12 ] = n14; + myNodes[ 13 ] = n25; + myNodes[ 14 ] = n36; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor Hexahedrons with 20 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); + myNodes.resize( 20 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n6; + myNodes[ 6 ] = n7; + myNodes[ 7 ] = n8; + myNodes[ 8 ] = n12; + myNodes[ 9 ] = n23; + myNodes[ 10 ] = n34; + myNodes[ 11 ] = n41; + myNodes[ 12 ] = n56; + myNodes[ 13 ] = n67; + myNodes[ 14 ] = n78; + myNodes[ 15 ] = n85; + myNodes[ 16 ] = n15; + myNodes[ 17 ] = n26; + myNodes[ 18 ] = n37; + myNodes[ 19 ] = n48; +} + + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticVolumeOfNodes::IsMediumNode(const SMDS_MeshNode* node) const +{ + int nbCorners = 0; + switch (myNodes.size()) { + case 10: nbCorners = 4; break; + case 13: nbCorners = 5; break; + case 15: nbCorners = 6; break; + default: nbCorners = 8; + } + for ( size_t i = nbCorners; i : "; + int i, nbNodes = myNodes.size(); + for (i = 0; i < nbNodes - 1; i++) + OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; +} + + +//======================================================================= +//private class : SMDS_QuadraticVolumeOfNodes_MyIterator +//purpose : +//======================================================================= + +class SMDS_QuadraticVolumeOfNodes_MyIterator : public SMDS_NodeVectorElemIterator +{ +public: + SMDS_QuadraticVolumeOfNodes_MyIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} +}; + +/// =================================================================== +/*! + * \brief Iterator on faces or edges of volume + */ +/// =================================================================== + +class _MySubIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) { + SMDS_VolumeTool vTool(vol); + if (type == SMDSAbs_Face) + vTool.GetAllExistingFaces( myElems ); + else + vTool.GetAllExistingFaces( myElems ); + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticVolumeOfNodes::elementsIterator + (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Volume: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge)); + break; + case SMDSAbs_Face: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face)); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr + (new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes)))); + } + return SMDS_ElemIteratorPtr(); +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_QuadraticVolumeOfNodes::GetNode(const int ind) const +{ + return myNodes[ ind ]; +} + +SMDSAbs_EntityType SMDS_QuadraticVolumeOfNodes::GetEntityType() const +{ + SMDSAbs_EntityType aType = SMDSEntity_Quad_Tetra; + switch(NbNodes()) + { + case 10: aType = SMDSEntity_Quad_Tetra; break; + case 13: aType = SMDSEntity_Quad_Pyramid; break; + case 15: aType = SMDSEntity_Quad_Penta; break; + case 18: aType = SMDSEntity_BiQuad_Penta; break; + case 20: + default: aType = SMDSEntity_Quad_Hexa; break; + } + return aType; +} diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx new file mode 100644 index 000000000..0f3d6a8e6 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx @@ -0,0 +1,131 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_QuadraticVolumeOfNodes.hxx +// Module : SMESH +// +#ifndef _SMDS_QuadraticVolumeOfNodes_HeaderFile +#define _SMDS_QuadraticVolumeOfNodes_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshVolume.hxx" + +class SMDS_EXPORT SMDS_QuadraticVolumeOfNodes: public SMDS_MeshVolume +{ +public: + // tetrahedron of 10 nodes + SMDS_QuadraticVolumeOfNodes (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34); + + // pyramid of 13 nodes + SMDS_QuadraticVolumeOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45); + + // Pentahedron with 15 nodes + SMDS_QuadraticVolumeOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36); + + // Hexahedrons with 20 nodes + SMDS_QuadraticVolumeOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48); + + virtual SMDSAbs_EntityType GetEntityType() const; + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + virtual void Print (std::ostream & OS) const; + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + private: + std::vector myNodes; +}; + +#endif diff --git a/src/SMDS/SMDS_SpacePosition.cxx b/src/SMDS/SMDS_SpacePosition.cxx index b7bcec930..b2b9a7f2e 100644 --- a/src/SMDS/SMDS_SpacePosition.cxx +++ b/src/SMDS/SMDS_SpacePosition.cxx @@ -27,18 +27,19 @@ // #include "SMDS_SpacePosition.hxx" -#include "SMDS_VertexPosition.hxx" SMDS_SpacePosition* SMDS_SpacePosition::_originPosition = new SMDS_SpacePosition(); -SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition() +SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z) { - return SMDS_PositionPtr( _originPosition, /*isOwner=*/false ); } -SMDS_PositionPtr SMDS_VertexPosition::StaticPosition() +SMDS_TypeOfPosition SMDS_SpacePosition::GetTypeOfPosition() const { - static SMDS_Position* _vertexPosition = new SMDS_VertexPosition; - return SMDS_PositionPtr( _vertexPosition, /*isOwner=*/false ); + return SMDS_TOP_3DSPACE; } +SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition() +{ + return _originPosition; +} diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx index 1bbac7b1f..fc2d22cc3 100644 --- a/src/SMDS/SMDS_SpacePosition.hxx +++ b/src/SMDS/SMDS_SpacePosition.hxx @@ -31,15 +31,14 @@ #include "SMDS_Position.hxx" -class SMDS_EXPORT SMDS_SpacePosition : public SMDS_Position +class SMDS_EXPORT SMDS_SpacePosition:public SMDS_Position { - public: - virtual SMDS_TypeOfPosition GetTypeOfPosition() const { return SMDS_TOP_3DSPACE; } - static SMDS_PositionPtr originSpacePosition(); - virtual const double* GetParameters() const { return 0; } - - private: +public: + SMDS_SpacePosition(double x=0, double y=0, double z=0); + virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; + static SMDS_PositionPtr originSpacePosition(); +private: static SMDS_SpacePosition* _originPosition; }; diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 03bff2d66..bf9df36cf 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -36,6 +36,8 @@ #include #include +using namespace std; + SMDS_CellLinks* SMDS_CellLinks::New() { return new SMDS_CellLinks(); @@ -148,7 +150,7 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p // --- type = VTK_POLYHEDRON int cellid = this->InsertNextCell(type, npts, pts); - std::set setOfNodes; + set setOfNodes; setOfNodes.clear(); int nbfaces = npts; int i = 0; @@ -163,7 +165,7 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p } } - std::set::iterator it = setOfNodes.begin(); + set::iterator it = setOfNodes.begin(); for (; it != setOfNodes.end(); ++it) { this->Links->ResizeCellList(*it, 1); @@ -179,24 +181,25 @@ void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) } void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, - std::vector& idCellsNewToOld, int newCellSize) + std::vector& idCellsOldToNew, int newCellSize) { + int alreadyCopied = 0; + this->DeleteLinks(); - // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes" in SMDS numeration. - // We compact only if there were holes + // --- if newNodeSize, create a new compacted vtkPoints - int oldNodeSize = this->GetNumberOfPoints(); - bool updateNodes = ( oldNodeSize > newNodeSize ); - if ( true /*updateNodes*/ ) + if ( newNodeSize ) { - // 21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion - // Use double type for storing coordinates of nodes instead float. + // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. vtkPoints *newPoints = vtkPoints::New(); - newPoints->SetDataType( VTK_DOUBLE ); - newPoints->SetNumberOfPoints( newNodeSize ); + newPoints->SetDataType(VTK_DOUBLE); + newPoints->SetNumberOfPoints(newNodeSize); + + int oldNodeSize = idNodesOldToNew.size(); - int i = 0, alreadyCopied = 0; + int i = 0; while ( i < oldNodeSize ) { // skip a hole if any @@ -212,20 +215,13 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n this->SetPoints(newPoints); newPoints->Delete(); } - else - { - this->Points->Squeeze(); - this->Points->Modified(); - } + this->Points->Squeeze(); - // Compact cells if VTK IDs do not correspond to SMDS IDs or nodes compacted + // --- create new compacted Connectivity, Locations and Types - int oldCellSize = this->Types->GetNumberOfTuples(); - bool updateCells = ( updateNodes || newCellSize != oldCellSize ); - for ( int newID = 0, nbIDs = idCellsNewToOld.size(); newID < nbIDs && !updateCells; ++newID ) - updateCells = ( idCellsNewToOld[ newID ] != newID ); + int oldCellSize = this->Types->GetNumberOfTuples(); - if ( false /*!updateCells*/ ) // no holes in elements + if ( !newNodeSize && oldCellSize == newCellSize ) // no holes in elements { this->Connectivity->Squeeze(); this->Locations->Squeeze(); @@ -235,28 +231,14 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n this->FaceLocations->Squeeze(); this->Faces->Squeeze(); } - this->Connectivity->Modified(); + for ( int i = 0; i < oldCellSize; ++i ) + idCellsOldToNew[i] = i; return; } - - if ((int) idNodesOldToNew.size() < oldNodeSize ) - { - idNodesOldToNew.reserve( oldNodeSize ); - for ( int i = idNodesOldToNew.size(); i < oldNodeSize; ++i ) - idNodesOldToNew.push_back( i ); - } - - // --- create new compacted Connectivity, Locations and Types - - int newConnectivitySize = this->Connectivity->GetNumberOfConnectivityEntries(); - if ( newCellSize != oldCellSize ) - for ( int i = 0; i < oldCellSize - 1; ++i ) - if ( this->Types->GetValue( i ) == VTK_EMPTY_CELL ) - newConnectivitySize -= this->Locations->GetValue( i+1 ) - this->Locations->GetValue( i ); - vtkCellArray *newConnectivity = vtkCellArray::New(); newConnectivity->Initialize(); - newConnectivity->Allocate( newConnectivitySize ); + int oldCellDataSize = this->Connectivity->GetData()->GetSize(); + newConnectivity->Allocate(oldCellDataSize); vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New(); newTypes->Initialize(); @@ -266,24 +248,41 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n newLocations->Initialize(); newLocations->SetNumberOfValues(newCellSize); - std::vector< vtkIdType > pointsCell(1024); // --- points id to fill a new cell + // TODO some polyhedron may be huge (only in some tests) + vtkIdType tmpid[NBMAXNODESINCELL]; + vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell - copyBloc(newTypes, idCellsNewToOld, idNodesOldToNew, - newConnectivity, newLocations, pointsCell ); + alreadyCopied = 0; + int i = 0; + while ( i < oldCellSize ) + { + // skip a hole if any + while ( i < oldCellSize && this->Types->GetValue(i) == VTK_EMPTY_CELL ) + ++i; + int startBloc = i; + // look for a block end + while ( i < oldCellSize && this->Types->GetValue(i) != VTK_EMPTY_CELL ) + ++i; + int endBloc = i; + if ( endBloc > startBloc ) + copyBloc(newTypes, + idCellsOldToNew, idNodesOldToNew, + newConnectivity, newLocations, + pointsCell, alreadyCopied, + startBloc, endBloc); + } + newConnectivity->Squeeze(); if (vtkDoubleArray* diameters = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls { - vtkDoubleArray* newDiameters = vtkDoubleArray::New(); - newDiameters->SetNumberOfComponents(1); - for ( int newCellID = 0; newCellID < newCellSize; newCellID++ ) + for (int oldCellID = 0; oldCellID < oldCellSize; oldCellID++) { - if ( newTypes->GetValue( newCellID ) == VTK_POLY_VERTEX ) - { - int oldCellID = idCellsNewToOld[ newCellID ]; - newDiameters->InsertValue( newCellID, diameters->GetValue( oldCellID )); - } - vtkDataSet::CellData->SetScalars( newDiameters ); + if (this->Types->GetValue(oldCellID) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[ oldCellID ]; + if (newTypes->GetValue(newCellId) == VTK_POLY_VERTEX) + diameters->SetValue( newCellId, diameters->GetValue( oldCellID )); } } @@ -295,23 +294,25 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); newFaces->Initialize(); newFaces->Allocate(this->Faces->GetSize()); - for ( int newCellID = 0; newCellID < newCellSize; newCellID++ ) + for (int i = 0; i < oldCellSize; i++) { - if ( newTypes->GetValue( newCellID ) == VTK_POLYHEDRON ) + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[i]; + if (newTypes->GetValue(newCellId) == VTK_POLYHEDRON) { - int oldCellId = idCellsNewToOld[ newCellID ]; - newFaceLocations->InsertNextValue( newFaces->GetMaxId()+1 ); - int oldFaceLoc = this->FaceLocations->GetValue( oldCellId ); - int nCellFaces = this->Faces->GetValue( oldFaceLoc++ ); - newFaces->InsertNextValue( nCellFaces ); - for ( int n = 0; n < nCellFaces; n++ ) + newFaceLocations->InsertNextValue(newFaces->GetMaxId()+1); + int oldFaceLoc = this->FaceLocations->GetValue(i); + int nCellFaces = this->Faces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(nCellFaces); + for (int n=0; nFaces->GetValue( oldFaceLoc++ ); - newFaces->InsertNextValue( nptsInFace ); - for ( int k = 0; k < nptsInFace; k++ ) + int nptsInFace = this->Faces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(nptsInFace); + for (int k=0; kFaces->GetValue( oldFaceLoc++ ); - newFaces->InsertNextValue( idNodesOldToNew[ oldpt ]); + int oldpt = this->Faces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(idNodesOldToNew[oldpt]); } } } @@ -322,13 +323,13 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } newFaceLocations->Squeeze(); newFaces->Squeeze(); - this->SetCells( newTypes, newLocations, newConnectivity, newFaceLocations, newFaces ); + this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); newFaceLocations->Delete(); newFaces->Delete(); } else { - this->SetCells( newTypes, newLocations, newConnectivity, FaceLocations, Faces ); + this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); } newTypes->Delete(); @@ -348,35 +349,39 @@ void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, if (nbPoints > 0) { memcpy(target, source, 3 * sizeof(double) * nbPoints); - alreadyCopied += nbPoints; + for (int j = start; j < end; j++) + idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId } } -void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray * newTypes, - const std::vector& idCellsNewToOld, - const std::vector& idNodesOldToNew, - vtkCellArray* newConnectivity, - vtkIdTypeArray* newLocations, - std::vector& pointsCell) +void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, + std::vector& idCellsOldToNew, + std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, + vtkIdTypeArray* newLocations, + vtkIdType* pointsCell, + int& alreadyCopied, + int start, + int end) { - for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); iNew++ ) + for (int j = start; j < end; j++) { - int iOld = idCellsNewToOld[ iNew ]; - newTypes->SetValue( iNew, this->Types->GetValue( iOld )); - vtkIdType oldLoc = this->Locations->GetValue( iOld ); + newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); + idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId + vtkIdType oldLoc = this->Locations->GetValue(j); vtkIdType nbpts; vtkIdType *oldPtsCell = 0; - this->Connectivity->GetCell( oldLoc, nbpts, oldPtsCell ); - if ((vtkIdType) pointsCell.size() < nbpts ) - pointsCell.resize( nbpts ); - for ( int l = 0; l < nbpts; l++ ) + this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); + assert(nbpts < NBMAXNODESINCELL); + for (int l = 0; l < nbpts; l++) { int oldval = oldPtsCell[l]; pointsCell[l] = idNodesOldToNew[oldval]; } - /*int newcnt = */newConnectivity->InsertNextCell( nbpts, pointsCell.data() ); - int newLoc = newConnectivity->GetInsertLocation( nbpts ); - newLocations->SetValue( iNew, newLoc ); + /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); + int newLoc = newConnectivity->GetInsertLocation(nbpts); + newLocations->SetValue(alreadyCopied, newLoc); + alreadyCopied++; } } @@ -651,7 +656,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId); SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); downEdge->setNodes(connEdgeId, vtkEdgeId); - std::vector vtkIds; + vector vtkIds; int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds); int downFaces[1000]; unsigned char downTypes[1000]; @@ -700,7 +705,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) // --- check if the edge is already registered by exploration of the faces //CHRONO(41); - std::vector vtkIds; + vector vtkIds; unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType; int *pts = &edgesWithNodes.elems[iedge].nodeIds[0]; SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); @@ -754,7 +759,7 @@ void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) CHRONOSTOP(23);CHRONO(24); - // compact downward connectivity structure: adjust downward arrays size, replace std::vector> by a single std::vector + // compact downward connectivity structure: adjust downward arrays size, replace vector> by a single vector // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use) for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--) @@ -1068,11 +1073,15 @@ SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, std::map >& nodeQuadDomains) { //MESSAGE("extrudeVolumeFromFace " << vtkVolId); - std::vector orderedOriginals( originalNodes.begin(), originalNodes.end() ); + vector orderedOriginals; + orderedOriginals.clear(); + set::const_iterator it = originalNodes.begin(); + for (; it != originalNodes.end(); ++it) + orderedOriginals.push_back(*it); int dim = 0; int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals); - std::vector orderedNodes; + vector orderedNodes; bool isQuadratic = false; switch (orderedOriginals.size()) @@ -1121,7 +1130,7 @@ SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, { double *coords = this->GetPoint(oldId); SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); - newId = newNode->GetVtkID(); + newId = newNode->getVtkId(); if (! nodeQuadDomains.count(oldId)) { std::map emptyMap; diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx index 448fed72d..5936e9759 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.hxx +++ b/src/SMDS/SMDS_UnstructuredGrid.hxx @@ -116,12 +116,9 @@ protected: SMDS_UnstructuredGrid(); ~SMDS_UnstructuredGrid(); void copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, int start, int end); - void copyBloc(vtkUnsignedCharArray *newTypes, - const std::vector& idCellsOldToNew, - const std::vector& idNodesOldToNew, - vtkCellArray* newConnectivity, - vtkIdTypeArray* newLocations, - std::vector& pointsCell); + void copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, + int start, int end); std::vector _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1 std::vector _downTypes; diff --git a/src/SMDS/SMDS_VertexPosition.cxx b/src/SMDS/SMDS_VertexPosition.cxx new file mode 100644 index 000000000..0e2d183e2 --- /dev/null +++ b/src/SMDS/SMDS_VertexPosition.cxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_VertexPosition.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#include "SMDS_VertexPosition.hxx" + +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_VertexPosition +//purpose : +//======================================================================= + +SMDS_VertexPosition:: SMDS_VertexPosition() +{ + //MESSAGE("*********************************************** SMDS_VertexPosition " << aVertexId); +} + +SMDS_TypeOfPosition SMDS_VertexPosition::GetTypeOfPosition() const +{ + //MESSAGE("################################################# GetTypeOfPosition"); + return SMDS_TOP_VERTEX; +} diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx index 4db67d527..0943de91c 100644 --- a/src/SMDS/SMDS_VertexPosition.hxx +++ b/src/SMDS/SMDS_VertexPosition.hxx @@ -31,12 +31,12 @@ #include "SMDS_Position.hxx" -class SMDS_EXPORT SMDS_VertexPosition : public SMDS_Position +class SMDS_EXPORT SMDS_VertexPosition:public SMDS_Position { - public: - SMDS_TypeOfPosition GetTypeOfPosition() const { return SMDS_TOP_VERTEX; } - virtual const double* GetParameters() const { return 0; } - static SMDS_PositionPtr StaticPosition(); + + public: + SMDS_TypeOfPosition GetTypeOfPosition() const; + SMDS_VertexPosition(); }; #endif diff --git a/src/SMDS/SMDS_VolumeOfFaces.cxx b/src/SMDS/SMDS_VolumeOfFaces.cxx new file mode 100644 index 000000000..929c54675 --- /dev/null +++ b/src/SMDS/SMDS_VolumeOfFaces.cxx @@ -0,0 +1,169 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_VolumeOfFaces.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_VolumeOfFaces.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_VolumeOfFaces::Print(ostream & OS) const +{ + OS << "volume <" << GetID() << "> : "; + int i; + for (i = 0; i < NbFaces()-1; ++i) OS << myFaces[i] << ","; + OS << myFaces[i]<< ") " << endl; +} + + +int SMDS_VolumeOfFaces::NbFaces() const +{ + return myNbFaces; +} + +class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator +{ + const SMDS_MeshFace* const *mySet; + int myLength; + int index; + public: + SMDS_VolumeOfFaces_MyIterator(const SMDS_MeshFace* const *s, int l): + mySet(s),myLength(l),index(0) {} + + bool more() + { + return index + + +class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume +{ + + public: + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + const SMDS_MeshFace * face2, + const SMDS_MeshFace * face3, + const SMDS_MeshFace * face4); + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + const SMDS_MeshFace * face2, + const SMDS_MeshFace * face3, + const SMDS_MeshFace * face4, + const SMDS_MeshFace * face5); + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + const SMDS_MeshFace * face2, + const SMDS_MeshFace * face3, + const SMDS_MeshFace * face4, + const SMDS_MeshFace * face5, + const SMDS_MeshFace * face6); + + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) {return false;} + virtual void Print(std::ostream & OS) const; + + virtual int NbFaces() const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + const SMDS_MeshFace * myFaces[6]; + int myNbFaces; +}; +#endif diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index f652eeaf2..3f76d5322 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -27,82 +27,90 @@ #endif #include "SMDS_VolumeOfNodes.hxx" - #include "SMDS_MeshNode.hxx" #include "SMDS_SetIterator.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" -#include - -#include +using namespace std; /////////////////////////////////////////////////////////////////////////////// /// Create an hexahedron. node 1,2,3,4 and 5,6,7,8 are quadrangle and /// 5,1 and 7,3 are an edges. /////////////////////////////////////////////////////////////////////////////// -SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6, - const SMDS_MeshNode * node7, - const SMDS_MeshNode * node8) -{ - myNbNodes = 8; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; - myNodes[5]=node6; - myNodes[6]=node7; - myNodes[7]=node8; +SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8) +{ + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 8; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; + myNodes[5]=node6; + myNodes[6]=node7; + myNodes[7]=node8; } -SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4) +SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4) { - myNbNodes = 4; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 4; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; } -SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5) +SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5) { - myNbNodes = 5; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 5; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; } -SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6) +SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6) { - myNbNodes = 6; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; - myNodes[5]=node6; + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 6; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; + myNodes[5]=node6; } bool SMDS_VolumeOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[], @@ -128,49 +136,98 @@ SMDS_VolumeOfNodes::~SMDS_VolumeOfNodes() } } -void SMDS_VolumeOfNodes::Print(std::ostream & OS) const +void SMDS_VolumeOfNodes::Print(ostream & OS) const { - OS << "volume <" << GetID() << "> : "; - int i; - for (i = 0; i < NbNodes()-1; ++i) OS << myNodes[i] << ","; - OS << myNodes[NbNodes()-1]<< ") " << std::endl; + OS << "volume <" << GetID() << "> : "; + int i; + for (i = 0; i < NbNodes()-1; ++i) OS << myNodes[i] << ","; + OS << myNodes[NbNodes()-1]<< ") " << endl; } int SMDS_VolumeOfNodes::NbFaces() const { - switch(NbNodes()) - { - case 4: return 4; - case 5: return 5; - case 6: return 5; - case 8: return 6; - default: MESSAGE("invalid number of nodes"); - } - return 0; + switch(NbNodes()) + { + case 4: return 4; + case 5: return 5; + case 6: return 5; + case 8: return 6; + default: MESSAGE("invalid number of nodes"); + } + return 0; } int SMDS_VolumeOfNodes::NbNodes() const { - return myNbNodes; + return myNbNodes; } int SMDS_VolumeOfNodes::NbEdges() const { - switch(NbNodes()) + switch(NbNodes()) + { + case 4: return 6; + case 5: return 8; + case 6: return 9; + case 8: return 12; + default: MESSAGE("invalid number of nodes"); + } + return 0; +} + +/*! + * \brief Iterator on node of volume + */ +class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator +{ + public: + SMDS_VolumeOfNodes_MyIterator(const SMDS_MeshNode* const* s, int l): + SMDS_NodeArrayElemIterator( s, & s[ l ]) {} +}; + +/*! + * \brief Iterator on faces or edges of volume + */ +class _MySubIterator : public SMDS_ElemIterator +{ + vector< const SMDS_MeshElement* > myElems; + size_t myIndex; +public: + _MySubIterator(const SMDS_VolumeOfNodes* vol, SMDSAbs_ElementType type):myIndex(0) { + SMDS_VolumeTool vTool(vol); + if (type == SMDSAbs_Face) + vTool.GetAllExistingFaces( myElems ); + else + vTool.GetAllExistingFaces( myElems ); + } + /// Return true if and only if there are other object in this iterator + virtual bool more() { return myIndex < myElems.size(); } + + /// Return the current object and step to the next one + virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; } +}; + +SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const +{ + switch(type) { - case 4: return 6; - case 5: return 8; - case 6: return 9; - case 8: return 12; - default: MESSAGE("invalid number of nodes"); + case SMDSAbs_Volume: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VolumeOfNodes_MyIterator(myNodes,myNbNodes)); + case SMDSAbs_Face: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face)); + case SMDSAbs_Edge: + return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge)); + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); } - return 0; } - SMDSAbs_ElementType SMDS_VolumeOfNodes::GetType() const { - return SMDSAbs_Volume; + return SMDSAbs_Volume; } /*! @@ -212,20 +269,3 @@ SMDSAbs_GeometryType SMDS_VolumeOfNodes::GetGeomType() const return aType; } -int SMDS_VolumeOfNodes::GetNodeIndex( const SMDS_MeshNode* node ) const -{ - for ( int i = 0; i < myNbNodes; ++i ) - if ( myNodes[i] == node ) - return i; - return -1; -} - -SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::nodesIterator() const -{ - return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); -} - -SMDS_NodeIteratorPtr SMDS_VolumeOfNodes::nodeIterator() const -{ - return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() ); -} diff --git a/src/SMDS/SMDS_VolumeOfNodes.hxx b/src/SMDS/SMDS_VolumeOfNodes.hxx index 15f0058c6..485ea7eda 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.hxx +++ b/src/SMDS/SMDS_VolumeOfNodes.hxx @@ -29,66 +29,63 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_CellOfNodes.hxx" +#include "SMDS_MeshVolume.hxx" -class SMDS_EXPORT SMDS_VolumeOfNodes: public SMDS_CellOfNodes +class SMDS_EXPORT SMDS_VolumeOfNodes:public SMDS_MeshVolume { - public: - SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4); - SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5); - SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6); - SMDS_VolumeOfNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6, - const SMDS_MeshNode * node7, - const SMDS_MeshNode * node8); - bool ChangeNodes(const SMDS_MeshNode* nodes[], - const int nbNodes); - ~SMDS_VolumeOfNodes(); + public: + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8); + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + ~SMDS_VolumeOfNodes(); - void Print(std::ostream & OS) const; - int NbFaces() const; - int NbNodes() const; - int NbEdges() const; - virtual SMDSAbs_ElementType GetType() const; - virtual SMDSAbs_EntityType GetEntityType() const; - virtual SMDSAbs_GeometryType GetGeomType() const; + void Print(std::ostream & OS) const; + int NbFaces() const; + int NbNodes() const; + int NbEdges() const; + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; - virtual bool IsPoly() const { return false; } - virtual bool IsQuadratic() const { return false; } /*! * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node + * \param ind - node index + * \retval const SMDS_MeshNode* - the node */ virtual const SMDS_MeshNode* GetNode(const int ind) const; - virtual int NbCornerNodes() const { return NbNodes(); } - virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - - virtual SMDS_ElemIteratorPtr nodesIterator() const; - virtual SMDS_NodeIteratorPtr nodeIterator() const; - - protected: - - const SMDS_MeshNode** myNodes; - int myNbNodes; + protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + const SMDS_MeshNode** myNodes; + int myNbNodes; }; diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 6de1ac68e..9e144a620 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -32,9 +32,10 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_VtkVolume.hxx" #include "SMDS_Mesh.hxx" -#include +#include "utilities.h" #include #include @@ -42,6 +43,8 @@ #include #include +using namespace std; + namespace { // ====================================================== @@ -503,7 +506,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, myNbFaces = theVolume->NbFaces(); if ( myVolume->IsPoly() ) { - myPolyedre = SMDS_Mesh::DownCast( myVolume ); + myPolyedre = dynamic_cast( myVolume ); myPolyFacetOri.resize( myNbFaces, 0 ); } @@ -519,7 +522,10 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, } else { - myVolumeNodes.assign( myVolume->begin_nodes(), myVolume->end_nodes() ); + int iNode = 0; + SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator(); + while ( nodeIt->more() ) + myVolumeNodes[ iNode++ ] = static_cast( nodeIt->next() ); } // check validity @@ -948,8 +954,8 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const //purpose : Return a set of face nodes. //======================================================================= -bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, - std::set& theFaceNodes ) const +bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, + set& theFaceNodes ) const { if ( !setFace( faceIndex )) return false; @@ -1054,7 +1060,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const { ori = ( -minProj < maxProj ? -1 : +1 ); double convexity = std::min( -minProj, maxProj ) / std::max( -minProj, maxProj ); - convexity2face.insert( std::make_pair( convexity, iF * ori )); + convexity2face.insert( make_pair( convexity, iF * ori )); } } if ( faceMostConvex < 0 ) // none facet has nodes on the same side @@ -1083,7 +1089,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const // compare orientation of links of the facet with myFwdLinks ori = 0; setFace( faceIndex ); - std::vector< NLink > links( myCurFace.myNbNodes ), links2; + vector< NLink > links( myCurFace.myNbNodes ), links2; for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i ) { NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] ); @@ -1204,7 +1210,7 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub } double size = cross.Magnitude(); - if ( size <= std::numeric_limits::min() ) + if ( size <= numeric_limits::min() ) return false; X = cross.x / size; @@ -1376,7 +1382,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, } else { d2 = 0; } - std::vector::const_iterator i; + vector::const_iterator i; for (int iface = 0; iface < myNbFaces; iface++) { from = to; @@ -1423,8 +1429,8 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]); } - int minInd = std::min( theNode1Index, theNode2Index ); - int maxInd = std::max( theNode1Index, theNode2Index ); + int minInd = min( theNode1Index, theNode2Index ); + int maxInd = max( theNode1Index, theNode2Index ); if ( minInd < 0 || maxInd > (int)myVolumeNodes.size() - 1 || maxInd == minInd ) return false; @@ -1559,7 +1565,7 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingFaces(std::vector & faces) const +int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) const { faces.clear(); SaveFacet savedFacet( myCurFace ); @@ -1600,7 +1606,7 @@ int SMDS_VolumeTool::GetAllExistingFaces(std::vector & */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingEdges(std::vector & edges) const +int SMDS_VolumeTool::GetAllExistingEdges(vector & edges) const { edges.clear(); edges.reserve( myVolumeNodes.size() * 2 ); @@ -1711,7 +1717,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV // int nb = myCurFace.myNbNodes; // if ( myVolume->GetEntityType() != vol->GetEntityType() ) // nb -= ( GetCenterNodeIndex(0) > 0 ); - // std::set faceNodes( nodes, nodes + nb ); + // set faceNodes( nodes, nodes + nb ); // if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 ) // continue; // } @@ -1741,7 +1747,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth // evaluate nb of face nodes shared by other volumes int maxNbShared = -1; - typedef std::map< const SMDS_MeshElement*, int > TElemIntMap; + typedef map< const SMDS_MeshElement*, int > TElemIntMap; TElemIntMap volNbShared; TElemIntMap::iterator vNbIt; for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { @@ -1750,7 +1756,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth while ( eIt->more() ) { const SMDS_MeshElement* elem = eIt->next(); if ( elem != myVolume ) { - vNbIt = volNbShared.insert( std::make_pair( elem, 0 )).first; + vNbIt = volNbShared.insert( make_pair( elem, 0 )).first; (*vNbIt).second++; if ( vNbIt->second > maxNbShared ) maxNbShared = vNbIt->second; @@ -1849,7 +1855,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth //purpose : Return index of a face formed by theFaceNodes //======================================================================= -int SMDS_VolumeTool::GetFaceIndex( const std::set& theFaceNodes, +int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes, const int theFaceIndexHint ) const { if ( theFaceIndexHint >= 0 ) @@ -1892,12 +1898,12 @@ int SMDS_VolumeTool::GetFaceIndex( const std::set& theFace //purpose : Return index of a face formed by theFaceNodes //======================================================================= -/*int SMDS_VolumeTool::GetFaceIndex( const std::set& theFaceNodesIndices ) +/*int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodesIndices ) { for ( int iFace = 0; iFace < myNbFaces; iFace++ ) { const int* nodes = GetFaceNodesIndices( iFace ); int nbFaceNodes = NbFaceNodes( iFace ); - std::set nodeSet; + set nodeSet; for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) nodeSet.insert( nodes[ iNode ] ); if ( theFaceNodesIndices == nodeSet ) @@ -1926,7 +1932,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const if (myVolume->IsPoly()) { - if ( !myPolyedre ) { + if (!myPolyedre) { MESSAGE("Warning: bad volumic element"); return false; } diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index d0a1f3121..271ab4af5 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -33,6 +33,7 @@ class SMDS_MeshElement; class SMDS_MeshNode; +class SMDS_VtkVolume; class SMDS_MeshVolume; #include @@ -251,7 +252,7 @@ class SMDS_EXPORT SMDS_VolumeTool bool projectNodesToNormal( int faceIndex, double& minProj, double& maxProj ) const; const SMDS_MeshElement* myVolume; - const SMDS_MeshVolume* myPolyedre; + const SMDS_VtkVolume* myPolyedre; bool myIgnoreCentralNodes; bool myVolForward; diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx index 0f4744925..a0f0d3784 100644 --- a/src/SMDS/SMDS_VtkCellIterator.cxx +++ b/src/SMDS/SMDS_VtkCellIterator.cxx @@ -20,40 +20,59 @@ #include "SMDS_VtkCellIterator.hxx" #include "utilities.h" -#include -#include - -_GetVtkNodes::_GetVtkNodes( vtkIdList* _vtkIdList, - SMDS_Mesh* mesh, - int vtkCellId, - SMDSAbs_EntityType aType ) +SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType) { - vtkUnstructuredGrid* grid = mesh->GetGrid(); + vtkUnstructuredGrid* grid = _mesh->getGrid(); + _vtkIdList = vtkIdList::New(); const std::vector& interlace = SMDS_MeshCell::fromVtkOrder( aType ); if ( interlace.empty() ) { - grid->GetCellPoints( vtkCellId, _vtkIdList ); + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); } else { vtkIdType npts, *pts; - grid->GetCellPoints( vtkCellId, npts, pts ); - _vtkIdList->SetNumberOfIds( npts ); - for (int i = 0; i < npts; i++) + grid->GetCellPoints( _cellId, npts, pts ); + _vtkIdList->SetNumberOfIds( _nbNodes = npts ); + for (int i = 0; i < _nbNodes; i++) _vtkIdList->SetId(i, pts[interlace[i]]); } } -_GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, - SMDS_Mesh* mesh, - int vtkCellId, - SMDSAbs_EntityType aType ) +SMDS_VtkCellIterator::~SMDS_VtkCellIterator() +{ + _vtkIdList->Delete(); +} + +bool SMDS_VtkCellIterator::more() +{ + return (_index < _nbNodes); +} + +const SMDS_MeshElement* SMDS_VtkCellIterator::next() { - vtkIdType * pts, npts; - vtkUnstructuredGrid* grid = mesh->GetGrid(); - grid->GetCellPoints( (vtkIdType)vtkCellId, npts, pts ); + vtkIdType id = _vtkIdList->GetId(_index++); + return _mesh->FindNodeVtk(id); +} + +SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type); + + _vtkIdList = vtkIdList::New(); + vtkIdType* pts; + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts); + _vtkIdList->SetNumberOfIds(_nbNodes); const int *ids = 0; - switch (aType) + switch (_type) { case SMDSEntity_Quad_Edge: { @@ -66,7 +85,7 @@ _GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, { static int id[] = { 0, 3, 1, 4, 2, 5 }; ids = id; - npts = 6; + _nbNodes = 6; break; } case SMDSEntity_Quad_Quadrangle: @@ -74,7 +93,7 @@ _GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, { static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; ids = id; - npts = 8; + _nbNodes = 8; break; } case SMDSEntity_Quad_Tetra: @@ -107,7 +126,7 @@ _GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, { static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 }; ids = id; - npts = 20; + _nbNodes = 20; break; } case SMDSEntity_Polygon: @@ -115,42 +134,62 @@ _GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, case SMDSEntity_Polyhedra: case SMDSEntity_Quad_Polyhedra: default: - const std::vector& i = SMDS_MeshCell::interlacedSmdsOrder( aType, npts ); + const std::vector& i = SMDS_MeshCell::interlacedSmdsOrder(aType, _nbNodes); if ( !i.empty() ) ids = & i[0]; } - _vtkIdList->SetNumberOfIds( npts ); - if ( ids ) - for (int i = 0; i < npts; i++) + for (int i = 0; i < _nbNodes; i++) _vtkIdList->SetId(i, pts[ids[i]]); else - for (int i = 0; i < npts; i++) + for (int i = 0; i < _nbNodes; i++) _vtkIdList->SetId(i, pts[i]); } -_GetVtkNodesPolyh::_GetVtkNodesPolyh( vtkIdList* _vtkIdList, - SMDS_Mesh* mesh, - int vtkCellId, - SMDSAbs_EntityType aType ) +bool SMDS_VtkCellIteratorToUNV::more() { - vtkUnstructuredGrid* grid = mesh->GetGrid(); - switch (aType) + return SMDS_VtkCellIterator::more(); +} + +const SMDS_MeshNode* SMDS_VtkCellIteratorToUNV::next() +{ + return static_cast< const SMDS_MeshNode* >( SMDS_VtkCellIterator::next() ); +} + +SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV() +{ +} + +SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellIteratorPolyH " << _type); + _vtkIdList = vtkIdList::New(); + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); + switch (_type) { case SMDSEntity_Polyhedra: { + //MESSAGE("SMDS_VtkCellIterator Polyhedra"); vtkIdType nFaces = 0; vtkIdType* ptIds = 0; - grid->GetFaceStream( vtkCellId, nFaces, ptIds ); - int id = 0, nbNodesInFaces = 0; + grid->GetFaceStream(_cellId, nFaces, ptIds); + int id = 0; + _nbNodesInFaces = 0; for (int i = 0; i < nFaces; i++) { int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] - nbNodesInFaces += nodesInFace; + _nbNodesInFaces += nodesInFace; id += (nodesInFace + 1); } - _vtkIdList->SetNumberOfIds( nbNodesInFaces ); + _vtkIdList->SetNumberOfIds(_nbNodesInFaces); id = 0; int n = 0; for (int i = 0; i < nFaces; i++) @@ -166,3 +205,12 @@ _GetVtkNodesPolyh::_GetVtkNodesPolyh( vtkIdList* _vtkIdList, assert(0); } } + +SMDS_VtkCellIteratorPolyH::~SMDS_VtkCellIteratorPolyH() +{ +} + +bool SMDS_VtkCellIteratorPolyH::more() +{ + return (_index < _nbNodesInFaces); +} diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx index 92fdc17a2..30ddadee5 100644 --- a/src/SMDS/SMDS_VtkCellIterator.hxx +++ b/src/SMDS/SMDS_VtkCellIterator.hxx @@ -27,68 +27,48 @@ #include #include -//-------------------------------------------------------------------------------- -/*! - * \brief Retrieve nodes of a cell - */ -struct _GetVtkNodes -{ - _GetVtkNodes( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); -}; -struct _GetVtkNodesToUNV -{ - _GetVtkNodesToUNV( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); -}; -struct _GetVtkNodesPolyh -{ - _GetVtkNodesPolyh( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); -}; - -//-------------------------------------------------------------------------------- -/*! - * \brief Iterator on nodes of a cell - */ -template< class SMDS_ITERATOR = SMDS_ElemIterator, class GET_VTK_NODES = _GetVtkNodes > -class SMDS_VtkCellIterator: public SMDS_ITERATOR +class SMDS_VtkCellIterator: public SMDS_ElemIterator { public: - typedef typename SMDS_ITERATOR::value_type result_type; - - SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) - : _mesh(mesh), _index(0), _vtkIdList( vtkIdList::New() ) + SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIterator(); + virtual bool more(); + virtual const SMDS_MeshElement* next(); + inline void exchange(vtkIdType a, vtkIdType b) { - GET_VTK_NODES getNodes( _vtkIdList, mesh, vtkCellId, aType ); - } - virtual ~SMDS_VtkCellIterator() { _vtkIdList->Delete(); } - virtual bool more() { return ( _index < _vtkIdList->GetNumberOfIds() ); } - virtual result_type next() { - vtkIdType id = _vtkIdList->GetId( _index++ ); - return static_cast( _mesh->FindNodeVtk( id )); + vtkIdType t = _vtkIdList->GetId(a); + _vtkIdList->SetId(a, _vtkIdList->GetId(b)); + _vtkIdList->SetId(b, t); } + protected: + SMDS_VtkCellIterator() {}; + SMDS_Mesh* _mesh; - int _index; + int _cellId; + int _index; + int _nbNodes; + SMDSAbs_EntityType _type; vtkIdList* _vtkIdList; }; -//-------------------------------------------------------------------------------- -template< class SMDS_ITERATOR = SMDS_ElemIterator > -class SMDS_VtkCellIteratorToUNV: public SMDS_VtkCellIterator< SMDS_ITERATOR, _GetVtkNodesToUNV > +class SMDS_VtkCellIteratorToUNV: public SMDS_NodeIterator, protected SMDS_VtkCellIterator { - typedef SMDS_VtkCellIterator< SMDS_ITERATOR, _GetVtkNodesToUNV > parent_t; public: - SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type): - parent_t( mesh, vtkCellId, type ) {} + SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual const SMDS_MeshNode* next(); + virtual bool more(); + virtual ~SMDS_VtkCellIteratorToUNV(); }; -//-------------------------------------------------------------------------------- -template< class SMDS_ITERATOR = SMDS_ElemIterator > -class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator< SMDS_ITERATOR, _GetVtkNodesPolyh > +class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator { - typedef SMDS_VtkCellIterator< SMDS_ITERATOR, _GetVtkNodesPolyh > parent_t; public: - SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type): - parent_t( mesh, vtkCellId, type ) {} + SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIteratorPolyH(); + virtual bool more(); +protected: + int _nbNodesInFaces; }; #endif diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx new file mode 100644 index 000000000..edf40f78f --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.cxx @@ -0,0 +1,167 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#include "SMDS_VtkEdge.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include +#include + +using namespace std; + +SMDS_VtkEdge::SMDS_VtkEdge() +{ +} + +SMDS_VtkEdge::SMDS_VtkEdge(std::vector& nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkEdge::~SMDS_VtkEdge() +{ +} + +void SMDS_VtkEdge::init(std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshEdge::init(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = ( nodeIds.size() == 3 ) ? VTK_QUADRATIC_EDGE : VTK_LINE; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) +{ + const SMDS_MeshNode* nodes[] = { node1, node2 }; + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return ChangeNodes(nodes, 2); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + return ((npts == 3) && (node->getVtkId() == pts[2])); +} + +void SMDS_VtkEdge::Print(std::ostream & OS) const +{ + OS << "edge <" << GetID() << "> : "; +} + +int SMDS_VtkEdge::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType *pts, npts; + grid->GetCellPoints( myVtkID, npts, pts ); + assert(npts >= 2); + return npts; +} + +int SMDS_VtkEdge::NbEdges() const +{ + return 1; +} + +SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const +{ + if (NbNodes() == 2) + return SMDSEntity_Edge; + else + return SMDSEntity_Quad_Edge; +} + +vtkIdType SMDS_VtkEdge::GetVtkType() const +{ + if (NbNodes() == 2) + return VTK_LINE; + else + return VTK_QUADRATIC_EDGE; + +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkEdge::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]); +} + +bool SMDS_VtkEdge::IsQuadratic() const +{ + if (this->NbNodes() > 2) + return true; + else + return false; +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_NodeIteratorPtr SMDS_VtkEdge::nodesIteratorToUNV() const +{ + return SMDS_NodeIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_NodeIteratorPtr SMDS_VtkEdge::interlacedNodesIterator() const +{ + return nodesIteratorToUNV(); +} diff --git a/src/SMDS/SMDS_VtkEdge.hxx b/src/SMDS/SMDS_VtkEdge.hxx new file mode 100644 index 000000000..aebfb6e0b --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +// SMESH SMDS : implementation of Salome mesh data structure +// File : SMDS_VtkEdge.hxx +// Module : SMESH + +#ifndef _SMDS_VTKEDGE_HXX_ +#define _SMDS_VTKEDGE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshEdge.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge +{ + +public: + SMDS_VtkEdge(); + SMDS_VtkEdge(std::vector& nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkEdge(); + void init(std::vector& nodeIds, SMDS_Mesh* mesh); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + virtual void Print(std::ostream & OS) const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const; +protected: +}; +#endif diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx new file mode 100644 index 000000000..724a7ec21 --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.cxx @@ -0,0 +1,334 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#include "SMDS_VtkFace.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +using namespace std; + +SMDS_VtkFace::SMDS_VtkFace() +{ +} + +SMDS_VtkFace::SMDS_VtkFace(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkFace::~SMDS_VtkFace() +{ +} + +void SMDS_VtkFace::init(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshFace::init(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TRIANGLE; + switch (nodeIds.size()) + { + case 3: aType = VTK_TRIANGLE; break; + case 4: aType = VTK_QUAD; break; + case 6: aType = VTK_QUADRATIC_TRIANGLE; break; + case 8: aType = VTK_QUADRATIC_QUAD; break; + case 9: aType = VTK_BIQUADRATIC_QUAD; break; + case 7: aType = VTK_BIQUADRATIC_TRIANGLE;break; + default: aType = VTK_POLYGON; + } + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + mesh->setMyModified(); +} + +void SMDS_VtkFace::initPoly(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshFace::init(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_POLYGON; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + mesh->setMyModified(); +} + +void SMDS_VtkFace::initQuadPoly(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshFace::init(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_QUADRATIC_POLYGON; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + mesh->setMyModified(); +} + +bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +void SMDS_VtkFace::Print(std::ostream & OS) const +{ + OS << "face <" << GetID() << "> : "; +} + +int SMDS_VtkFace::NbEdges() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 3; + switch (aVtkType) + { + case VTK_TRIANGLE: + case VTK_QUADRATIC_TRIANGLE: + case VTK_BIQUADRATIC_TRIANGLE: + nbEdges = 3; + break; + case VTK_QUAD: + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + nbEdges = 4; + break; + case VTK_QUADRATIC_POLYGON: + nbEdges = NbNodes() / 2; + break; + case VTK_POLYGON: + default: + nbEdges = NbNodes(); + break; + } + return nbEdges; +} + +int SMDS_VtkFace::NbFaces() const +{ + return 1; +} + +int SMDS_VtkFace::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType *pts, npts; + grid->GetCellPoints( myVtkID, npts, pts ); + return npts; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkFace::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]); +} + +/*! + * \brief Check if a node belongs to the element + * \param node - the node to check + * \retval int - node index within the element, -1 if not found + */ +int SMDS_VtkFace::GetNodeIndex( const SMDS_MeshNode* node ) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + for ( vtkIdType i = 0; i < npts; ++i ) + if ( pts[i] == node->getVtkId() ) + return i; + return -1; +} + +bool SMDS_VtkFace::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polygons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + case VTK_QUADRATIC_QUAD: + case VTK_QUADRATIC_POLYGON: + case VTK_BIQUADRATIC_QUAD: + case VTK_BIQUADRATIC_TRIANGLE: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkFace::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return ( aVtkType == VTK_POLYGON || aVtkType == VTK_QUADRATIC_POLYGON ); +} + +bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + case VTK_BIQUADRATIC_TRIANGLE: + rankFirstMedium = 3; // medium nodes are of rank 3,4,5 + break; + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7 + break; + case VTK_QUADRATIC_POLYGON: + rankFirstMedium = npts / 2; + break; + default: + //MESSAGE("wrong element type " << aVtkType); + return false; + } + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium)); + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +int SMDS_VtkFace::NbCornerNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = NbNodes(); + vtkIdType aVtkType = grid->GetCellType(myVtkID); + switch ( aVtkType ) + { + case VTK_POLYGON: + break; + case VTK_QUADRATIC_POLYGON: + nbPoints /= 2; + break; + default: + if ( nbPoints > 4 ) + nbPoints /= 2; + } + return nbPoints; +} + +SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return SMDS_MeshCell::toSmdsType( VTKCellType( aVtkType )); +} + +SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + switch ( aVtkType ) { + case VTK_TRIANGLE: + case VTK_QUADRATIC_TRIANGLE: + case VTK_BIQUADRATIC_TRIANGLE: return SMDSGeom_TRIANGLE; + + case VTK_QUAD: + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE; + + case VTK_POLYGON: + case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON; + default:; + } + return SMDSGeom_NONE; +} + +vtkIdType SMDS_VtkFace::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return aVtkType; +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_NodeIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const +{ + return SMDS_NodeIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_NodeIteratorPtr SMDS_VtkFace::interlacedNodesIterator() const +{ + return nodesIteratorToUNV(); +} + +//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor +void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + grid->RemoveReferenceToCell(pts[0], myVtkID); + pts[0] = node->getVtkId(); + node->AddInverseElement(this), + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); +} diff --git a/src/SMDS/SMDS_VtkFace.hxx b/src/SMDS/SMDS_VtkFace.hxx new file mode 100644 index 000000000..50c49a0a8 --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#ifndef _SMDS_VTKFACE_HXX_ +#define _SMDS_VTKFACE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshFace.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace +{ +public: + SMDS_VtkFace(); + SMDS_VtkFace(const std::vector& nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkFace(); + void init(const std::vector& nodeIds, SMDS_Mesh* mesh); + void initPoly(const std::vector& nodeIds, SMDS_Mesh* mesh); + void initQuadPoly(const std::vector& nodeIds, SMDS_Mesh* mesh); + + bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles + + virtual void Print(std::ostream & OS) const; + virtual int NbEdges() const; + virtual int NbFaces() const; + virtual int NbNodes() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; + + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + virtual int NbCornerNodes() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const; +protected: +}; + +#endif diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx new file mode 100644 index 000000000..ecbcd928d --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -0,0 +1,698 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#include "SMDS_VtkVolume.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +SMDS_VtkVolume::SMDS_VtkVolume() +{ +} + +SMDS_VtkVolume::SMDS_VtkVolume(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} +/*! + * typed used are vtk types (@see vtkCellType.h) + * see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx) + */ +void SMDS_VtkVolume::init(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshVolume::init(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TETRA; + switch (nodeIds.size()) // cases are in order of usage frequency + { + case 4: aType = VTK_TETRA; break; + case 8: aType = VTK_HEXAHEDRON; break; + case 5: aType = VTK_PYRAMID; break; + case 6: aType = VTK_WEDGE; break; + case 10: aType = VTK_QUADRATIC_TETRA; break; + case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; + case 13: aType = VTK_QUADRATIC_PYRAMID; break; + case 15: aType = VTK_QUADRATIC_WEDGE; break; + case 18: aType = VTK_BIQUADRATIC_QUADRATIC_WEDGE; break; + case 12: aType = VTK_HEXAGONAL_PRISM; break; + case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON; break; + default: aType = VTK_HEXAHEDRON; + } + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]); + mesh->setMyModified(); +} + +void SMDS_VtkVolume::initPoly(const std::vector& nodeIds, + const std::vector& nbNodesPerFace, + SMDS_Mesh* mesh) +{ + SMDS_MeshVolume::init(); + SMDS_UnstructuredGrid* grid = mesh->getGrid(); + //double center[3]; + //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]); + std::vector ptIds; + vtkIdType nbFaces = nbNodesPerFace.size(); + int k = 0; + for (int i = 0; i < nbFaces; i++) + { + int nf = nbNodesPerFace[i]; + ptIds.push_back(nf); + // EAP: a right approach is: + // - either the user should care of order of nodes or + // - the user should use a service method arranging nodes if he + // don't want or can't to do it by him-self + // The method below works OK only with planar faces and convex polyhedrones + // + // double a[3]; + // double b[3]; + // double c[3]; + // grid->GetPoints()->GetPoint(nodeIds[k], a); + // grid->GetPoints()->GetPoint(nodeIds[k + 1], b); + // grid->GetPoints()->GetPoint(nodeIds[k + 2], c); + // bool isFaceForward = this->isForward(a, b, c, center); + const vtkIdType *facePts = &nodeIds[k]; + //if (isFaceForward) + for (int n = 0; n < nf; n++) + ptIds.push_back(facePts[n]); + // else + // for (int n = nf - 1; n >= 0; n--) + // ptIds.push_back(facePts[n]); + k += nf; + } + myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]); + mesh->setMyModified(); +} + +bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +/*! + * Reorder in VTK order a list of nodes given in SMDS order. + * To be used before ChangeNodes: lists are given or computed in SMDS order. + */ +bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + if (nbNodes != this->NbNodes()) + { + MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes()); + return false; + } + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType )); + if ( !interlace.empty() ) + { + ASSERT( (int)interlace.size() == nbNodes ); + std::vector initNodes( nodes, nodes+nbNodes ); + for ( size_t i = 0; i < interlace.size(); ++i ) + nodes[i] = initNodes[ interlace[i] ]; + } + return true; +} + +SMDS_VtkVolume::~SMDS_VtkVolume() +{ +} + +void SMDS_VtkVolume::Print(ostream & OS) const +{ + OS << "volume <" << GetID() << "> : "; +} + +int SMDS_VtkVolume::NbFaces() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbFaces = 4; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbFaces = 4; + break; + case VTK_PYRAMID: + case VTK_WEDGE: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + nbFaces = 5; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + nbFaces = 6; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbFaces = nFaces; + break; + } + case VTK_HEXAGONAL_PRISM: + nbFaces = 8; + break; + default: + MESSAGE("invalid volume type") + ; + nbFaces = 0; + break; + } + return nbFaces; +} + +int SMDS_VtkVolume::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + vtkIdType nbPoints = 0; + if (aVtkType != VTK_POLYHEDRON) + { + vtkIdType *pts; + grid->GetCellPoints( myVtkID, nbPoints, pts ); + } + else + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + nbPoints += nodesInFace; + id += (nodesInFace + 1); + } + } + return nbPoints; +} + +int SMDS_VtkVolume::NbEdges() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 6; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbEdges = 6; + break; + case VTK_PYRAMID: + case VTK_QUADRATIC_PYRAMID: + nbEdges = 8; + break; + case VTK_WEDGE: + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + nbEdges = 9; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + nbEdges = 12; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbEdges = 0; + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int edgesInFace = ptIds[id]; + id += (edgesInFace + 1); + nbEdges += edgesInFace; + } + nbEdges = nbEdges / 2; + break; + } + case VTK_HEXAGONAL_PRISM: + nbEdges = 18; + break; + default: + MESSAGE("invalid volume type") + ; + nbEdges = 0; + break; + } + return nbEdges; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + */ +int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbNodes = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + id += (nodesInFace + 1); + if (i == face_ind - 1) + { + nbNodes = nodesInFace; + break; + } + } + } + return nbNodes; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + * 1 <= node_ind <= NbFaceNodes() + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const +{ + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + const SMDS_MeshNode* node = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + if (i == face_ind - 1) // first face is number 1 + { + if ((node_ind > 0) && (node_ind <= nodesInFace)) + node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node + break; + } + id += (nodesInFace + 1); + } + } + return node; +} + +/*! polyhedron only, + * return number of nodes for each face + */ +std::vector SMDS_VtkVolume::GetQuantities() const +{ + std::vector quantities; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + quantities.push_back(nodesInFace); + id += (nodesInFace + 1); + } + } + return quantities; +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + { + SMDSAbs_EntityType aType = this->GetEntityType(); + if (aType == SMDSEntity_Polyhedra) + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + else + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + } + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_NodeIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const +{ + return SMDS_NodeIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_NodeIteratorPtr SMDS_VtkVolume::interlacedNodesIterator() const +{ + return SMDS_NodeIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDSAbs_ElementType SMDS_VtkVolume::GetType() const +{ + return SMDSAbs_Volume; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + if ( aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0, nbPoints = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + if ( ind < nbPoints + nodesInFace ) + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( ptIds[ ind + i ]); + nbPoints += nodesInFace; + id += (nodesInFace + 1); + } + return 0; + } + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + const std::vector& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType )); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] ); +} +/*! + * \brief Check if a node belongs to the element + * \param node - the node to check + * \retval int - node index within the element, -1 if not found + */ +int SMDS_VtkVolume::GetNodeIndex( const SMDS_MeshNode* node ) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + const vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + if ( aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int iF = 0; iF < nFaces; iF++) + { + int nodesInFace = ptIds[id]; + for ( vtkIdType i = 0; i < nodesInFace; ++i ) + if ( ptIds[id+i+1] == node->getVtkId() ) + return id+i-iF; + id += (nodesInFace + 1); + } + return -1; + } + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + for ( vtkIdType i = 0; i < npts; ++i ) + if ( pts[i] == node->getVtkId() ) + { + const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType )); + return interlace.empty() ? i : interlace[i]; + } + return -1; +} + +bool SMDS_VtkVolume::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polyhedrons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkVolume::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return (aVtkType == VTK_POLYHEDRON); +} + +bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + rankFirstMedium = 4; // medium nodes are of rank 4 to 9 + break; + case VTK_QUADRATIC_PYRAMID: + rankFirstMedium = 5; // medium nodes are of rank 5 to 12 + break; + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + rankFirstMedium = 6; // medium nodes are of rank 6 to 14 + break; + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + rankFirstMedium = 8; // medium nodes are of rank 8 to 19 + break; + default: + return false; + } + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +int SMDS_VtkVolume::NbCornerNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(myVtkID); + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: return 4; + case VTK_QUADRATIC_PYRAMID: return 5; + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: return 6; + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: return 8; + default:; + } + return NbNodes(); +} + +SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + + SMDSAbs_EntityType aType = SMDSEntity_Tetra; + switch (aVtkType) + { + case VTK_TETRA: + aType = SMDSEntity_Tetra; + break; + case VTK_PYRAMID: + aType = SMDSEntity_Pyramid; + break; + case VTK_WEDGE: + aType = SMDSEntity_Penta; + break; + case VTK_HEXAHEDRON: + aType = SMDSEntity_Hexa; + break; + case VTK_QUADRATIC_TETRA: + aType = SMDSEntity_Quad_Tetra; + break; + case VTK_QUADRATIC_PYRAMID: + aType = SMDSEntity_Quad_Pyramid; + break; + case VTK_QUADRATIC_WEDGE: + aType = SMDSEntity_Quad_Penta; + break; + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + aType = SMDSEntity_BiQuad_Penta; + break; + case VTK_QUADRATIC_HEXAHEDRON: + aType = SMDSEntity_Quad_Hexa; + break; + case VTK_TRIQUADRATIC_HEXAHEDRON: + aType = SMDSEntity_TriQuad_Hexa; + break; + case VTK_HEXAGONAL_PRISM: + aType = SMDSEntity_Hexagonal_Prism; + break; + case VTK_POLYHEDRON: + aType = SMDSEntity_Polyhedra; + break; + default: + aType = SMDSEntity_Polyhedra; + break; + } + return aType; +} + +SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + + SMDSAbs_GeometryType aType = SMDSGeom_NONE; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + aType = SMDSGeom_TETRA; + break; + case VTK_PYRAMID: + case VTK_QUADRATIC_PYRAMID: + aType = SMDSGeom_PYRAMID; + break; + case VTK_WEDGE: + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + aType = SMDSGeom_PENTA; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + aType = SMDSGeom_HEXA; + break; + case VTK_HEXAGONAL_PRISM: + aType = SMDSGeom_HEXAGONAL_PRISM; + break; + case VTK_POLYHEDRON: + aType = SMDSGeom_POLYHEDRA; + break; + default: + aType = SMDSGeom_POLYHEDRA; + break; + } + return aType; +} + +vtkIdType SMDS_VtkVolume::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aType = grid->GetCellType(myVtkID); + return aType; +} + +void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, + const vtkIdType * nodeIds, + int nbNodes, + double* result) +{ + for (int j = 0; j < 3; j++) + result[j] = 0; + if (nbNodes <= 0) + return; + for (int i = 0; i < nbNodes; i++) + { + double *coords = grid->GetPoint(nodeIds[i]); + for (int j = 0; j < 3; j++) + result[j] += coords[j]; + } + for (int j = 0; j < 3; j++) + result[j] = result[j] / nbNodes; + return; +} + +bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d) +{ + double u[3], v[3], w[3]; + for (int j = 0; j < 3; j++) + { + u[j] = b[j] - a[j]; + v[j] = c[j] - a[j]; + w[j] = d[j] - a[j]; + } + double prodmixte = ((u[1]*v[2] - u[2]*v[1]) * w[0] + + (u[2]*v[0] - u[0]*v[2]) * w[1] + + (u[0]*v[1] - u[1]*v[0]) * w[2] ); + return (prodmixte < 0); +} + +/*! For polyhedron only + * @return actual number of nodes (not the sum of nodes of all faces) + */ +int SMDS_VtkVolume::NbUniqueNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + return grid->GetCell(myVtkID)->GetNumberOfPoints(); +} + +/*! For polyhedron use only + * @return iterator on actual nodes (not through the faces) + */ +SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx new file mode 100644 index 000000000..02f86ce2a --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2010-2016 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, or (at your option) any later version. +// +// 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 +// + +#ifndef _SMDS_VTKVOLUME_HXX_ +#define _SMDS_VTKVOLUME_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshVolume.hxx" +#include "SMDS_UnstructuredGrid.hxx" +#include + +class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume +{ +public: + SMDS_VtkVolume(); + SMDS_VtkVolume(const std::vector& nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkVolume(); + void init(const std::vector& nodeIds, SMDS_Mesh* mesh); +//#ifdef VTK_HAVE_POLYHEDRON + void initPoly(const std::vector& nodeIds, + const std::vector& nbNodesPerFace, SMDS_Mesh* mesh); +//#endif + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes); + + virtual void Print(std::ostream & OS) const; + virtual int NbFaces() const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + // 1 <= face_ind <= NbFaces() + int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() + // 1 <= node_ind <= NbFaceNodes() + const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + virtual int NbCornerNodes() const; + static void gravityCenter(SMDS_UnstructuredGrid* grid, + const vtkIdType *nodeIds, + int nbNodes, + double* result); + static bool isForward(double* a,double* b,double* c,double* d); + int NbUniqueNodes() const; + SMDS_ElemIteratorPtr uniqueNodesIterator() const; + std::vector GetQuantities() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_NodeIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_NodeIteratorPtr interlacedNodesIterator() const; + +protected: +}; + +#endif diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index d0ee85cb8..561f64471 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -358,9 +358,12 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes(); while ( nIt->more() ) { - SMDS_EdgePositionPtr epos = nIt->next()->GetPosition(); - if ( !epos ) + const SMDS_MeshNode* node = nIt->next(); + const SMDS_PositionPtr& pos = node->GetPosition(); + if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition()); if ( !paramSet.insert( epos->GetUParameter() ).second ) return false; // equal parameters } @@ -421,9 +424,11 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM const SMDS_MeshNode* node = nIt->next(); if ( ignoreMediumNodes && SMESH_MesherHelper::IsMedium( node, typeToCheck )) continue; - SMDS_EdgePositionPtr epos = node->GetPosition(); - if ( ! epos ) + const SMDS_PositionPtr& pos = node->GetPosition(); + if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition()); theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node )); ++nbNodes; } @@ -909,12 +914,7 @@ bool SMESH_Algo::error(SMESH_ComputeErrorPtr error) if ( error ) { _error = error->myName; _comment = error->myComment; - if ( error->HasBadElems() ) - { - SMESH_BadInputElements* badElems = static_cast( error.get() ); - _badInputElements = badElems->GetElements(); - _mesh = badElems->GetMesh(); - } + _badInputElements = error->myBadElements; return error->IsOK(); } return true; @@ -928,15 +928,11 @@ bool SMESH_Algo::error(SMESH_ComputeErrorPtr error) SMESH_ComputeErrorPtr SMESH_Algo::GetComputeError() const { - if ( !_badInputElements.empty() && _mesh ) - { - SMESH_BadInputElements* err = new SMESH_BadInputElements( _mesh, _error, _comment, this ); - // hope this method is called by only SMESH_subMesh after this->Compute() - err->myBadElements.splice( err->myBadElements.end(), - (list&) _badInputElements ); - return SMESH_ComputeErrorPtr( err ); - } - return SMESH_ComputeError::New( _error, _comment, this ); + SMESH_ComputeErrorPtr err = SMESH_ComputeError::New( _error, _comment, this ); + // hope this method is called by only SMESH_subMesh after this->Compute() + err->myBadElements.splice( err->myBadElements.end(), + (list&) _badInputElements ); + return err; } //================================================================================ @@ -954,7 +950,6 @@ void SMESH_Algo::InitComputeError() if ( (*elem)->GetID() < 1 ) delete *elem; _badInputElements.clear(); - _mesh = 0; _computeCanceled = false; _progressTic = 0; @@ -1248,7 +1243,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); const SMDS_MeshNode* n = nodeRows[iRow][iCol]; meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); - if ( SMDS_FacePositionPtr pos = n->GetPosition() ) + if ( SMDS_FacePosition* pos = dynamic_cast< SMDS_FacePosition*>( n->GetPosition() )) pos->SetParameters( uv.Coord(1), uv.Coord(2) ); } } diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index cceb370ef..81ff8eb3a 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -462,7 +462,6 @@ protected: int _error; //!< SMESH_ComputeErrorName or anything algo specific std::string _comment; //!< any text explaining what is wrong in Compute() std::list _badInputElements; //!< to explain COMPERR_BAD_INPUT_MESH - const SMDS_Mesh* _mesh; //!< mesh being computed, needed to create SMESH_BadInputElements volatile bool _computeCanceled; //!< is set to True while computing to stop it diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index f87162e45..c62e70e32 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -54,6 +54,9 @@ using namespace std; +//#include + + //============================================================================= /*! * Constructor @@ -65,7 +68,9 @@ SMESH_Gen::SMESH_Gen() _localId = 0; _hypId = 0; _segmentation = _nbSegments = 10; + SMDS_Mesh::_meshList.clear(); _compute_canceled = false; + //vtkDebugLeaks::SetExitError(0); } namespace @@ -402,10 +407,8 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } if ( aCompactMesh ) - { - aMesh.GetMeshDS()->Modified(); - aMesh.GetMeshDS()->CompactMesh(); - } + aMesh.GetMeshDS()->compactMesh(); + return ret; } diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 1dcdd5359..3e21e9a11 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -450,7 +450,7 @@ void SMESH_Mesh::Clear() void SMESH_Mesh::ClearSubMesh(const int theShapeId) { - // clear sub-meshes; get ready to re-compute as a side-effect + // 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, @@ -458,7 +458,7 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) while ( smIt->more() ) { sm = smIt->next(); - TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); + 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 ); @@ -470,7 +470,7 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) //======================================================================= //function : UNVToMesh -//purpose : +//purpose : //======================================================================= int SMESH_Mesh::UNVToMesh(const char* theFileName) @@ -485,19 +485,32 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) myReader.SetMeshId(-1); myReader.Perform(); - TGroupNamesMap& aGroupNames = myReader.GetGroupNamesMap(); - TGroupNamesMap::iterator gr2names; - int anId = 1 + ( _mapGroup.empty() ? 0 : _mapGroup.rbegin()->first ); - for ( gr2names = aGroupNames.begin(); gr2names != aGroupNames.end(); ++gr2names ) + if ( SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup() ) { - SMDS_MeshGroup* aGroup = gr2names->first; - const std::string& aName = gr2names->second; - SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _myMeshDS, aGroup->GetType() ); - aGroupDS->SMDSGroup() = std::move( *aGroup ); - aGroupDS->SetStoreName( aName.c_str() ); - AddGroup( aGroupDS ); + TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap(); + aGroup->InitSubGroupsIterator(); + while (aGroup->MoreSubGroups()) + { + SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup(); + string aName = aGroupNames[aSubGroup]; + int aId; + if ( SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId )) + { + SMESHDS_Group* aGroupDS = dynamic_cast( aSMESHGroup->GetGroupDS() ); + if ( aGroupDS ) { + aGroupDS->SetStoreName(aName.c_str()); + aSubGroup->InitIterator(); + const SMDS_MeshElement* aElement = 0; + while ( aSubGroup->More() ) + if (( aElement = aSubGroup->Next() )) + aGroupDS->SMDSGroup().Add( aElement ); + + if (aElement) + aGroupDS->SetType( aElement->GetType() ); + } + } + } } - return 1; } @@ -538,16 +551,12 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) } } } - - _myMeshDS->Modified(); - _myMeshDS->CompactMesh(); - return (int) status; } //======================================================================= //function : STLToMesh -//purpose : +//purpose : //======================================================================= std::string SMESH_Mesh::STLToMesh(const char* theFileName) diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index e9dbc5a32..9b581c9ce 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -162,7 +162,7 @@ SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOn myIsQuad = elem->IsQuadratic(); if ( myType == SMDSAbs_Volume && !basicOnly ) { - vector quant = static_cast( elem )->GetQuantities(); + vector quant = static_cast( elem )->GetQuantities(); myPolyhedQuantities.swap( quant ); } } @@ -682,16 +682,16 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, { ClearLastCreated(); - if ( !theTria1 || !theTria2 || - !dynamic_cast( theTria1 ) || - !dynamic_cast( theTria2 ) || - theTria1->GetType() != SMDSAbs_Face || - theTria2->GetType() != SMDSAbs_Face ) + if (!theTria1 || !theTria2) return false; + const SMDS_VtkFace* F1 = dynamic_cast( theTria1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( theTria2 ); + if (!F2) return false; if ((theTria1->GetEntityType() == SMDSEntity_Triangle) && - (theTria2->GetEntityType() == SMDSEntity_Triangle)) - { + (theTria2->GetEntityType() == SMDSEntity_Triangle)) { + // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | // |/ | | \| @@ -805,9 +805,9 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, gp_Pnt xyz; if ( F.IsNull() ) { - xyz = ( SMESH_NodeXYZ( nodes[3] ) + - SMESH_NodeXYZ( nodes[4] ) + - SMESH_NodeXYZ( nodes[5] )) / 3.; + xyz = ( SMESH_TNodeXYZ( nodes[3] ) + + SMESH_TNodeXYZ( nodes[4] ) + + SMESH_TNodeXYZ( nodes[5] )) / 3.; } else { @@ -886,10 +886,10 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - if ( !dynamic_cast( tr1 ) || - !dynamic_cast( tr2 )) - return false; - + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; if ((tr1->GetEntityType() == SMDSEntity_Triangle) && (tr2->GetEntityType() == SMDSEntity_Triangle)) { @@ -1006,15 +1006,15 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - if ( !dynamic_cast( tr1 ) || - !dynamic_cast( tr2 )) - return false; - + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; SMESHDS_Mesh * aMesh = GetMeshDS(); if ((tr1->GetEntityType() == SMDSEntity_Triangle) && - (tr2->GetEntityType() == SMDSEntity_Triangle)) - { + (tr2->GetEntityType() == SMDSEntity_Triangle)) { + const SMDS_MeshNode* aNodes [ 4 ]; if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) return false; @@ -1025,8 +1025,9 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, AddToSameGroups( newElem, tr1, aMesh ); int aShapeId = tr1->getshapeId(); if ( aShapeId ) + { aMesh->SetMeshElementOnShape( newElem, aShapeId ); - + } aMesh->RemoveElement( tr1 ); aMesh->RemoveElement( tr2 ); @@ -1108,7 +1109,8 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) const SMDSAbs_EntityType geomType = theElem->GetEntityType(); if ( geomType == SMDSEntity_Polyhedra ) // polyhedron { - const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( theElem ); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( theElem ); if (!aPolyedre) { MESSAGE("Warning: bad volumic element"); return false; @@ -1166,7 +1168,7 @@ int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, if ( theFaces.empty() ) { - SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=true*/); + SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=*/true); while ( fIt->more() ) theFaces.insert( theFaces.end(), fIt->next() ); } @@ -1554,7 +1556,7 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems) if ( F.IsNull() ) { for ( ; iN < nodes.size(); ++iN ) - xyz[ iN ] = SMESH_NodeXYZ( nodes[ iN ] ); + xyz[ iN ] = SMESH_TNodeXYZ( nodes[ iN ] ); for ( ; iN < 8; ++iN ) // mid-side points of a linear qudrangle xyz[ iN ] = 0.5 * ( xyz[ iN - 4 ] + xyz[( iN - 3 )%4 ] ); @@ -2359,7 +2361,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, if ( fSubMesh ) // update position of the bary node on geometry { if ( subMesh ) - subMesh->RemoveNode( baryNode ); + subMesh->RemoveNode( baryNode, false ); GetMeshDS()->SetNodeOnFace( baryNode, fSubMesh->GetID() ); const TopoDS_Shape& s = GetMeshDS()->IndexToShape( fSubMesh->GetID() ); if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE ) @@ -3828,7 +3830,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, // } if ( project ) { // compute new UV gp_XY newUV; - gp_Pnt pNode = SMESH_NodeXYZ( node ); + gp_Pnt pNode = SMESH_TNodeXYZ( node ); if ( !getClosestUV( projector, pNode, newUV )) { MESSAGE("Node Projection Failed " << node); } @@ -4083,7 +4085,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, const SMDS_MeshElement* QF = *elemIt; if ( QF->IsQuadratic() ) { - nodes.assign( SMDS_MeshElement::iterator( QF->interlacedNodesIterator() ), + nodes.assign( SMDS_MeshElement::iterator( QF->interlacedNodesElemIterator() ), SMDS_MeshElement::iterator() ); nodes.push_back( nodes[0] ); gp_Pnt xyz; @@ -4097,9 +4099,9 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, xyz = surface->Value( uv.X(), uv.Y() ); } else { - xyz = 0.5 * ( SMESH_NodeXYZ( nodes[i-1] ) + SMESH_NodeXYZ( nodes[i+1] )); + xyz = 0.5 * ( SMESH_TNodeXYZ( nodes[i-1] ) + SMESH_TNodeXYZ( nodes[i+1] )); } - if (( SMESH_NodeXYZ( nodes[i] ) - xyz.XYZ() ).Modulus() > disttol ) + if (( SMESH_TNodeXYZ( nodes[i] ) - xyz.XYZ() ).Modulus() > disttol ) // we have to move a medium node aMesh->MoveNode( nodes[i], xyz.X(), xyz.Y(), xyz.Z() ); } @@ -4127,8 +4129,8 @@ namespace const int iNotSame) { - SMESH_NodeXYZ pP = prevNodes[ iNotSame ]; - SMESH_NodeXYZ pN = nextNodes[ iNotSame ]; + SMESH_TNodeXYZ pP = prevNodes[ iNotSame ]; + SMESH_TNodeXYZ pN = nextNodes[ iNotSame ]; gp_XYZ extrDir( pN - pP ), faceNorm; SMESH_MeshAlgos::FaceNormal( face, faceNorm, /*normalized=*/false ); @@ -4832,9 +4834,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, SMDS_VolumeTool vTool( *v, /*ignoreCentralNodes=*/false ); int iF, nbF = vTool.NbFaces(); for ( iF = 0; iF < nbF; iF ++ ) { - if ( vTool.IsFreeFace( iF ) && - vTool.GetFaceNodes( iF, faceNodeSet ) && - initNodeSet != faceNodeSet) // except an initial face + if (vTool.IsFreeFace( iF ) && + vTool.GetFaceNodes( iF, faceNodeSet ) && + initNodeSet != faceNodeSet) // except an initial face { if ( nbSteps == 1 && faceNodeSet == topNodeSet ) continue; @@ -5323,7 +5325,7 @@ void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& el while ( itN->more() ) { const SMDS_MeshElement* node = itN->next(); if ( newNodes.insert( node ).second ) - myBaseP += SMESH_NodeXYZ( node ); + myBaseP += SMESH_TNodeXYZ( node ); } } } @@ -5389,7 +5391,7 @@ makeNodesByDir( SMESHDS_Mesh* mesh, std::list & newNodes, const bool makeMediumNodes) { - gp_XYZ p = SMESH_NodeXYZ( srcNode ); + gp_XYZ p = SMESH_TNodeXYZ( srcNode ); int nbNodes = 0; for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps @@ -5426,7 +5428,7 @@ makeNodesByDir( SMESHDS_Mesh* mesh, iSc += int( makeMediumNodes ); ScaleIt& scale = scales[ iSc % 2 ]; - gp_XYZ xyz = SMESH_NodeXYZ( *nIt ); + gp_XYZ xyz = SMESH_TNodeXYZ( *nIt ); xyz = ( *scale * ( xyz - center )) + center; mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() ); @@ -5447,7 +5449,7 @@ makeNodesByDirAndSew( SMESHDS_Mesh* mesh, std::list & newNodes, const bool makeMediumNodes) { - gp_XYZ P1 = SMESH_NodeXYZ( srcNode ); + gp_XYZ P1 = SMESH_TNodeXYZ( srcNode ); int nbNodes = 0; for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps @@ -5458,11 +5460,10 @@ makeNodesByDirAndSew( SMESHDS_Mesh* mesh, // if myNodes.size()>0 we 'nave to use given sequence // else - use all nodes of mesh const SMDS_MeshNode * node = 0; - if ( myNodes.Length() > 0 ) - { - for ( int i = 1; i <= myNodes.Length(); i++ ) - { - SMESH_NodeXYZ P2 = myNodes.Value(i); + if ( myNodes.Length() > 0 ) { + int i; + for ( i = 1; i <= myNodes.Length(); i++ ) { + gp_XYZ P2 = SMESH_TNodeXYZ( myNodes.Value(i) ); if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance ) { node = myNodes.Value(i); @@ -5470,12 +5471,10 @@ makeNodesByDirAndSew( SMESHDS_Mesh* mesh, } } } - else - { + else { SMDS_NodeIteratorPtr itn = mesh->nodesIterator(); - while(itn->more()) - { - SMESH_NodeXYZ P2 = itn->next(); + while(itn->more()) { + SMESH_TNodeXYZ P2( itn->next() ); if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance ) { node = P2._node; @@ -5507,7 +5506,7 @@ makeNodesByNormal2D( SMESHDS_Mesh* mesh, { const bool alongAvgNorm = ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL ); - gp_XYZ p = SMESH_NodeXYZ( srcNode ); + gp_XYZ p = SMESH_TNodeXYZ( srcNode ); // get normals to faces sharing srcNode vector< gp_XYZ > norms, baryCenters; @@ -5527,7 +5526,7 @@ makeNodesByNormal2D( SMESHDS_Mesh* mesh, gp_XYZ bc(0,0,0); int nbN = 0; for ( SMDS_ElemIteratorPtr nIt = face->nodesIterator(); nIt->more(); ++nbN ) - bc += SMESH_NodeXYZ( nIt->next() ); + bc += SMESH_TNodeXYZ( nIt->next() ); baryCenters.push_back( bc / nbN ); } } @@ -5795,8 +5794,9 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], return EXTR_BAD_STARTING_NODE; aItN = pSubMeshDS->GetNodes(); while ( aItN->more() ) { - const SMDS_MeshNode* pNode = aItN->next(); - SMDS_EdgePositionPtr pEPos = pNode->GetPosition(); + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -5839,7 +5839,8 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], aItN = locMeshDS->GetNodes(); while ( aItN->more() ) { const SMDS_MeshNode* pNode = aItN->next(); - SMDS_EdgePositionPtr pEPos = pNode->GetPosition(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -5961,7 +5962,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], SMDS_ElemIteratorPtr nIt; //check start node - if( !theTrack->GetMeshDS()->Contains( theN1 )) { + if( !theTrack->GetMeshDS()->Contains(theN1) ) { return EXTR_BAD_STARTING_NODE; } @@ -6021,8 +6022,8 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], int startNid = theN1->GetID(); for ( size_t i = 1; i < aNodesList.size(); i++ ) { - gp_Pnt p1 = SMESH_NodeXYZ( aNodesList[i-1] ); - gp_Pnt p2 = SMESH_NodeXYZ( aNodesList[i] ); + gp_Pnt p1 = SMESH_TNodeXYZ( aNodesList[i-1] ); + gp_Pnt p2 = SMESH_TNodeXYZ( aNodesList[i] ); TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 ); list LPP; aPrms.clear(); @@ -6078,7 +6079,8 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], while ( aItN->more() ) { const SMDS_MeshNode* pNode = aItN->next(); if( pNode==aN1 || pNode==aN2 ) continue; - SMDS_EdgePositionPtr pEPos = pNode->GetPosition(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -6134,8 +6136,9 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], aPrms.clear(); aItN = locMeshDS->GetNodes(); while ( aItN->more() ) { - const SMDS_MeshNode* pNode = aItN->next(); - SMDS_EdgePositionPtr pEPos = pNode->GetPosition(); + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -6293,7 +6296,7 @@ SMESH_MeshEditor::makeExtrElements(TIDSortedElemSet theElemSets while ( itN->more() ) { const SMDS_MeshElement* node = itN->next(); if ( newNodes.insert( node ).second ) - aGC += SMESH_NodeXYZ( node ); + aGC += SMESH_TNodeXYZ( node ); } } } @@ -6337,7 +6340,7 @@ SMESH_MeshEditor::makeExtrElements(TIDSortedElemSet theElemSets aTolAng=1.e-4; aV0x = aV0; - aPN0 = SMESH_NodeXYZ( node ); + aPN0 = SMESH_TNodeXYZ( node ); const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; aP0x = aPP0.Pnt(); @@ -6657,8 +6660,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, if ( geomType == SMDSGeom_POLYHEDRA ) // ------------------ polyhedral volume { - const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem ); - if ( !aPolyedre ) + const SMDS_VtkVolume* aPolyedre = dynamic_cast( elem ); + if (!aPolyedre) continue; nodes.clear(); bool allTransformed = true; @@ -7032,7 +7035,7 @@ void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet & theNodes, if ( theNodes.empty() ) // get all nodes in the mesh { TIDSortedNodeSet* nodes[2] = { &corners, &medium }; - SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(); + SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true); if ( theSeparateCornersAndMedium ) while ( nIt->more() ) { @@ -7220,7 +7223,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes, AddToSameGroups( nToKeep, nToRemove, mesh ); // set _alwaysComputed to a sub-mesh of VERTEX to enable further mesh computing // w/o creating node in place of merged ones. - SMDS_PositionPtr pos = nToRemove->GetPosition(); + const SMDS_PositionPtr& pos = nToRemove->GetPosition(); if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) sm->SetIsAlwaysComputed( true ); @@ -7408,7 +7411,7 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem, if ( nbUniqueNodes >= 4 ) { // each face has to be analyzed in order to check volume validity - if ( const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem )) + if ( const SMDS_VtkVolume* aPolyedre = dynamic_cast( elem )) { int nbFaces = aPolyedre->NbFaces(); @@ -7953,11 +7956,24 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst if ( e == curElem || foundElems.insert( e ).second ) { // get nodes int iNode = 0, nbNodes = e->NbNodes(); - vector nodes( nbNodes+1 ); - nodes.assign( SMDS_MeshElement::iterator( e->interlacedNodesIterator() ), - SMDS_MeshElement::iterator() ); - nodes.push_back( nodes[ 0 ]); - + vector nodes(nbNodes+1); + + if ( e->IsQuadratic() ) { + const SMDS_VtkFace* F = + dynamic_cast(e); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + // use special nodes iterator + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); + while( anIter->more() ) { + nodes[ iNode++ ] = cast2Node(anIter->next()); + } + } + else { + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + nodes[ iNode++ ] = static_cast( nIt->next() ); + } + nodes[ iNode ] = nodes[ 0 ]; // check 2 links for ( iNode = 0; iNode < nbNodes; iNode++ ) if (((nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) || @@ -8214,13 +8230,27 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : & faceNodes[0]; if ( isVolume ) // --volume hasVolumes = true; - else if ( elem->GetType() == SMDSAbs_Face ) { // --face + else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode - SMDS_NodeIteratorPtr nIt = elem->interlacedNodesIterator(); - while ( nIt->more() ) { - nodes[ iNode ] = cast2Node( nIt->next() ); - if ( nodes[ iNode++ ] == prevSideNode ) - iPrevNode = iNode - 1; + if(elem->IsQuadratic()) { + const SMDS_VtkFace* F = + dynamic_cast(elem); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + // use special nodes iterator + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); + while( anIter->more() ) { + nodes[ iNode ] = cast2Node(anIter->next()); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } + } + else { + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + while ( nIt->more() ) { + nodes[ iNode ] = cast2Node( nIt->next() ); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } } // there are 2 links to check nbNodes = 2; @@ -8680,21 +8710,48 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theElemen // add nodes of face up to first node of link bool isFLN = false; - SMDS_NodeIteratorPtr nodeIt = theFace->interlacedNodesIterator(); - while ( nodeIt->more() && !isFLN ) { - const SMDS_MeshNode* n = nodeIt->next(); - poly_nodes[iNode++] = n; - isFLN = ( n == nodes[il1] ); - } - // add nodes to insert - list::iterator nIt = aNodesToInsert.begin(); - for (; nIt != aNodesToInsert.end(); nIt++) { - poly_nodes[iNode++] = *nIt; + + if ( theFace->IsQuadratic() ) { + const SMDS_VtkFace* F = dynamic_cast(theFace); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + // use special nodes iterator + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); + while( anIter->more() && !isFLN ) { + const SMDS_MeshNode* n = cast2Node(anIter->next()); + poly_nodes[iNode++] = n; + if (n == nodes[il1]) { + isFLN = true; + } + } + // add nodes to insert + list::iterator nIt = aNodesToInsert.begin(); + for (; nIt != aNodesToInsert.end(); nIt++) { + poly_nodes[iNode++] = *nIt; + } + // add nodes of face starting from last node of link + while ( anIter->more() ) { + poly_nodes[iNode++] = cast2Node(anIter->next()); + } } - // add nodes of face starting from last node of link - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - poly_nodes[iNode++] = n; + else { + SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); + while ( nodeIt->more() && !isFLN ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + poly_nodes[iNode++] = n; + if (n == nodes[il1]) { + isFLN = true; + } + } + // add nodes to insert + list::iterator nIt = aNodesToInsert.begin(); + for (; nIt != aNodesToInsert.end(); nIt++) { + poly_nodes[iNode++] = *nIt; + } + // add nodes of face starting from last node of link + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + poly_nodes[iNode++] = n; + } } // make a new face @@ -9036,7 +9093,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, const int nbNodes = elem->NbCornerNodes(); nodes.assign(elem->begin_nodes(), elem->end_nodes()); if ( aGeomType == SMDSEntity_Polyhedra ) - nbNodeInFaces = static_cast( elem )->GetQuantities(); + nbNodeInFaces = static_cast( elem )->GetQuantities(); else if ( aGeomType == SMDSEntity_Hexagonal_Prism ) volumeToPolyhedron( elem, nodes, nbNodeInFaces ); @@ -9257,7 +9314,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT const int id = volume->GetID(); vector nodes (volume->begin_nodes(), volume->end_nodes()); if ( type == SMDSEntity_Polyhedra ) - nbNodeInFaces = static_cast(volume)->GetQuantities(); + nbNodeInFaces = static_cast(volume)->GetQuantities(); else if ( type == SMDSEntity_Hexagonal_Prism ) volumeToPolyhedron( volume, nodes, nbNodeInFaces ); @@ -10019,8 +10076,20 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, //cout << " F " << face[ iSide]->GetID() <erase( face[ iSide ]); // put face nodes to fnodes - SMDS_MeshElement::iterator nIt( face[ iSide ]->interlacedNodesIterator() ), nEnd; - fnodes[ iSide ].assign( nIt, nEnd ); + if ( face[ iSide ]->IsQuadratic() ) + { + // use interlaced nodes iterator + const SMDS_VtkFace* F = dynamic_cast( face[ iSide ]); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + SMDS_ElemIteratorPtr nIter = F->interlacedNodesElemIterator(); + while ( nIter->more() ) + fnodes[ iSide ].push_back( cast2Node( nIter->next() )); + } + else + { + fnodes[ iSide ].assign( face[ iSide ]->begin_nodes(), + face[ iSide ]->end_nodes() ); + } fnodes[ iSide ].push_back( fnodes[ iSide ].front()); } } @@ -10916,9 +10985,9 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements ) if ( mesh->GetMeshInfo().NbElements( types[i] )) { type = types[i]; - elemIt = mesh->elementsIterator( type ); break; } + elemIt = mesh->elementsIterator( type ); } else { @@ -11137,7 +11206,8 @@ namespace { const double theTol) { gp_XYZ centerXYZ (0, 0, 0); - for ( SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); aNodeItr->more(); ) + SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); + while ( aNodeItr->more() ) centerXYZ += SMESH_NodeXYZ( aNodeItr->next() ); gp_Pnt aPnt = centerXYZ / theElem->NbNodes(); @@ -11362,7 +11432,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectormyMesh->GetMeshDS(); meshDS->BuildDownWardConnectivity(true); CHRONO(50); - SMDS_UnstructuredGrid *grid = meshDS->GetGrid(); + SMDS_UnstructuredGrid *grid = meshDS->getGrid(); // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes // build the list of cells with only a node or an edge on the border, with their domain and volume indexes @@ -11428,7 +11498,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetVtkID(); + int vtkId = anElem->getVtkId(); //MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID()); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; @@ -11436,7 +11506,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); for (int n = 0; n < nbNeighbors; n++) { - int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]); + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared { @@ -11499,7 +11569,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorFindElement(GetMeshDS()->FromVtkToSmds(vtkId)); + const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId)); if (!domain.count(anElem)) continue; int vtkType = grid->GetCellType(vtkId); @@ -11583,7 +11653,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetPoint(oldId); SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); copyPosition( meshDS->FindNodeVtk( oldId ), newNode ); - int newId = newNode->GetVtkID(); + int newId = newNode->getVtkId(); nodeDomains[oldId][idom] = newId; // cloned node for other domains //MESSAGE("-+-+-c oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" < domvol; // domain --> a volume with the edge + map domvol; // domain --> a volume with the edge map angleDom; // oriented angles between planes defined by edge and volume centers int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); for ( size_t id = 0; id < doms.size(); id++ ) @@ -11665,31 +11735,26 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorFromVtkToSmds(vtkVolIds[ivol]); - const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); + int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]); + SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); if (domain.count(elem)) { - const SMDS_MeshVolume* svol = SMDS_Mesh::DownCast(elem); - domvol[idom] = (SMDS_MeshVolume*) svol; + SMDS_VtkVolume* svol = dynamic_cast(elem); + domvol[idom] = svol; //MESSAGE(" domain " << idom << " volume " << elem->GetID()); - double values[3] = { 0,0,0 }; + double values[3]; vtkIdType npts = 0; vtkIdType* pts = 0; grid->GetCellPoints(vtkVolIds[ivol], npts, pts); - for ( vtkIdType i = 0; i < npts; ++i ) - { - double *coords = grid->GetPoint( pts[i] ); - for ( int j = 0; j < 3; ++j ) - values[j] += coords[j] / npts; - } - if ( id == 0 ) + SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); + if (id ==0) { - gref.SetCoord( values[0], values[1], values[2] ); + gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); angleDom[idom] = 0; } else { - gp_Pnt g( values[0], values[1], values[2] ); + gp_Pnt g(values[0], values[1], values[2]); angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -piGetMeshDS()->FromVtkToSmds(vtkId) << " domain " << idomain + //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain // << " type " << vtkType << " downId " << downId); } } @@ -11910,7 +11975,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; int vtkVolId = itdom->second; - //MESSAGE("modify nodes of cell " << this->GetMeshDS()->FromVtkToSmds(vtkVolId) << " domain " << idom); + //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom); localClonedNodeIds.clear(); for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) { @@ -11977,7 +12042,8 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vectorDownCast ( *elemItr ); + SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; + SMDS_MeshFace* aFace = dynamic_cast (anElem); if (!aFace) continue; // MESSAGE("aFace=" << aFace->GetID()); @@ -11986,11 +12052,11 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vectornodeIterator(); + SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator(); while (nodeIt->more()) { - const SMDS_MeshNode* node = nodeIt->next(); - bool isMedium = ( isQuad && aFace->IsMediumNode( node )); + const SMDS_MeshNode* node = static_cast (nodeIt->next()); + bool isMedium = isQuad && (aFace->IsMediumNode(node)); if (isMedium) ln2.push_back(node); else @@ -12098,7 +12164,7 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector( aFace )->ChangeNodes( &ln[0], ln.size() ); + aFace->ChangeNodes(&ln[0], ln.size()); } } return true; @@ -12209,7 +12275,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); meshDS->BuildDownWardConnectivity(true); - SMDS_UnstructuredGrid* grid = meshDS->GetGrid(); + SMDS_UnstructuredGrid* grid = meshDS->getGrid(); // --- set of volumes detected inside @@ -12236,7 +12302,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, while (volItr->more()) { vol = (SMDS_MeshElement*)volItr->next(); - setOfInsideVol.insert(vol->GetVtkID()); + setOfInsideVol.insert(vol->getVtkId()); sgrp->Add(vol->GetID()); } } @@ -12291,7 +12357,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, while (volItr->more()) { startVol = (SMDS_MeshElement*)volItr->next(); - setOfVolToCheck.insert(startVol->GetVtkID()); + setOfVolToCheck.insert(startVol->getVtkId()); } if (setOfVolToCheck.empty()) { @@ -12310,7 +12376,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, { std::set::iterator it = setOfVolToCheck.begin(); int vtkId = *it; - //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); bool volInside = false; vtkIdType npts = 0; vtkIdType* pts = 0; @@ -12344,14 +12410,14 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, if (distance2 < radius2) { volInside = true; // one or more nodes inside the domain - sgrp->Add(meshDS->FromVtkToSmds(vtkId)); + sgrp->Add(meshDS->fromVtkToSmds(vtkId)); break; } } if (volInside) { setOfInsideVol.insert(vtkId); - //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS]; @@ -12363,7 +12429,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, else { setOfOutsideVol.insert(vtkId); - //MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); } setOfVolToCheck.erase(vtkId); } @@ -12398,7 +12464,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, int vtkId = *it; if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON) { - //MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); int countInside = 0; int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; @@ -12410,9 +12476,9 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, //MESSAGE("countInside " << countInside); if (countInside > 1) { - //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); setOfInsideVol.insert(vtkId); - sgrp->Add(meshDS->FromVtkToSmds(vtkId)); + sgrp->Add(meshDS->fromVtkToSmds(vtkId)); addedInside = true; } else @@ -12433,7 +12499,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, for (; it != setOfInsideVol.end(); ++it) { int vtkId = *it; - //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); + //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS]; @@ -12452,7 +12518,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); if (vtkFaceId >= 0) { - sgrpi->Add(meshDS->FromVtkToSmds(vtkFaceId)); + sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId)); // find also the smds edges on this face int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]); const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]); @@ -12461,7 +12527,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, { int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]); if (vtkEdgeId >= 0) - sgrpei->Add(meshDS->FromVtkToSmds(vtkEdgeId)); + sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId)); } } } @@ -12471,7 +12537,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, skinFaces[face] = vtkId; int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); if (vtkFaceId >= 0) - sgrps->Add(meshDS->FromVtkToSmds(vtkFaceId)); + sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId)); } } } @@ -12490,7 +12556,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, { const SMDS_MeshElement *elem = itelem->next(); int shapeId = elem->getshapeId(); - int vtkId = elem->GetVtkID(); + int vtkId = elem->getVtkId(); if (!shapeIdToVtkIdSet.count(shapeId)) { shapeIdToVtkIdSet[shapeId] = emptySet; @@ -12525,7 +12591,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, { if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here continue; - int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]); + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group { @@ -12765,7 +12831,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, if (elements.empty()) eIt = aMesh->elementsIterator(elemType); else eIt = SMESHUtils::elemSetIterator( elements ); - while ( eIt->more() ) + while (eIt->more()) { const SMDS_MeshElement* elem = eIt->next(); const int iQuad = elem->IsQuadratic(); @@ -12846,7 +12912,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, else if ( elem->GetType() == SMDSAbs_Face ) // elem is a face ------------------------ { avoidSet.clear(), avoidSet.insert( elem ); - elemNodes.assign( SMDS_MeshElement::iterator( elem->interlacedNodesIterator() ), + elemNodes.assign( SMDS_MeshElement::iterator( elem->interlacedNodesElemIterator() ), SMDS_MeshElement::iterator() ); elemNodes.push_back( elemNodes[0] ); nodes.resize( 2 + iQuad ); @@ -13000,7 +13066,7 @@ void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from, case SMDS_TOP_FACE: { - SMDS_FacePositionPtr fPos = pos; + const SMDS_FacePosition* fPos = static_cast< const SMDS_FacePosition* >( pos ); GetMeshDS()->SetNodeOnFace( to, from->getshapeId(), fPos->GetUParameter(), fPos->GetVParameter() ); break; @@ -13008,7 +13074,7 @@ void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from, case SMDS_TOP_EDGE: { // WARNING: it is dangerous to set equal nodes on one EDGE!!!!!!!! - SMDS_EdgePositionPtr ePos = pos; + const SMDS_EdgePosition* ePos = static_cast< const SMDS_EdgePosition* >( pos ); GetMeshDS()->SetNodeOnEdge( to, from->getshapeId(), ePos->GetUParameter() ); break; } diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index ad48bd49d..242900a74 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -643,22 +643,22 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, { gp_Pnt2d uv( Precision::Infinite(), Precision::Infinite() ); - SMDS_PositionPtr pos = n->GetPosition(); + const SMDS_PositionPtr Pos = n->GetPosition(); bool uvOK = false; - if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) + if ( Pos->GetTypeOfPosition() == SMDS_TOP_FACE ) { // node has position on face - SMDS_FacePositionPtr fpos = pos; + const SMDS_FacePosition* fpos = static_cast( Pos ); uv.SetCoord( fpos->GetUParameter(), fpos->GetVParameter() ); if ( check ) uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2.*getFaceMaxTol( F )); // 2. from 22830 } - else if ( pos->GetTypeOfPosition() == SMDS_TOP_EDGE ) + else if ( Pos->GetTypeOfPosition() == SMDS_TOP_EDGE ) { // node has position on EDGE => it is needed to find // corresponding EDGE from FACE, get pcurve for this // EDGE and retrieve value from this pcurve - SMDS_EdgePositionPtr epos = pos; + const SMDS_EdgePosition* epos = static_cast( Pos ); const int edgeID = n->getshapeId(); const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); double f, l, u = epos->GetUParameter(); @@ -699,7 +699,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, uv = newUV; } } - else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + else if ( Pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { if ( int vertexID = n->getshapeId() ) { const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID)); @@ -1031,7 +1031,8 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, const SMDS_PositionPtr pos = n->GetPosition(); if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - param = pos->GetParameters()[0]; + const SMDS_EdgePosition* epos = static_cast( pos ); + param = epos->GetUParameter(); } else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { @@ -4561,16 +4562,8 @@ namespace { // Structures used by FixQuadraticElements() TopoDS_Shape shape = theHelper.GetSubShape().Oriented( TopAbs_FORWARD ); if ( shape.IsNull() ) return; - if ( !dynamic_cast( theError.get() )) - { - if ( !theError ) - theError.reset( new SMESH_BadInputElements( meshDS )); - else - theError.reset( new SMESH_BadInputElements( meshDS, - theError->myName, - theError->myComment, - theError->myAlgo)); - } + if ( !theError ) theError = SMESH_ComputeError::New(); + gp_XYZ faceNorm; if ( shape.ShapeType() == TopAbs_FACE ) // 2D @@ -4688,13 +4681,13 @@ namespace { // Structures used by FixQuadraticElements() gp_XYZ pMid3D = 0.5 * ( pN0 + SMESH_TNodeXYZ( nOnEdge[1] )); meshDS->MoveNode( n, pMid3D.X(), pMid3D.Y(), pMid3D.Z() ); MSG( "move OUT of face " << n ); - static_cast( theError.get() )->add( f ); + theError->myBadElements.push_back( f ); } } } } } - if ( theError->HasBadElems() ) + if ( !theError->myBadElements.empty() ) theError->myName = EDITERR_NO_MEDIUM_ON_GEOM; return; @@ -4882,13 +4875,13 @@ namespace { // Structures used by FixQuadraticElements() MSG( "move OUT of solid " << nMedium ); } } - static_cast( theError.get() )->add( vol ); + theError->myBadElements.push_back( vol ); } } // loop on volumes sharing a node on FACE } // loop on nodes on FACE } // loop on FACEs of a SOLID - if ( theError->HasBadElems() ) + if ( !theError->myBadElements.empty() ) theError->myName = EDITERR_NO_MEDIUM_ON_GEOM; } // 3D case } @@ -4900,7 +4893,7 @@ namespace { // Structures used by FixQuadraticElements() * \brief Move medium nodes of faces and volumes to fix distorted elements * \param error - container of fixed distorted elements * \param volumeOnly - to fix nodes on faces or not, if the shape is solid - * + * * Issue 0020307: EDF 992 SMESH : Linea/Quadratic with Medium Node on Geometry */ //======================================================================= @@ -5275,7 +5268,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, gp_XY newUV = ApplyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added ); gp_Pnt newPnt = s->Value( newUV.X(), newUV.Y()); move = gp_Vec( XYZ((*link1)->_mediumNode), newPnt.Transformed(loc) ); - if ( SMDS_FacePositionPtr nPos = (*link1)->_mediumNode->GetPosition()) + if ( SMDS_FacePosition* nPos = + dynamic_cast< SMDS_FacePosition* >((*link1)->_mediumNode->GetPosition())) nPos->SetParameters( newUV.X(), newUV.Y() ); #ifdef _DEBUG_ if ( (XYZ((*link1)->node1()) - XYZ((*link1)->node2())).SquareModulus() < diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index f032ae475..b307ba31c 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -801,7 +801,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, ++nbMeduimNodes; continue; } - SMDS_EdgePositionPtr epos = node->GetPosition(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition()); double u = epos->GetUParameter(); paramNodeMap.insert( make_pair( u, node )); } @@ -928,7 +929,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, if ( theProject || edgesUVBox.IsOut( p->myInitUV ) ) p->myInitUV = project( node, projector ); else { - SMDS_FacePositionPtr pos = node->GetPosition(); + const SMDS_FacePosition* pos = + static_cast(node->GetPosition()); p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() ); } p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 ); @@ -3286,7 +3288,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, const SMDS_MeshNode* node = nIt->next(); if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) continue; - SMDS_EdgePositionPtr epos = node->GetPosition(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition()); double u = ( epos->GetUParameter() - f ) / ( l - f ); (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u ); } @@ -4169,8 +4172,7 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, createElements( theMesh, nodesVector, myElemPointIDs, myElements ); } - aMeshDS->Modified(); - aMeshDS->CompactMesh(); + aMeshDS->compactMesh(); if ( myToKeepNodes ) myOutNodes.swap( nodesVector ); diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx index 9e2e34792..a28033fda 100644 --- a/src/SMESH/SMESH_ProxyMesh.cxx +++ b/src/SMESH/SMESH_ProxyMesh.cxx @@ -38,21 +38,9 @@ */ //================================================================================ -SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0), _subContainer(0) +SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0) { } -//================================================================================ -/*! - * \brief Constructor - */ -//================================================================================ - -SMESH_ProxyMesh::SMESH_ProxyMesh(const SMESH_Mesh& mesh) - : _mesh( &mesh ), - _subContainer( new SubMesh( GetMeshDS() ) ) -{ -} - //================================================================================ /*! * \brief Make a proxy mesh from components. Components become empty @@ -71,7 +59,7 @@ SMESH_ProxyMesh::SMESH_ProxyMesh(std::vector& components): takeTmpElemsInMesh( m ); - if ( !_mesh && m->_mesh ) setMesh( *( m->_mesh )); + if ( !_mesh ) _mesh = m->_mesh; if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes; if ( _subMeshes.size() < m->_subMeshes.size() ) @@ -113,8 +101,6 @@ SMESH_ProxyMesh::SMESH_ProxyMesh(std::vector& components): SMESH_ProxyMesh::~SMESH_ProxyMesh() { - delete _subContainer; - for ( size_t i = 0; i < _subMeshes.size(); ++i ) delete _subMeshes[i]; _subMeshes.clear(); @@ -125,19 +111,6 @@ SMESH_ProxyMesh::~SMESH_ProxyMesh() _elemsInMesh.clear(); } -//================================================================================ -/*! - * \brief Set mesh - */ -//================================================================================ - -void SMESH_ProxyMesh::setMesh(const SMESH_Mesh& mesh) -{ - _mesh = &mesh; - if ( _mesh ) - _subContainer = new SubMesh( GetMeshDS() ); -} - //================================================================================ /*! * \brief Returns index of a shape @@ -149,19 +122,6 @@ int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape)); } -//================================================================================ -/*! - * \brief Create a SubMesh - * \param [ino] index - shape index - * \return SubMesh* - new SubMesh - */ -//================================================================================ - -SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::newSubmesh(int index) const -{ - return new SubMesh( GetMeshDS(),index ); -} - //================================================================================ /*! * \brief Returns the submesh of a shape; it can be a proxy sub-mesh @@ -285,15 +245,15 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const if ( !_mesh->HasShapeToMesh() ) return SMDS_ElemIteratorPtr(); - _subContainer->RemoveAllSubmeshes(); + _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 ); + _subContainer.AddSubMesh( sm ); - return _subContainer->SMESHDS_SubMesh::GetElements(); + return _subContainer.SMESHDS_SubMesh::GetElements(); } //================================================================================ @@ -308,16 +268,16 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const if ( _mesh->HasShapeToMesh() ) return SMDS_ElemIteratorPtr(); - _subContainer->RemoveAllSubmeshes(); + _subContainer.RemoveAllSubmeshes(); for ( unsigned i = 0; i < _subMeshes.size(); ++i ) if ( _subMeshes[i] ) - _subContainer->AddSubMesh( _subMeshes[i] ); + _subContainer.AddSubMesh( _subMeshes[i] ); - if ( _subContainer->NbSubMeshes() == 0 ) // no elements substituted + 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(); + SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements(); if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() ) return proxyIter; @@ -573,7 +533,7 @@ int SMESH_ProxyMesh::SubMesh::NbElements() const */ //================================================================================ -SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const +SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements(bool reverse) const { return SMDS_ElemIteratorPtr ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() )); @@ -598,7 +558,7 @@ int SMESH_ProxyMesh::SubMesh::NbNodes() const */ //================================================================================ -SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes() const +SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes(bool reverse) const { if ( !_uvPtStructVec.empty() ) return SMDS_NodeIteratorPtr ( new SMDS_SetIterator diff --git a/src/SMESH/SMESH_ProxyMesh.hxx b/src/SMESH/SMESH_ProxyMesh.hxx index 35a4c3a97..a64002e02 100644 --- a/src/SMESH/SMESH_ProxyMesh.hxx +++ b/src/SMESH/SMESH_ProxyMesh.hxx @@ -26,7 +26,6 @@ #include "SMESH_SMESH.hxx" -#include "SMDS_ElementHolder.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_TypeDefs.hxx" @@ -57,7 +56,7 @@ public: /*! * \brief Proxy sub-mesh */ - class SMESH_EXPORT SubMesh : public SMESHDS_SubMesh, SMDS_ElementHolder + class SMESH_EXPORT SubMesh : public SMESHDS_SubMesh { public: @@ -67,20 +66,19 @@ public: virtual void AddElement(const SMDS_MeshElement * e); virtual int NbElements() const; virtual int NbNodes() const; - virtual SMDS_ElemIteratorPtr GetElements() const; - virtual SMDS_NodeIteratorPtr GetNodes() const; + virtual SMDS_ElemIteratorPtr GetElements(bool reverse=false) const; + virtual SMDS_NodeIteratorPtr GetNodes(bool reverse=false) const; virtual void Clear(); virtual bool Contains(const SMDS_MeshElement * ME) const; template< class ITERATOR > - void ChangeElements( ITERATOR it, ITERATOR end ) + void ChangeElements( ITERATOR it, ITERATOR end ) { // change SubMesh contents without deleting tmp elements // for which the caller is responsible _elements.assign( it, end ); } - SubMesh(const SMDS_Mesh* mesh, int index=0) - :SMESHDS_SubMesh(0,index), SMDS_ElementHolder(mesh), _n2n(0) {} + SubMesh(int index=0):SMESHDS_SubMesh(0,index),_n2n(0) {} virtual ~SubMesh() { Clear(); } protected: @@ -88,20 +86,13 @@ public: TN2NMap* _n2n; UVPtStructVec _uvPtStructVec; // for SubMesh of EDGE friend class SMESH_ProxyMesh; - - protected: // methods of SMDS_ElementHolder; remove elements before mesh compacting or clearing - virtual SMDS_ElemIteratorPtr getElements() { Clear(); return GetElements(); } - virtual void tmpClear() {} - virtual void add( const SMDS_MeshElement* element ) {} - virtual void compact() {} - virtual void clear() { Clear(); } }; //-------------------------------------------------------------------------------- // Public interface SMESH_ProxyMesh(); SMESH_ProxyMesh(std::vector& components); - SMESH_ProxyMesh(const SMESH_Mesh& mesh); + SMESH_ProxyMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; } virtual ~SMESH_ProxyMesh(); // Returns the submesh of a shape; it can be a proxy sub-mesh @@ -138,11 +129,11 @@ public: // Interface for descendants protected: - void setMesh(const SMESH_Mesh& mesh); + void setMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; } int shapeIndex(const TopoDS_Shape& shape) const; - virtual SubMesh* newSubmesh(int index=0) const; + virtual SubMesh* newSubmesh(int index=0) const { return new SubMesh(index); } // returns a proxy sub-mesh; zero index is for the case of mesh w/o shape SubMesh* findProxySubMesh(int shapeIndex=0) const; @@ -186,7 +177,7 @@ public: std::set< const SMDS_MeshElement* > _elemsInMesh; // Complex submesh used to iterate over elements in other sub-meshes - mutable SubMesh* _subContainer; + mutable SubMesh _subContainer; }; #endif diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index e8a61f295..05800491b 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1293,19 +1293,40 @@ static void cleanSubMesh( SMESH_subMesh * subMesh ) SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS(); int nbElems = subMeshDS->NbElements(); if ( nbElems > 0 ) - for ( SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); ite->more(); ) - meshDS->RemoveFreeElement( ite->next(), subMeshDS ); - + { + // start from elem with max ID to avoid filling the pool of IDs + bool rev = true; + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements( rev ); + const SMDS_MeshElement * lastElem = ite->next(); + rev = ( lastElem->GetID() == meshDS->MaxElementID() ); + if ( !rev ) + ite = subMeshDS->GetElements( rev ); + else + meshDS->RemoveFreeElement( lastElem, subMeshDS ); + while (ite->more()) { + const SMDS_MeshElement * elt = ite->next(); + meshDS->RemoveFreeElement( elt, subMeshDS ); + } + } int nbNodes = subMeshDS->NbNodes(); if ( nbNodes > 0 ) - for ( SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); itn->more() ; ) - { + { + bool rev = true; + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes( rev ); + const SMDS_MeshNode * lastNode = itn->next(); + rev = ( lastNode->GetID() == meshDS->MaxNodeID() ); + if ( !rev ) + itn = subMeshDS->GetNodes( rev ); + else + meshDS->RemoveNode( lastNode ); + while (itn->more()) { const SMDS_MeshNode * node = itn->next(); if ( node->NbInverseElements() == 0 ) meshDS->RemoveFreeNode( node, subMeshDS ); else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another - meshDS->RemoveNode( node ); + meshDS->RemoveNode(node); } + } subMeshDS->Clear(); } } diff --git a/src/SMESHClient/SMESH_Client.cxx b/src/SMESHClient/SMESH_Client.cxx index 73ad16111..f556f1a92 100644 --- a/src/SMESHClient/SMESH_Client.cxx +++ b/src/SMESHClient/SMESH_Client.cxx @@ -749,30 +749,30 @@ namespace SMESH::log_array_var& theSeq, CORBA::Long theId) { - // const SMESH::long_array& anIndexes = theSeq[theId].indexes; - // CORBA::Long iind = 0, aNbElems = theSeq[theId].number; - - // for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) - // { - // // find element - // const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]); - // // nb nodes - // int nbNodes = anIndexes[iind++]; - // // nodes - // std::vector aNodes (nbNodes); - // for (int iNode = 0; iNode < nbNodes; iNode++) { - // aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]); - // } - // // nb faces - // int nbFaces = anIndexes[iind++]; - // // quantities - // std::vector quantities (nbFaces); - // for (int iFace = 0; iFace < nbFaces; iFace++) { - // quantities[iFace] = anIndexes[iind++]; - // } - // // change - // theMesh->ChangePolyhedronNodes(elem, aNodes, quantities); - // } + const SMESH::long_array& anIndexes = theSeq[theId].indexes; + CORBA::Long iind = 0, aNbElems = theSeq[theId].number; + + for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) + { + // find element + const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]); + // nb nodes + int nbNodes = anIndexes[iind++]; + // nodes + std::vector aNodes (nbNodes); + for (int iNode = 0; iNode < nbNodes; iNode++) { + aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]); + } + // nb faces + int nbFaces = anIndexes[iind++]; + // quantities + std::vector quantities (nbFaces); + for (int iFace = 0; iFace < nbFaces; iFace++) { + quantities[iFace] = anIndexes[iind++]; + } + // change + theMesh->ChangePolyhedronNodes(elem, aNodes, quantities); + } } } @@ -986,10 +986,10 @@ SMESH_Client::Update(bool theIsClear) ChangePolyhedronNodes(mySMDSMesh, aSeq, anId); break; case SMESH::RENUMBER: - // for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3) - // { - // mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] ); - // } + for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3) + { + mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] ); + } break; default:; diff --git a/src/SMESHDS/SMESHDS_Group.cxx b/src/SMESHDS/SMESHDS_Group.cxx index e6df602ff..6ffa1b19c 100644 --- a/src/SMESHDS/SMESHDS_Group.cxx +++ b/src/SMESHDS/SMESHDS_Group.cxx @@ -19,13 +19,17 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes // File : SMESHDS_Group.cxx // Module : SMESH +// $Header$ // - #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" +using namespace std; + //============================================================================= /*! * @@ -35,8 +39,8 @@ SMESHDS_Group::SMESHDS_Group (const int theID, const SMESHDS_Mesh* theMesh, const SMDSAbs_ElementType theType) - : SMESHDS_GroupBase(theID,theMesh,theType), - myGroup(theMesh,theType) + : SMESHDS_GroupBase(theID,theMesh,theType), + myGroup(theMesh,theType) { } @@ -143,7 +147,20 @@ void SMESHDS_Group::Clear() myGroup.Clear(); resetIterator(); } - + +// ===================== +// class MyGroupIterator +// ===================== + +class MyGroupIterator: public SMDS_ElemIterator +{ + const SMDS_MeshGroup& myGroup; + public: + MyGroupIterator(const SMDS_MeshGroup& group): myGroup(group) { myGroup.InitIterator(); } + bool more() { return myGroup.More(); } + const SMDS_MeshElement* next() { return myGroup.Next(); } +}; + //======================================================================= //function : GetElements //purpose : @@ -151,7 +168,7 @@ void SMESHDS_Group::Clear() SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const { - return myGroup.GetElements(); + return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup )); } //================================================================================ @@ -172,14 +189,11 @@ int SMESHDS_Group::GetTic() const void SMESHDS_Group::SetType(SMDSAbs_ElementType theType) { - if ( myGroup.IsEmpty() || GetType() == SMDSAbs_All ) - { + if ( myGroup.IsEmpty() || GetType() == SMDSAbs_All ) { SMESHDS_GroupBase::SetType( theType ); myGroup.SetType ( theType ); } else - { SMESHDS_GroupBase::SetType( myGroup.GetType() ); - } } diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.cxx b/src/SMESHDS/SMESHDS_GroupOnFilter.cxx index e5b2fb736..7653e176c 100644 --- a/src/SMESHDS/SMESHDS_GroupOnFilter.cxx +++ b/src/SMESHDS/SMESHDS_GroupOnFilter.cxx @@ -26,14 +26,11 @@ #include "SMESHDS_GroupOnFilter.hxx" #include "SMDS_SetIterator.hxx" -#include "ObjectPool.hxx" #include "SMESHDS_Mesh.hxx" #include #include -#include - using namespace std; //#undef WITH_TBB @@ -48,12 +45,11 @@ SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int theID, const SMESHDS_Mesh* theMesh, const SMDSAbs_ElementType theType, const SMESH_PredicatePtr& thePredicate) - : SMESHDS_GroupBase( theID, theMesh, theType ), - SMDS_ElementHolder( theMesh ), + : SMESHDS_GroupBase(theID,theMesh,theType), myMeshInfo( SMDSEntity_Last, 0 ), - myMeshModifTime( 0 ), - myPredicateTic( 0 ), - myNbElemToSkip( 0 ) + myMeshModifTime(0), + myPredicateTic(0), + myNbElemToSkip(0) { SetPredicate( thePredicate ); } @@ -536,38 +532,3 @@ SMESHDS_GroupOnFilter::setNbElemToSkip( SMDS_ElemIteratorPtr& okElemIt ) } return firstOkElem; } - -//================================================================================ -/*! - * \brief Return elements before mesh compacting - */ -//================================================================================ - -SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::getElements() -{ - return boost::make_shared< SMDS_ElementVectorIterator >( myElements.begin(), myElements.end() ); -} - -//================================================================================ -/*! - * \brief clear myElements before re-filling after mesh compacting - */ -//================================================================================ - -void SMESHDS_GroupOnFilter::tmpClear() -{ - std::vector< const SMDS_MeshElement*> newElems( myElements.size() ); - myElements.swap( newElems ); - myElements.clear(); -} - -//================================================================================ -/*! - * \brief Re-fill myElements after mesh compacting - */ -//================================================================================ - -void SMESHDS_GroupOnFilter::add( const SMDS_MeshElement* element ) -{ - myElements.push_back( element ); -} diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.hxx b/src/SMESHDS/SMESHDS_GroupOnFilter.hxx index 9b235c1a3..94bc25af4 100644 --- a/src/SMESHDS/SMESHDS_GroupOnFilter.hxx +++ b/src/SMESHDS/SMESHDS_GroupOnFilter.hxx @@ -27,14 +27,13 @@ #include "SMESH_SMESHDS.hxx" -#include "SMDS_ElementHolder.hxx" #include "SMESHDS_GroupBase.hxx" #include "SMESH_Controls.hxx" - + /*! * \brief Groups whose contents is dynamically updated using the filter */ -class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase, SMDS_ElementHolder +class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase { public: @@ -70,13 +69,6 @@ class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase, SMDS_Eleme bool IsUpToDate() const; - protected: // methods of SMDS_ElementHolder - - virtual SMDS_ElemIteratorPtr getElements(); - virtual void tmpClear(); - virtual void add( const SMDS_MeshElement* element ); - virtual void compact() {}; - private: void update() const; diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index e973495bf..865e700c1 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -50,6 +50,8 @@ #include "utilities.h" +using namespace std; + class SMESHDS_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< const SMESHDS_SubMesh > { }; @@ -103,7 +105,7 @@ int SMESHDS_Mesh::GetPersistentId() const //======================================================================= void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) { - if ( !myShape.IsNull() && S.IsNull() ) // case: "save study" after geometry removal + if ( !myShape.IsNull() && S.IsNull() ) { // removal of a shape to mesh, delete ... // - hypotheses @@ -114,7 +116,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) if ( !sm->IsComplexSubmesh() ) { SMDS_NodeIteratorPtr nIt = sm->GetNodes(); while ( nIt->more() ) - sm->RemoveNode(nIt->next()); + sm->RemoveNode(nIt->next(), false); } } // - sub-meshes @@ -122,7 +124,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) myIndexToShape.Clear(); // - groups on geometry - std::set::iterator gr = myGroups.begin(); + set::iterator gr = myGroups.begin(); while ( gr != myGroups.end() ) { if ( dynamic_cast( *gr )) myGroups.erase( gr++ ); @@ -135,8 +137,6 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) if ( !S.IsNull() ) TopExp::MapShapes(myShape, myIndexToShape); } - - SMDS_Mesh::setNbShapes( MaxShapeIndex() ); } //======================================================================= @@ -148,14 +148,14 @@ bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H) { if (!myShapeToHypothesis.IsBound(SS/*.Oriented(TopAbs_FORWARD)*/)) { - std::list aList; + list aList; myShapeToHypothesis.Bind(SS/*.Oriented(TopAbs_FORWARD)*/, aList); } - std::list& alist = + list& alist = myShapeToHypothesis(SS/*.Oriented(TopAbs_FORWARD)*/); // ignore orientation of SS //Check if the Hypothesis is still present - std::list::iterator ith = find(alist.begin(),alist.end(), H ); + list::iterator ith = find(alist.begin(),alist.end(), H ); if (alist.end() != ith) return false; @@ -173,8 +173,8 @@ bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, { if( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) ) { - std::list& alist=myShapeToHypothesis.ChangeFind( S/*.Oriented(TopAbs_FORWARD)*/ ); - std::list::iterator ith=find(alist.begin(),alist.end(), H ); + list& alist=myShapeToHypothesis.ChangeFind( S/*.Oriented(TopAbs_FORWARD)*/ ); + list::iterator ith=find(alist.begin(),alist.end(), H ); if (ith != alist.end()) { alist.erase(ith); @@ -223,7 +223,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes )) return false; - std::vector IDs( nbnodes ); + vector IDs( nbnodes ); for ( int i = 0; i < nbnodes; i++ ) IDs [ i ] = nodes[ i ]->GetID(); myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes); @@ -236,8 +236,8 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //purpose : //======================================================================= bool SMESHDS_Mesh::ChangePolygonNodes -(const SMDS_MeshElement * elem, - std::vector nodes) + (const SMDS_MeshElement * elem, + vector nodes) { ASSERT(nodes.size() > 3); @@ -249,14 +249,14 @@ bool SMESHDS_Mesh::ChangePolygonNodes //purpose : //======================================================================= bool SMESHDS_Mesh::ChangePolyhedronNodes -(const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities) + (const SMDS_MeshElement * elem, + std::vector nodes, + std::vector quantities) { ASSERT(nodes.size() > 3); - //if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities)) - return false; + if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities)) + return false; int i, len = nodes.size(); std::vector nodes_ids (len); @@ -276,10 +276,10 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) { // TODO not possible yet to have node numbers not starting to O and continuous. - if ( !this->IsCompacted() ) - this->CompactMesh(); - // SMDS_Mesh::Renumber( isNodes, startID, deltaID ); - // myScript->Renumber( isNodes, startID, deltaID ); + if (!this->isCompacted()) + this->compactMesh(); +// SMDS_Mesh::Renumber( isNodes, startID, deltaID ); +// myScript->Renumber( isNodes, startID, deltaID ); } //======================================================================= @@ -294,7 +294,7 @@ SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID) } SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID -(const SMDS_MeshNode * node, int ID) + (const SMDS_MeshNode * node, int ID) { return Add0DElementWithID(node->GetID(), ID); } @@ -801,9 +801,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID -(const std::vector& nodes, - const std::vector& quantities, - const int ID) + (const std::vector& nodes, + const std::vector& quantities, + const int ID) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); if (anElem) { @@ -818,8 +818,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume -(const std::vector& nodes, - const std::vector& quantities) + (const std::vector& nodes, + const std::vector& quantities) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities); if (anElem) { @@ -838,9 +838,10 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume //purpose : //======================================================================= -static void removeFromContainers (SMESHDS_Mesh* theMesh, - std::set& theGroups, - std::vector& theElems) +static void removeFromContainers (SMESHDS_Mesh* theMesh, + set& theGroups, + list& theElems, + const bool isNode) { if ( theElems.empty() ) return; @@ -849,13 +850,13 @@ static void removeFromContainers (SMESHDS_Mesh* theMesh, // Element can belong to several groups if ( !theGroups.empty() ) { - std::set::iterator GrIt = theGroups.begin(); + set::iterator GrIt = theGroups.begin(); for ( ; GrIt != theGroups.end(); GrIt++ ) { SMESHDS_Group* group = dynamic_cast( *GrIt ); if ( !group || group->IsEmpty() ) continue; - std::vector::iterator elIt = theElems.begin(); + list::iterator elIt = theElems.begin(); for ( ; elIt != theElems.end(); elIt++ ) { group->SMDSGroup().Remove( *elIt ); @@ -864,24 +865,24 @@ static void removeFromContainers (SMESHDS_Mesh* theMesh, } } - //const bool deleted=true; + const bool deleted=true; // Rm from sub-meshes // Element should belong to only one sub-mesh - // if ( theMesh->SubMeshes()->more() ) - // { - // std::list::iterator elIt = theElems.begin(); - // if ( isNode ) { - // for ( ; elIt != theElems.end(); ++elIt ) - // if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() )) - // sm->RemoveNode( static_cast (*elIt), deleted ); - // } - // else { - // for ( ; elIt != theElems.end(); ++elIt ) - // if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() )) - // sm->RemoveElement( *elIt, deleted ); - // } - // } + if ( theMesh->SubMeshes()->more() ) + { + list::iterator elIt = theElems.begin(); + if ( isNode ) { + for ( ; elIt != theElems.end(); ++elIt ) + if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() )) + sm->RemoveNode( static_cast (*elIt), deleted ); + } + else { + for ( ; elIt != theElems.end(); ++elIt ) + if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() )) + sm->RemoveElement( *elIt, deleted ); + } + } } //======================================================================= @@ -890,69 +891,56 @@ static void removeFromContainers (SMESHDS_Mesh* theMesh, //======================================================================= void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) { - if ( RemoveFreeNode( n, 0, true )) + if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces())) + { + RemoveFreeNode( n, 0, true ); return; + } myScript->RemoveNode(n->GetID()); - // remove inverse elements from the sub-meshes - for ( SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(); eIt->more() ; ) - { - const SMDS_MeshElement* e = eIt->next(); - if ( SMESHDS_SubMesh * sm = MeshElements( e->getshapeId() )) - sm->RemoveElement( e ); - } - if ( SMESHDS_SubMesh * sm = MeshElements( n->getshapeId() )) - sm->RemoveNode( n ); - - - std::vector removedElems; - std::vector removedNodes; + list removedElems; + list removedNodes; SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true ); - removeFromContainers( this, myGroups, removedElems ); - removeFromContainers( this, myGroups, removedNodes ); + removeFromContainers( this, myGroups, removedElems, false ); + removeFromContainers( this, myGroups, removedNodes, true ); } //======================================================================= //function : RemoveFreeNode //purpose : //======================================================================= -bool SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, +void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh, bool fromGroups) { - if ( n->NbInverseElements() > 0 ) - return false; - myScript->RemoveNode(n->GetID()); // Rm from group // Node can belong to several groups - if ( fromGroups && !myGroups.empty() ) { - std::set::iterator GrIt = myGroups.begin(); + if (fromGroups && !myGroups.empty()) { + set::iterator GrIt = myGroups.begin(); for (; GrIt != myGroups.end(); GrIt++) { SMESHDS_Group* group = dynamic_cast(*GrIt); - if (group && group->GetType() == SMDSAbs_Node ) + if (group && !group->IsEmpty()) group->SMDSGroup().Remove(n); } } // Rm from sub-mesh // Node should belong to only one sub-mesh - if ( !subMesh || !subMesh->RemoveNode( n )) + if ( !subMesh || !subMesh->RemoveNode(n,/*deleted=*/false)) if (( subMesh = MeshElements( n->getshapeId() ))) - subMesh->RemoveNode(n); + subMesh->RemoveNode(n,/*deleted=*/false ); SMDS_Mesh::RemoveFreeElement(n); - - return true; } //======================================================================= //function : RemoveElement -//purpose : +//purpose : //======================================================================== void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) { @@ -961,7 +949,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) RemoveNode( static_cast( elt )); return; } - //if (!hasConstructionEdges() && !hasConstructionFaces()) + if (!hasConstructionEdges() && !hasConstructionFaces()) { SMESHDS_SubMesh* subMesh=0; if ( elt->getshapeId() > 0 ) @@ -973,12 +961,12 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) myScript->RemoveElement(elt->GetID()); - std::vector removedElems; - std::vector removedNodes; + list removedElems; + list removedNodes; - SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes ); + SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false ); - removeFromContainers( this, myGroups, removedElems ); + removeFromContainers( this, myGroups, removedElems, false ); } //======================================================================= @@ -994,16 +982,16 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, return; } - // if (hasConstructionEdges() || hasConstructionFaces()) - // // this methods is only for meshes without descendants - // return; + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; myScript->RemoveElement(elt->GetID()); // Rm from group // Element can belong to several groups if ( fromGroups && !myGroups.empty() ) { - std::set::iterator GrIt = myGroups.begin(); + set::iterator GrIt = myGroups.begin(); for (; GrIt != myGroups.end(); GrIt++) { SMESHDS_Group* group = dynamic_cast(*GrIt); if (group && !group->IsEmpty()) @@ -1016,7 +1004,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, if ( !subMesh && elt->getshapeId() > 0 ) subMesh = MeshElements( elt->getshapeId() ); if ( subMesh ) - subMesh->RemoveElement( elt ); + subMesh->RemoveElement( elt, /*deleted=*/false ); SMDS_Mesh::RemoveFreeElement( elt ); } @@ -1055,8 +1043,8 @@ void SMESHDS_Mesh::ClearMesh() //================================================================================ /*! * \brief return submesh by shape - * \param shape - the sub-shape - * \retval SMESHDS_SubMesh* - the found submesh + * \param shape - the sub-shape + * \retval SMESHDS_SubMesh* - the found submesh */ //================================================================================ @@ -1071,81 +1059,84 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape ) //================================================================================ /*! * \brief Add element or node to submesh - * \param elem - element to add - * \param subMesh - submesh to be filled in + * \param elem - element to add + * \param subMesh - submesh to be filled in */ //================================================================================ -int SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ) +bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ) { if ( elem && subMesh ) { - subMesh->AddElement( elem ); - return subMesh->GetID(); + if ( elem->GetType() == SMDSAbs_Node ) + subMesh->AddNode( static_cast( elem )); + else + subMesh->AddElement( elem ); + return true; } - return 0; + return false; } //======================================================================= //function : SetNodeOnVolume -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, const TopoDS_Shell & S) { - if ( int shapeID = add( aNode, getSubmesh( S ))) + if ( add( aNode, getSubmesh(S) )) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID ); + ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() ); } //======================================================================= //function : SetNodeOnVolume -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode * aNode, const TopoDS_Solid & S) { - if ( int shapeID = add( aNode, getSubmesh( S ))) + if ( add( aNode, getSubmesh(S) )) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID ); + ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() ); } //======================================================================= //function : SetNodeOnFace -//purpose : +//purpose : //======================================================================= -void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode * aNode, - const TopoDS_Face & S, - double u, - double v) +void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode * aNode, + const TopoDS_Face & S, + double u, + double v) { - if ( int shapeID = add( aNode, getSubmesh( S ))) + if ( add( aNode, getSubmesh(S) )) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_FacePosition( u, v )), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= //function : SetNodeOnEdge -//purpose : +//purpose : //======================================================================= -void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode * aNode, - const TopoDS_Edge & S, - double u) +void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode * aNode, + const TopoDS_Edge & S, + double u) { - if ( int shapeID = add( aNode, getSubmesh( S ))) + if ( add( aNode, getSubmesh(S) )) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_EdgePosition( u )), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= //function : SetNodeOnVertex -//purpose : +//purpose : //======================================================================= -void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode * aNode, +void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode * aNode, const TopoDS_Vertex & S) { - if ( int shapeID = add( aNode, getSubmesh( S ))) + if ( add( aNode, getSubmesh(S) )) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_VertexPosition()), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -1157,12 +1148,12 @@ void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) int shapeId = aNode->getshapeId(); if (shapeId > 0) if ( SMESHDS_SubMesh* sm = MeshElements( shapeId )) - sm->RemoveNode(aNode); + sm->RemoveNode(aNode, /*deleted=*/false); } //======================================================================= //function : SetMeshElementOnShape -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement, const TopoDS_Shape & S) @@ -1178,7 +1169,12 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, const TopoDS_Shape & S) { if ( SMESHDS_SubMesh* sm = MeshElements( S )) - sm->RemoveElement(elem); + { + if (elem->GetType() == SMDSAbs_Node) + sm->RemoveNode(static_cast (elem), /*deleted=*/false); + else + sm->RemoveElement(elem, /*deleted=*/false); + } } //======================================================================= @@ -1230,9 +1226,9 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const //function : SubMeshIndices //purpose : //======================================================================= -std::list SMESHDS_Mesh::SubMeshIndices() const +list SMESHDS_Mesh::SubMeshIndices() const { - std::list anIndices; + list anIndices; SMESHDS_SubMeshIteratorPtr smIt = SubMeshes(); while ( const SMESHDS_SubMesh* sm = smIt->next() ) anIndices.push_back( sm->GetID() ); @@ -1255,13 +1251,13 @@ SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const //purpose : //======================================================================= -const std::list& +const list& SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const { if ( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) ) // ignore orientation of S - return myShapeToHypothesis.Find( S/*.Oriented(TopAbs_FORWARD)*/ ); + return myShapeToHypothesis.Find( S/*.Oriented(TopAbs_FORWARD)*/ ); - static std::list empty; + static list empty; return empty; } @@ -1286,7 +1282,7 @@ bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const //======================================================================= SMESHDS_Script* SMESHDS_Mesh::GetScript() { - return myScript; + return myScript; } //======================================================================= @@ -1295,7 +1291,7 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript() //======================================================================= void SMESHDS_Mesh::ClearScript() { - myScript->Clear(); + myScript->Clear(); } //======================================================================= @@ -1412,46 +1408,46 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { - if ( int shapeID = add( aNode, NewSubMesh( Index ))) - ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID ); + if ( add( aNode, NewSubMesh( Index ))) + ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition()); } //======================================================================= //function : SetNodeOnFace -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode* aNode, int Index, double u, double v) { //Set Position on Node - if ( int shapeID = add( aNode, NewSubMesh( Index ))) + if ( add( aNode, NewSubMesh( Index ))) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v )), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= //function : SetNodeOnEdge -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode* aNode, int Index, double u) { //Set Position on Node - if ( int shapeID = add( aNode, NewSubMesh( Index ))) + if ( add( aNode, NewSubMesh( Index ))) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( u )), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= //function : SetNodeOnVertex -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index) { //Set Position on Node - if ( int shapeID = add( aNode, NewSubMesh( Index ))) + if ( add( aNode, NewSubMesh( Index ))) const_cast< SMDS_MeshNode* > - ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()), shapeID ); + ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -2217,7 +2213,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, - const SMDS_MeshNode * n48, + const SMDS_MeshNode * n48, const SMDS_MeshNode * n1234, const SMDS_MeshNode * n1256, const SMDS_MeshNode * n2367, @@ -2236,14 +2232,126 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID); } -void SMESHDS_Mesh::CompactMesh() +void SMESHDS_Mesh::compactMesh() { - if ( IsCompacted() ) + if ( isCompacted() ) return; + SMDS_Mesh::compactMesh(); + + int newNodeSize = 0; + int nbNodes = myNodes.size(); + int nbVtkNodes = myGrid->GetNumberOfPoints(); + int nbNodeTemp = Max( nbVtkNodes, nbNodes ); + vector idNodesOldToNew(nbNodeTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + int vtkid = myNodes[i]->getVtkId(); + idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0) + newNodeSize++; + } + } + bool areNodesModified = (newNodeSize != nbVtkNodes); + areNodesModified = true; + + int newCellSize = 0; + int nbCells = myCells.size(); + int nbVtkCells = myGrid->GetNumberOfCells(); + int nbCellTemp = Max( nbVtkCells, nbCells ); + vector idCellsOldToNew(nbCellTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbCells; i++) + { + if (myCells[i]) + { + newCellSize++; + } + } + if (areNodesModified) + myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize); + else + myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize); + + int nbVtkPts = myGrid->GetNumberOfPoints(); + nbVtkCells = myGrid->GetNumberOfCells(); + if (nbVtkPts != newNodeSize) + { + MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize); + if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id + } + if (nbVtkCells != newCellSize) + { + MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize); + if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id + } - SMDS_Mesh::CompactMesh(); + // --- SMDS_MeshNode and myNodes, myNodeIdFactory + + if ( true ) + { + SetOfNodes newNodes(newNodeSize+1,NULL); // 0 not used, SMDS numbers 1..n + int newSmdsId = 0; + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + newSmdsId++; // SMDS id starts from 1 + int oldVtkId = myNodes[i]->getVtkId(); + int newVtkId = idNodesOldToNew[oldVtkId]; + myNodes[i]->setVtkId(newVtkId); + myNodes[i]->setId(newSmdsId); + newNodes[newSmdsId] = myNodes[i]; + } + } + myNodes.swap(newNodes); + this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes + } + + // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells + + int vtkIndexSize = myCellIdVtkToSmds.size(); + for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++) + { + int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId]; + if (oldSmdsId > 0) + { + int newVtkId = idCellsOldToNew[oldVtkId]; + myCells[oldSmdsId]->setVtkId(newVtkId); + } + } + + SetOfCells newCells(newCellSize+1, NULL); // 0 not used, SMDS numbers 1..n + vector newVtkToSmds(newCellSize+1, -1); + + int myCellsSize = myCells.size(); + int newSmdsId = 0; + for (int i = 0; i < myCellsSize; i++) + { + if ( myCells[i] ) + { + newSmdsId++; // SMDS id starts from 1 + assert(newSmdsId <= newCellSize); + newCells[newSmdsId] = myCells[i]; + newCells[newSmdsId]->setId(newSmdsId); + int idvtk = myCells[i]->getVtkId(); + assert(idvtk < newCellSize); + newVtkToSmds[idvtk] = newSmdsId; + } + } + + myCells.swap(newCells); + myCellIdVtkToSmds.swap(newVtkToSmds); + this->myElementIDFactory->emptyPool(newSmdsId); this->myScript->SetModified(true); // notify GUI client for buildPrs when update + + // --- compact list myNodes and myElements in submeshes + + SMESHDS_SubMeshIteratorPtr smIt = SubMeshes(); + while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() )) + sm->compactList(); } void SMESHDS_Mesh::CleanDownWardConnectivity() diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 51baee630..92f631890 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -66,7 +66,7 @@ class DownIdType; class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh { - public: +public: SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode); bool IsEmbeddedMode(); void SetPersistentId(int id); @@ -566,18 +566,18 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector & nodes); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (const std::vector& nodes_ids, - const std::vector& quantities, - const int ID); + (const std::vector& nodes_ids, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (const std::vector& nodes, - const std::vector& quantities, - const int ID); + (const std::vector& nodes, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolume - (const std::vector& nodes, - const std::vector& quantities); + (const std::vector& nodes, + const std::vector& quantities); virtual void MoveNode(const SMDS_MeshNode *, double x, double y, double z); virtual void RemoveNode(const SMDS_MeshNode *); @@ -587,7 +587,7 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh * Methods do not work for meshes with descendants. * Implemented for fast cleaning of meshes. */ - bool RemoveFreeNode (const SMDS_MeshNode *, SMESHDS_SubMesh *, bool fromGroups=true); + void RemoveFreeNode (const SMDS_MeshNode *, SMESHDS_SubMesh *, bool fromGroups=true); void RemoveFreeElement(const SMDS_MeshElement *, SMESHDS_SubMesh *, bool fromGroups=true); void ClearMesh(); @@ -646,13 +646,13 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const; - virtual void CompactMesh(); + virtual void compactMesh(); void CleanDownWardConnectivity(); void BuildDownWardConnectivity(bool withEdges); ~SMESHDS_Mesh(); - private: +private: ShapeToHypothesis myShapeToHypothesis; @@ -665,12 +665,12 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh TopTools_IndexedMapOfShape myIndexToShape; typedef std::set TGroups; - TGroups myGroups; + TGroups myGroups; SMESHDS_Script* myScript; bool myIsEmbeddedMode; - int add( const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ); + bool add( const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ); SMESHDS_SubMesh* getSubmesh( const TopoDS_Shape & shape); }; diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 4a086e3b7..892873016 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -27,12 +27,15 @@ // $Header: // #include "SMESHDS_SubMesh.hxx" - #include "SMESHDS_Mesh.hxx" + +#include "utilities.h" #include "SMDS_SetIterator.hxx" -#include "SMDS_ElementFactory.hxx" +#include +#include + +using namespace std; -#include //================================================================================ /*! @@ -44,8 +47,8 @@ SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index) { myParent = parent; myIndex = index; - myNbElements = 0; - myNbNodes = 0; + myUnusedIdNodes = 0; + myUnusedIdElements = 0; } //================================================================================ @@ -63,16 +66,16 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh() //purpose : //======================================================================= -void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) +void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) { if (!IsComplexSubmesh()) { - if ( elem->GetType() == SMDSAbs_Node ) + if ( ME->GetType() == SMDSAbs_Node ) { - AddNode( static_cast< const SMDS_MeshNode* >( elem )); + AddNode( static_cast< const SMDS_MeshNode* >( ME )); return; } - int oldShapeId = elem->GetShapeID(); + int oldShapeId = ME->getshapeId(); if ( oldShapeId > 0 ) { if (oldShapeId != myIndex) @@ -80,10 +83,28 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) throw SALOME_Exception (LOCALIZED("add element in subshape already belonging to a subshape")); } + int idInSubShape = ME->getIdInShape(); + if (idInSubShape >= 0) + { + MESSAGE("add element in subshape already belonging to that subshape " + << ME->GetID() << " " << oldShapeId << " " << idInSubShape); + // check if ok: do nothing if ok + if (idInSubShape >= (int)myElements.size()) + { + throw SALOME_Exception(LOCALIZED("out of bounds")); + } + if (ME != myElements[idInSubShape]) + { + throw SALOME_Exception(LOCALIZED("not the same element")); + } + return; + } } - elem->setShapeID( myIndex ); - myNbElements++; + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(myIndex); + elem->setIdInShape(myElements.size()); + myElements.push_back(ME); } } @@ -92,17 +113,41 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) //purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem ) +bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted) { - if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex ) + if (!ME) { return false; } - if ( !IsComplexSubmesh() ) + if (!IsComplexSubmesh()) { - elem->setShapeID( 0 ); - myNbElements--; - return true; + if ( ME->getshapeId() != myIndex ) // elem not in a pool can loose it's data already + { + if ( isElemDeleted ) + for ( size_t i = 0; i < myElements.size(); ++i ) + if ( myElements[i] == ME ) + { + myElements[i] = 0; + ++myUnusedIdElements; + return true; + } + return false; + } + int idInSubShape = ME->getIdInShape(); + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(0); + elem->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < (int) myElements.size())) + { + myElements[idInSubShape] = 0; // this vector entry is no more used + if ( ++myUnusedIdElements == (int) myElements.size() ) + { + clearVector( myElements ); + myUnusedIdElements = 0; + } + return true; + } + return false; } return false; } @@ -116,16 +161,22 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) { if ( !IsComplexSubmesh() ) { - const int shapeId = N->getshapeId(); - if ( shapeId > 0 ) + const int idInSubShape = N->getIdInShape(); + const int shapeId = N->getshapeId(); + if ((shapeId > 0) && (idInSubShape >= 0)) { if ( shapeId != myIndex ) throw SALOME_Exception (LOCALIZED("a node being in sub-mesh is added to another sub-mesh")); + if ( idInSubShape >= (int)myNodes.size() || myNodes[ idInSubShape ] != N ) + throw SALOME_Exception + (LOCALIZED("a node with wrong idInSubShape is re-added to the same sub-mesh")); return; // already in } - N->setShapeID( myIndex ); - myNbNodes++; + SMDS_MeshNode* node = (SMDS_MeshNode*)(N); + node->setShapeId(myIndex); + node->setIdInShape(myNodes.size()); + myNodes.push_back(N); } } @@ -134,18 +185,38 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) //purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) +bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted) { - if ( !N || N->getshapeId() != myIndex ) + if (!IsComplexSubmesh()) { + if ( N->getshapeId() != myIndex ) + { + if ( isNodeDeleted ) + for ( size_t i = 0; i < myNodes.size(); ++i ) + if ( myNodes[i] == N ) + { + myNodes[i] = 0; + ++myUnusedIdNodes; + return true; + } + return false; + } + int idInSubShape = N->getIdInShape(); + SMDS_MeshNode* node = (SMDS_MeshNode*) (N); + node->setShapeId(0); + node->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < (int) myNodes.size())) + { + myNodes[idInSubShape] = 0; // this vector entry is no more used + if ( ++myUnusedIdNodes == (int) myNodes.size() ) + { + clearVector( myNodes ); + myUnusedIdNodes = 0; + } + return true; + } return false; } - if ( !IsComplexSubmesh() ) - { - N->setShapeID( 0 ); - myNbNodes--; - return true; - } return false; } @@ -157,10 +228,10 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) int SMESHDS_SubMesh::NbElements() const { if ( !IsComplexSubmesh() ) - return myNbElements; + return myElements.size() - myUnusedIdElements; int nbElems = 0; - TSubMeshSet::const_iterator it = mySubMeshes.begin(); + set::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbElements(); @@ -175,10 +246,10 @@ int SMESHDS_SubMesh::NbElements() const int SMESHDS_SubMesh::NbNodes() const { if ( !IsComplexSubmesh() ) - return myNbNodes; + return myNodes.size() - myUnusedIdNodes; int nbElems = 0; - TSubMeshSet::const_iterator it = mySubMeshes.begin(); + set::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbNodes(); @@ -235,7 +306,7 @@ public: template class MyIterator : public SMDS_Iterator { public: - MyIterator (const TSubMeshSet& theSubMeshes) + MyIterator (const set& theSubMeshes) : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ) {} bool more() @@ -260,9 +331,9 @@ protected: getElements(const SMESHDS_SubMesh*) const = 0; private: - bool myMore; - TSubMeshSet::const_iterator mySubIt, mySubEnd; - boost::shared_ptr< SMDS_Iterator > myElemIt; + bool myMore; + set::const_iterator mySubIt, mySubEnd; + boost::shared_ptr< SMDS_Iterator > myElemIt; }; // ===================== @@ -272,7 +343,7 @@ private: class MyElemIterator: public MyIterator { public: - MyElemIterator (const TSubMeshSet& theSubMeshes) + MyElemIterator (const set& theSubMeshes) :MyIterator( theSubMeshes ) {} SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const { return theSubMesh->GetElements(); } @@ -285,7 +356,7 @@ public: class MyNodeIterator: public MyIterator { public: - MyNodeIterator (const TSubMeshSet& theSubMeshes) + MyNodeIterator (const set& theSubMeshes) :MyIterator( theSubMeshes ) {} SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const { return theSubMesh->GetNodes(); } @@ -296,12 +367,13 @@ public: //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const +SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements( bool reverse ) const { if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - return myParent->shapeElementsIterator( myIndex, myNbElements ); + typedef MySetIterator< const SMDS_MeshElement*, std::vector > TIter; + return SMDS_ElemIteratorPtr( new TIter( myElements, reverse )); } //======================================================================= @@ -309,12 +381,13 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const //purpose : //======================================================================= -SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const +SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes( bool reverse ) const { if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return myParent->shapeNodesIterator( myIndex, myNbNodes ); + typedef MySetIterator< const SMDS_MeshNode*, std::vector > TIter; + return SMDS_NodeIteratorPtr( new TIter( myNodes, reverse )); } //======================================================================= @@ -324,18 +397,35 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const { - if ( !ME || ME->IsNull() ) + // DO NOT TRY TO FIND A REMOVED ELEMENT !! + //if ( IsComplexSubmesh() || !ME ) + if (!ME) return false; if ( IsComplexSubmesh() ) { - TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin(); + set::const_iterator aSubIt = mySubMeshes.begin(); for (; aSubIt != mySubMeshes.end(); aSubIt++) if ((*aSubIt)->Contains(ME)) return true; return false; } - return ME->getshapeId() == myIndex; + + if (ME->GetType() == SMDSAbs_Node) + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < (int) myNodes.size())) + if (myNodes[idInShape] == ME) + return true; + } + else + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < (int) myElements.size())) + if (myElements[idInShape] == ME) + return true; + } + return false; } //======================================================================= @@ -347,18 +437,18 @@ bool SMESHDS_SubMesh::IsQuadratic() const { if ( IsComplexSubmesh() ) { - TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin(); + set::const_iterator aSubIt = mySubMeshes.begin(); for (; aSubIt != mySubMeshes.end(); aSubIt++) if ((*aSubIt)->IsQuadratic()) return true; return false; } - if ( myNbElements == 0 ) - return false; + for ( size_t i = 0; i < myElements.size(); ++i ) + if ( myElements[i] ) + return myElements[i]->IsQuadratic(); - SMDS_ElemIteratorPtr it = GetElements(); - return it->more() && it->next()->IsQuadratic(); + return false; } //======================================================================= @@ -409,8 +499,10 @@ bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const { - typedef SMDS_SetIterator< const SMESHDS_SubMesh*, TSubMeshSet::const_iterator > TIterator; - return boost::make_shared< TIterator >( mySubMeshes.begin(), mySubMeshes.end()); + typedef set::const_iterator TIterator; + return SMESHDS_SubMeshIteratorPtr + ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(), + mySubMeshes.end())); } //======================================================================= @@ -422,22 +514,26 @@ void SMESHDS_SubMesh::Clear() { if ( myParent && myParent->NbNodes() > 0 ) { - if ( myNbElements > 0 ) - for ( SMDS_ElemIteratorPtr it = GetElements(); it->more(); ) - { - const SMDS_MeshElement * elem = it->next(); - elem->setShapeID( 0 ); - } - if ( myNbNodes > 0 ) - for ( SMDS_NodeIteratorPtr it = GetNodes(); it->more(); ) - { - const SMDS_MeshNode * elem = it->next(); - elem->setShapeID( 0 ); - } + for ( size_t i = 0; i < myElements.size(); ++i ) + { + if ( myElements[i] && + myElements[i]->GetID() > 0 && + myElements[i] == myParent->FindElement( myElements[i]->GetID() )) // not deleted + const_cast< SMDS_MeshElement* >( myElements[i] )->setShapeId( 0 ); + } + for ( size_t i = 0; i < myNodes.size(); ++i ) + { + if ( myNodes[i] && + myNodes[i]->GetID() > 0 && + myNodes[i] == myParent->FindNode( myNodes[i]->GetID() )) // not deleted + const_cast< SMDS_MeshNode* >( myNodes[i] )->setShapeId( 0 ); + } } - myNbElements = 0; - myNbNodes = 0; + clearVector( myElements ); + clearVector( myNodes ); + myUnusedIdNodes = 0; + myUnusedIdElements = 0; if ( NbSubMeshes() > 0 ) { SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator(); @@ -447,3 +543,71 @@ void SMESHDS_SubMesh::Clear() } } } + +int SMESHDS_SubMesh::getSize() +{ + int c = NbNodes(); + int d = NbElements(); + return c+d; +} + +void SMESHDS_SubMesh::compactList() +{ + if ( myUnusedIdElements > 0 ) + { + std::vector newElems; + newElems.reserve( myElements.size() - myUnusedIdElements ); + for ( size_t i = 0; i < myElements.size(); i++) + if ( myElements[i] ) + { + SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i]; + elem->setIdInShape( newElems.size() ); + newElems.push_back( elem ); + } + myElements.swap(newElems); + myUnusedIdElements = 0; + } + else + { + std::vector( myElements ).swap( myElements ); + } + + if ( myUnusedIdNodes > 0 ) + { + std::vector newNodes; + newNodes.reserve( myNodes.size() - myUnusedIdNodes ); + for ( size_t i = 0; i < myNodes.size(); i++ ) + if ( myNodes[i] ) + { + SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i]; + node->setIdInShape( newNodes.size() ); + newNodes.push_back( node ); + } + myNodes.swap(newNodes); + myUnusedIdNodes = 0; + } + else + { + std::vector( myNodes ).swap( myNodes ); + } +} + +//======================================================================= +//function : GetElement +//purpose : Return an element by its IdInShape +//======================================================================= + +const SMDS_MeshElement* SMESHDS_SubMesh::GetElement( size_t idInShape ) const +{ + return ( !IsComplexSubmesh() && idInShape < myElements.size() ) ? myElements[idInShape] : 0; +} + +//======================================================================= +//function : GetElement +//purpose : Return a node by its IdInShape +//======================================================================= + +const SMDS_MeshNode* SMESHDS_SubMesh::GetNode( size_t idInShape ) const +{ + return ( !IsComplexSubmesh() && idInShape < myNodes.size() ) ? myNodes[idInShape] : 0; +} diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index 2caffb10b..9a9d61f63 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -30,12 +30,9 @@ #include "SMESH_SMESHDS.hxx" #include "SMDS_Mesh.hxx" +#include #include -#include -class SMESHDS_SubMesh; -typedef boost::container::flat_set< const SMESHDS_SubMesh* > TSubMeshSet; - class SMESHDS_SubMesh; typedef SMDS_Iterator SMESHDS_SubMeshIterator; typedef boost::shared_ptr< SMESHDS_SubMeshIterator > SMESHDS_SubMeshIteratorPtr; @@ -52,11 +49,11 @@ class SMESHDS_EXPORT SMESHDS_SubMesh // if !IsComplexSubmesh() virtual void AddElement(const SMDS_MeshElement * ME); - virtual bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in + virtual bool RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted); // ret true if ME was in virtual void AddNode(const SMDS_MeshNode * ME); - virtual bool RemoveNode(const SMDS_MeshNode * ME); // ret true if ME was in - //virtual const SMDS_MeshElement* GetElement( size_t idInShape ) const; - //virtual const SMDS_MeshNode* GetNode ( size_t idInShape ) const; + virtual bool RemoveNode(const SMDS_MeshNode * ME, bool isNodeDeleted); // ret true if ME was in + virtual const SMDS_MeshElement* GetElement( size_t idInShape ) const; + virtual const SMDS_MeshNode* GetNode ( size_t idInShape ) const; // if IsComplexSubmesh() void AddSubMesh( const SMESHDS_SubMesh* theSubMesh ); @@ -68,25 +65,29 @@ class SMESHDS_EXPORT SMESHDS_SubMesh // for both types virtual int NbElements() const; + virtual SMDS_ElemIteratorPtr GetElements(bool reverse=false) const; virtual int NbNodes() const; - virtual SMDS_ElemIteratorPtr GetElements() const; - virtual SMDS_NodeIteratorPtr GetNodes() const; + virtual SMDS_NodeIteratorPtr GetNodes(bool reverse=false) const; virtual bool Contains(const SMDS_MeshElement * ME) const; // check if elem or node is in virtual bool IsQuadratic() const; // clear the contents virtual void Clear(); + int getSize(); + void compactList(); SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); } int GetID() const { return myIndex; } private: + SMESHDS_Mesh * myParent; + std::vector myElements; + std::vector myNodes; - int myIndex; - int myNbElements; - int myNbNodes; - SMESHDS_Mesh * myParent; - TSubMeshSet mySubMeshes; + int myUnusedIdNodes; + int myUnusedIdElements; + int myIndex; + std::set mySubMeshes; }; #endif diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index 0491cfef9..30ab3e6d0 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -1289,7 +1289,7 @@ void SMESHGUI_ExtrusionDlg::ClickOnHelp() #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", + arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)). arg(myHelpFileName)); } @@ -1323,7 +1323,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() return; const SMDS_MeshFace* face = - aMesh->DownCast< SMDS_MeshFace >(aMesh->FindElement(aMapIndex(1))); + dynamic_cast(aMesh->FindElement(aMapIndex(1))); if (!face) return; diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 7b9f4974f..4f9b3cce3 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -1426,8 +1426,8 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() aGroupMainShape = aGeomGroup; aGroupMainShape->Register(); } - CORBA::String_var entry = aGroupMainShape->GetStudyEntry(); - _PTR(SObject) aGroupMainShapeSO = aStudy->FindObjectID( entry.in() ); + _PTR(SObject) aGroupMainShapeSO = + aStudy->FindObjectID(aGroupMainShape->GetStudyEntry()); _PTR(SObject) anObj, aRef; bool isRefOrSubShape = false; @@ -1451,10 +1451,10 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() myGeomObjects->length(i); if ( i == 0 ) - { - myIsBusy = false; - return; - } + { + myIsBusy = false; + return; + } aNbSel = i; } @@ -2453,9 +2453,9 @@ void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op) GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape(); if ( !aGeomVar->_is_nil() ) { - CORBA::String_var ID = aGeomVar->GetStudyEntry(); - _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - if ( _PTR(SObject) aGeomSO = aStudy->FindObjectID( ID.in() )) { + QString ID = aGeomVar->GetStudyEntry(); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if ( _PTR(SObject) aGeomSO = aStudy->FindObjectID( ID.toLatin1().data() )) { SALOME_ListIO anIOList; Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() ); diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 57bd8236d..03e542d6a 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -1121,7 +1121,7 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* */ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element ) { - gp_XYZ n = SMESH::getNormale( SMDS_Mesh::DownCast( element )); + gp_XYZ n = SMESH::getNormale( dynamic_cast( element )); return XYZ(n.X(), n.Y(), n.Z()); } @@ -1397,7 +1397,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) { myInfo->append( QString( "%1? %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) ); } - if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast( e )) { + if ( const SMDS_BallElement* ball = dynamic_cast( e )) { // Ball diameter myInfo->append( QString( "%1: %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() )); } @@ -1915,7 +1915,7 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) case SMDSEntity_Polyhedra: case SMDSEntity_Quad_Polyhedra: gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: + default: break; } if ( !gtype.isEmpty() ) { @@ -1930,7 +1930,7 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" )); quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )); } - if ( const SMDS_BallElement* ball = SMDS_Mesh::DownCast< SMDS_BallElement >( e )) { + if ( const SMDS_BallElement* ball = dynamic_cast( e )) { // ball diameter QTreeWidgetItem* diamItem = createItem( elemItem, Bold ); diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )); @@ -1949,14 +1949,12 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) } } else { - SMDS_NodeIteratorPtr nodeIt = e->nodeIterator(); - std::set< const SMDS_MeshNode* > addedNodes; + const SMDS_VtkVolume* aVtkVolume = dynamic_cast(e); + SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator(); QList uniqueNodes; - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = nodeIt->next(); - if ( addedNodes.insert( node ).second ) - uniqueNodes.append( nodeIt->next() ); - } + while ( nodeIt->more() ) + uniqueNodes.append( nodeIt->next() ); + SMDS_VolumeTool vtool( e ); const int nbFaces = vtool.NbFaces(); for( int face_id = 0; face_id < nbFaces; face_id++ ) { @@ -1965,10 +1963,10 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) faceItem->setExpanded( true ); const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id ); - const int nbNodes = vtool.NbFaceNodes ( face_id ); + const int nbNodes = vtool.NbFaceNodes( face_id ); for( int node_id = 0; node_id < nbNodes; node_id++ ) { const SMDS_MeshNode* node = aNodeIds[node_id]; - nodeInfo( node, uniqueNodes.indexOf(node) + 1, uniqueNodes.size(), faceItem ); + nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem ); } } } diff --git a/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx b/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx index 1aa8e927e..5b350d06e 100644 --- a/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx +++ b/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx @@ -98,7 +98,7 @@ bool SMESHGUI_PreVisualObj::IsValid() const vtkUnstructuredGrid* SMESHGUI_PreVisualObj::GetUnstructuredGrid() { - return myMesh->GetGrid(); + return myMesh->getGrid(); } @@ -116,13 +116,13 @@ vtkIdType SMESHGUI_PreVisualObj::GetNodeVTKId( int theObjID ) vtkIdType SMESHGUI_PreVisualObj::GetElemObjId( int theVTKID ) { - return this->GetMesh()->FromVtkToSmds(theVTKID); + return this->GetMesh()->fromVtkToSmds(theVTKID); } vtkIdType SMESHGUI_PreVisualObj::GetElemVTKId( int theObjID ) { const SMDS_MeshElement* e = myMesh->FindElement(theObjID); - return e ? e->GetVtkID() : -1; + return e ? e->getVtkId() : -1; } void SMESHGUI_PreVisualObj::ClearEntitiesFlags() diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx index 9e7554e1e..33787322d 100644 --- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx @@ -641,7 +641,7 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument() else if ( isFaceSelected ) { const SMDS_MeshFace* face = - SMDS_Mesh::DownCast( aMesh->FindElement( aMapIndex( 1 ))); + dynamic_cast(aMesh->FindElement(aMapIndex(1))); if (!face) return; gp_XYZ aNormale = SMESH::getNormale(face); diff --git a/src/SMESHUtils/SMESH_ComputeError.hxx b/src/SMESHUtils/SMESH_ComputeError.hxx index cf78362b2..4055741ff 100644 --- a/src/SMESHUtils/SMESH_ComputeError.hxx +++ b/src/SMESHUtils/SMESH_ComputeError.hxx @@ -25,7 +25,6 @@ #define SMESH_ComputeError_HeaderFile #include "SMESH_Utils.hxx" -#include "SMDS_ElementHolder.hxx" #include #include @@ -76,20 +75,22 @@ struct SMESHUtils_EXPORT SMESH_ComputeError std::string myComment; const SMESH_Algo* myAlgo; + std::list myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH + static SMESH_ComputeErrorPtr New( int error = COMPERR_OK, std::string comment = "", const SMESH_Algo* algo = 0) { return SMESH_ComputeErrorPtr( new SMESH_ComputeError( error, comment, algo )); } - SMESH_ComputeError( int error = COMPERR_OK, - std::string comment = "", - const SMESH_Algo* algo = 0) - : myName(error), myComment(comment), myAlgo(algo) {} + SMESH_ComputeError(int error = COMPERR_OK, + std::string comment = "", + const SMESH_Algo* algo = 0) + :myName(error),myComment(comment),myAlgo(algo) {} bool IsOK() const { return myName == COMPERR_OK; } bool IsKO() const { return myName != COMPERR_OK && myName != COMPERR_WARNING; } bool IsCommon() const { return myName < 0 && myName > COMPERR_LAST_ALGO_ERROR; } - virtual bool HasBadElems() const { return false; } + bool HasBadElems() const { return !myBadElements.empty(); } // not inline methods are implemented in src/SMESHUtils/SMESH_TryCatch.cxx @@ -99,31 +100,6 @@ struct SMESHUtils_EXPORT SMESH_ComputeError // Return the most severe error static SMESH_ComputeErrorPtr Worst( SMESH_ComputeErrorPtr er1, SMESH_ComputeErrorPtr er2 ); - - virtual ~SMESH_ComputeError() {} -}; - -struct SMESHUtils_EXPORT SMESH_BadInputElements : public SMESH_ComputeError, SMDS_ElementHolder -{ - typedef std::list TElemList; - TElemList myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH - - SMESH_BadInputElements(const SMDS_Mesh* mesh, - int error = COMPERR_OK, - std::string comment = "", - const SMESH_Algo* algo = 0) - :SMESH_ComputeError(error, comment ,algo), SMDS_ElementHolder(mesh) {} - - const SMDS_Mesh* GetMesh() const { return myMesh; } - const TElemList& GetElements() { return myBadElements; } - - virtual bool HasBadElems() const { return !myBadElements.empty(); } - - // methods of SMDS_ElementHolder - virtual SMDS_ElemIteratorPtr getElements(); - virtual void tmpClear(); - virtual void add( const SMDS_MeshElement* element ); - virtual void compact() { } }; #endif diff --git a/src/SMESHUtils/SMESH_FillHole.cxx b/src/SMESHUtils/SMESH_FillHole.cxx index cc724d3ce..ee22ef944 100644 --- a/src/SMESHUtils/SMESH_FillHole.cxx +++ b/src/SMESHUtils/SMESH_FillHole.cxx @@ -28,9 +28,8 @@ #include "SMESH_Comment.hxx" -#include "ObjectPool.hxx" -#include "SMDS_Mesh.hxx" #include "SMESH_TypeDefs.hxx" +#include "SMDS_Mesh.hxx" #include diff --git a/src/SMESHUtils/SMESH_FreeBorders.cxx b/src/SMESHUtils/SMESH_FreeBorders.cxx index 2793d4cda..d09860465 100644 --- a/src/SMESHUtils/SMESH_FreeBorders.cxx +++ b/src/SMESHUtils/SMESH_FreeBorders.cxx @@ -92,7 +92,7 @@ namespace myNodes[0] = node1->Node(); myNodes[1] = node2->Node(); myFace = face; - setID( ID ); // mesh element ID + setId( ID ); // mesh element ID } bool IsInGroup() const { diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index c953da515..646fb7bff 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -28,7 +28,6 @@ #include "SMESH_MeshAlgos.hxx" -#include "ObjectPool.hxx" #include "SMDS_FaceOfNodes.hxx" #include "SMDS_LinearEdge.hxx" #include "SMDS_Mesh.hxx" @@ -70,7 +69,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher TIDSortedNodeSet nodes; if ( theMesh ) { - SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(); + SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) nodes.insert( nodes.end(), nIt->next() ); } @@ -1293,7 +1292,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin std::vector< SMESH_TNodeXYZ > xyz; xyz.reserve( element->NbNodes()+1 ); - SMDS_NodeIteratorPtr nodeIt = element->interlacedNodesIterator(); + SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator(); for ( int i = 0; nodeIt->more(); ++i ) xyz.push_back( SMESH_TNodeXYZ( nodeIt->next() )); @@ -1529,11 +1528,11 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem, switch ( elem->GetType() ) { case SMDSAbs_Volume: - return GetDistance( static_cast( elem ), point, closestPnt ); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Face: - return GetDistance( static_cast( elem ), point, closestPnt ); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Edge: - return GetDistance( static_cast( elem ), point, closestPnt ); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Node: if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem ); return point.Distance( SMESH_TNodeXYZ( elem )); @@ -1665,8 +1664,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, int i = 0, nbNodes = seg->NbNodes(); std::vector< SMESH_TNodeXYZ > xyz( nbNodes ); - for ( SMDS_NodeIteratorPtr nodeIt = seg->interlacedNodesIterator(); nodeIt->more(); i++ ) - xyz[ i ].Set( nodeIt->next() ); + SMDS_ElemIteratorPtr nodeIt = seg->interlacedNodesElemIterator(); + while ( nodeIt->more() ) + xyz[ i++ ].Set( nodeIt->next() ); for ( i = 1; i < nbNodes; ++i ) { @@ -1836,7 +1836,7 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode* n1, if ( !face && elem->IsQuadratic()) { // analysis for quadratic elements using all nodes - SMDS_NodeIteratorPtr anIter = elem->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = elem->interlacedNodesElemIterator(); const SMDS_MeshNode* prevN = static_cast( anIter->next() ); for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ ) { diff --git a/src/SMESHUtils/SMESH_TryCatch.cxx b/src/SMESHUtils/SMESH_TryCatch.cxx index b026cdd6b..71e587caa 100644 --- a/src/SMESHUtils/SMESH_TryCatch.cxx +++ b/src/SMESHUtils/SMESH_TryCatch.cxx @@ -39,10 +39,7 @@ const char* SMESH::returnError(const char* txt) } // ------------------------------------------------------------------ - #include "SMESH_ComputeError.hxx" -#include "SMDS_SetIterator.hxx" -#include #define _case2char(err) case err: return #err; @@ -81,31 +78,11 @@ SMESH_ComputeErrorPtr SMESH_ComputeError::Worst( SMESH_ComputeErrorPtr er1, if ( !er1->IsKO() ) return er2; if ( !er2->IsKO() ) return er1; // both KO - bool hasInfo1 = er1->myComment.size() || er1->HasBadElems(); - bool hasInfo2 = er2->myComment.size() || er2->HasBadElems(); + bool hasInfo1 = er1->myComment.size() || !er1->myBadElements.empty(); + bool hasInfo2 = er2->myComment.size() || !er2->myBadElements.empty(); if ( er1->myName == er2->myName || hasInfo1 != hasInfo2 ) return hasInfo1 < hasInfo2 ? er2 : er1; return er1->myName == COMPERR_CANCELED ? er2 : er1; } - -// Return bad elements -SMDS_ElemIteratorPtr SMESH_BadInputElements::getElements() -{ - typedef SMDS_SetIterator< const SMDS_MeshElement*, - std::list< const SMDS_MeshElement* >::const_iterator> TIterator; - return boost::make_shared< TIterator >( myBadElements.begin(), myBadElements.end() ); -} - -// Temporary remove its elements before the mesh compacting -void SMESH_BadInputElements::tmpClear() -{ - myBadElements.clear(); -} - -// Re-add elements after the mesh compacting -void SMESH_BadInputElements::add( const SMDS_MeshElement* element ) -{ - myBadElements.push_back( element ); -} diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index ea45c41ce..2e11e27e5 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -85,6 +85,7 @@ #include "MED_Factory.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_VertexPosition.hxx" @@ -1638,7 +1639,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr else { errStruct.algoName = error->myAlgo->GetName(); } - errStruct.hasBadMesh = error->HasBadElems(); + errStruct.hasBadMesh = !error->myBadElements.empty(); } } error_array->length( nbErr ); @@ -1680,7 +1681,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, { // compute error SMESH_ComputeErrorPtr error = sm->GetComputeError(); - if ( error && error->HasBadElems() ) + if ( error && !error->myBadElements.empty()) { typedef map TNode2LocalIDMap; typedef TNode2LocalIDMap::iterator TNodeLocalID; @@ -1690,10 +1691,8 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, list< TNodeLocalID > connectivity; int i, nbElements = 0, nbConnNodes = 0; - const list& badElems = - static_cast( error.get() )->myBadElements; - list::const_iterator elemIt = badElems.begin(); - list::const_iterator elemEnd = badElems.end(); + list::iterator elemIt = error->myBadElements.begin(); + list::iterator elemEnd = error->myBadElements.end(); for ( ; elemIt != elemEnd; ++elemIt, ++nbElements ) { SMDS_ElemIteratorPtr nIt = (*elemIt)->nodesIterator(); @@ -1720,7 +1719,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, } // fill element types result->elementTypes.length( nbElements ); - for ( i = 0, elemIt = badElems.begin(); i myBadElements.begin(); i elementTypes[i].SMDS_ElementType = (SMESH::ElementType) elem->GetType(); @@ -3127,9 +3126,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( !myHyp->_is_nil() ) { SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); if ( myImpl ) { - CORBA::String_var hn = myHyp->GetName(), ln = myHyp->GetLibName(); - std::string hypname = hn.in(); - std::string libname = ln.in(); + string hypname = string( myHyp->GetName() ); + string libname = string( myHyp->GetLibName() ); // BUG SWP13062 // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for // WIN32 and ".so" for X-system) must be deleted @@ -3141,13 +3139,13 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); + //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif - CORBA::String_var objStr = GetORB()->object_to_string( anObject ); - CORBA::String_var hypdata = myImpl->SaveTo(); - int id = myStudyContext->findId( string( objStr.in() )); + CORBA::String_var objStr = GetORB()->object_to_string( anObject ); + int id = myStudyContext->findId( string( objStr.in() ) ); + string hypdata = string( myImpl->SaveTo() ); // for each hypothesis create HDF group basing on its id char hypGrpName[30]; @@ -3167,10 +3165,10 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); aDataset->CloseOnDisk(); // --> persistent data of hypothesis - aSize[ 0 ] = strlen( hypdata.in() ) + 1; + aSize[ 0 ] = hypdata.length() + 1; aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( hypdata.in() ) ); + aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); aDataset->CloseOnDisk(); // close hypothesis HDF group aGroup->CloseOnDisk(); @@ -3197,9 +3195,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( !myHyp->_is_nil() ) { SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); if ( myImpl ) { - CORBA::String_var hn = myHyp->GetName(), ln = myHyp->GetLibName(); - std::string hypname = hn.in(); - std::string libname = ln.in(); + string hypname = string( myHyp->GetName() ); + string libname = string( myHyp->GetLibName() ); // BUG SWP13062 // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for // WIN32 and ".so" for X-system) must be deleted @@ -3211,13 +3208,13 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); + //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif - CORBA::String_var objStr = GetORB()->object_to_string( anObject ); - CORBA::String_var hypdata = myImpl->SaveTo(); - int id = myStudyContext->findId( string( objStr.in() ) ); + CORBA::String_var objStr = GetORB()->object_to_string( anObject ); + int id = myStudyContext->findId( string( objStr.in() ) ); + string hypdata = string( myImpl->SaveTo() ); // for each algorithm create HDF group basing on its id char hypGrpName[30]; @@ -3237,10 +3234,10 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); aDataset->CloseOnDisk(); // --> persistent data of algorithm - aSize[0] = strlen( hypdata.in() ) + 1; + aSize[0] = hypdata.length() + 1; aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( hypdata.in() )); + aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); aDataset->CloseOnDisk(); // close algorithm HDF group aGroup->CloseOnDisk(); @@ -3322,14 +3319,13 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, SALOMEDS::SObject_wrap myShape; bool ok = myRef->ReferencedObject( myShape.inout() ); if ( ok ) { - CORBA::Object_var shapeObj = myShape->GetObject(); - shapeRefFound = (! CORBA::is_nil( shapeObj )); - CORBA::String_var myRefOnObject = myShape->GetID(); - if ( shapeRefFound && myRefOnObject.in()[0] ) { - aSize[ 0 ] = strlen( myRefOnObject.in() ) + 1; + shapeRefFound = (! CORBA::is_nil( myShape->GetObject() )); + string myRefOnObject = myShape->GetID(); + if ( shapeRefFound && myRefOnObject.length() > 0 ) { + aSize[ 0 ] = myRefOnObject.length() + 1; aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.in() ) ); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); aDataset->CloseOnDisk(); } } @@ -3338,7 +3334,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // write applied hypotheses if exist SALOMEDS::SObject_wrap myHypBranch; found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() ); - if ( found && !shapeRefFound && hasShape ) { // remove applied hyps + if ( found && !shapeRefFound && hasShape) { // remove applied hyps myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch ); } if ( found && (shapeRefFound || !hasShape) ) { @@ -3675,8 +3671,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // For each group, create a dataset named "Group " // and store the group's user name into it - const char* grpName = aGrpBaseDS->GetStoreName(); - CORBA::String_var aUserName = myGroupImpl->GetName(); + const char* grpName = aGrpBaseDS->GetStoreName(); + char* aUserName = myGroupImpl->GetName(); aSize[ 0 ] = strlen( aUserName ) + 1; aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); @@ -3714,14 +3710,14 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, mySubRef->ReferencedObject( myShape.inout() ) && !CORBA::is_nil( myShape->GetObject() )) { - CORBA::String_var myRefOnObject = myShape->GetID(); - if ( myRefOnObject.in()[0] ) { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { char aRefName[ 30 ]; sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = strlen( myRefOnObject.in() ) + 1; + aSize[ 0 ] = myRefOnObject.length() + 1; aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.in() )); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); aDataset->CloseOnDisk(); } } @@ -3869,7 +3865,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // Position const SMDS_PositionPtr pos = node->GetPosition(); if ( onFace ) { // on FACE - SMDS_FacePositionPtr fPos = pos; + const SMDS_FacePosition* fPos = + dynamic_cast( pos ); if ( fPos ) { aUPos[ iNode ] = fPos->GetUParameter(); aVPos[ iNode ] = fPos->GetVParameter(); @@ -3879,7 +3876,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, nbNodes--; } else { // on EDGE - SMDS_EdgePositionPtr ePos = pos; + const SMDS_EdgePosition* ePos = + dynamic_cast( pos ); if ( ePos ) { aUPos[ iNode ] = ePos->GetUParameter(); iNode++; @@ -4560,7 +4558,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myStudyContext->mapOldToNew( subid, newSubId ); } } - delete [] refFromFile; } if ( aSubMesh->_is_nil() ) @@ -4595,7 +4592,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp ); } } - delete [] refFromFile; } } // close "applied algorithms" HDF group @@ -4631,7 +4627,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp ); } } - delete [] refFromFile; } } // close "APPLIED HYPOTHESES" hdf group @@ -4713,7 +4708,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aShape = GeomObjectToShape( aShapeObject ); } } - delete [] refFromFile; } // Try to read a filter of SMESH_GroupOnFilter SMESH::Filter_var filter; @@ -4732,14 +4726,12 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); filters.push_back( filter ); } - delete [] persistStr; } // Create group servant SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1); SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) ); - delete [] nameFromFile; // Obtain a SMESHDS_Group object if ( aNewGroup->_is_nil() ) continue; @@ -4778,7 +4770,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); aGroupBaseDS->SetColor( aColor ); - delete [] anRGB; } } } @@ -4796,7 +4787,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // read Sub-Mesh ORDER if any - if ( aTopGroup->ExistInternalObject( "Mesh Order" )) { + if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { aDataset = new HDFdataset( "Mesh Order", aTopGroup ); aDataset->OpenOnDisk(); size = aDataset->GetSize(); @@ -4812,7 +4803,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, anOrderIds.back().push_back(smIDs[ i ]); myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); - delete [] smIDs; } } // loop on meshes diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx index 2fcac5a7f..ca0103c01 100644 --- a/src/SMESH_I/SMESH_Measurements_i.cxx +++ b/src/SMESH_I/SMESH_Measurements_i.cxx @@ -255,13 +255,16 @@ static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure); else { - if ( const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] )) - for (SMDS_NodeIteratorPtr aNodeIter = elem->nodeIterator(); aNodeIter->more(); ) - enlargeBoundingBox( aNodeIter->next(), theMeasure); + const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] ); + if (!elem) + continue; + SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator(); + while( aNodeIter->more() ) + enlargeBoundingBox( dynamic_cast( aNodeIter->next() ), theMeasure); } } } - + //======================================================================= // name : BoundingBox // Purpose : compute common bounding box of entities diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 2bd604063..d7afbed39 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -42,6 +42,7 @@ #include "SMDS_Mesh0DElement.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Group.hxx" @@ -533,9 +534,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() SMESHDS_Mesh* aMeshDS; std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS; if ( hasBadElems ) { - const list& badElems = - static_cast( getEditor().GetError().get() )->myBadElements; - aMeshPartDS.reset( new SMESH_MeshPartDS( badElems )); + aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements )); aMeshDS = aMeshPartDS.get(); } else { @@ -681,7 +680,7 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError() errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0 errOut->comment = errIn->myComment.c_str(); errOut->subShapeID = -1; - errOut->hasBadMesh = errIn->HasBadElems(); + errOut->hasBadMesh = !errIn->myBadElements.empty(); } else { @@ -6964,7 +6963,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, // group of boundary elements SMESH_Group* smesh_group = 0; SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face; - if ( strlen( groupName )) + if ( strlen(groupName) ) { SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 ); group_var = mesh_i->CreateGroup( groupType, groupName ); diff --git a/src/SMESH_I/SMESH_MeshPartDS.hxx b/src/SMESH_I/SMESH_MeshPartDS.hxx index 4c81674a2..986ee3c06 100644 --- a/src/SMESH_I/SMESH_MeshPartDS.hxx +++ b/src/SMESH_I/SMESH_MeshPartDS.hxx @@ -47,10 +47,10 @@ public: SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart); SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & badElems ); - virtual SMDS_NodeIteratorPtr nodesIterator () const; - virtual SMDS_EdgeIteratorPtr edgesIterator () const; - virtual SMDS_FaceIteratorPtr facesIterator () const; - virtual SMDS_VolumeIteratorPtr volumesIterator() const; + virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; @@ -61,6 +61,24 @@ public: private: TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ]; SMESHDS_Mesh* _meshDS; + /*! + * \brief Class used to access to protected data of SMDS_MeshInfo + */ + struct TMeshInfo : public SMDS_MeshInfo + { + void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } + }; + /*! + * \brief Element holing its ID only + */ + struct TElemID : public SMDS_MeshElement + { + TElemID(int ID) : SMDS_MeshElement( ID ) {} + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_All; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; } + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_NONE; } + virtual vtkIdType GetVtkType() const { return -1; } + }; }; #endif diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index f97541aef..a170d36d5 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -29,14 +29,12 @@ #include "DriverMED_W_Field.h" #include "DriverMED_W_SMESHDS_Mesh.h" #include "MED_Factory.hxx" -#include "SMDS_LinearEdge.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_ElemIterator.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshGroup.hxx" #include "SMDS_SetIterator.hxx" -#include "SMDS_StdIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" @@ -1104,8 +1102,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup return; vector nodeIds; // to remove nodes becoming free - bool isNodal = ( theGroup->GetType() == SMESH::NODE ); - if ( !isNodal && !theGroup->IsEmpty() ) + if ( !theGroup->IsEmpty() ) { CORBA::Long elemID = theGroup->GetID( 1 ); int nbElemNodes = GetElemNbNodes( elemID ); @@ -1113,44 +1110,36 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup nodeIds.reserve( theGroup->Size() * nbElemNodes ); } - // Retrieve contents + // Remove contents SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup ); SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() ); - SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd; - std::vector< const SMDS_MeshElement* > elems( theGroup->Size() ); - elems.assign( elemBeg, elemEnd ); - - TPythonDump pyDump; // Suppress dump from RemoveGroup() - - // Remove group - RemoveGroup( theGroup ); - - // Remove contents - for ( size_t i = 0; i < elems.size(); ++i ) + while ( elemIt->more() ) { - if ( !isNodal ) - { - for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); ) - nodeIds.push_back( nIt->next()->GetID() ); + const SMDS_MeshElement* e = elemIt->next(); - _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 ); - } - else - { - _impl->GetMeshDS()->RemoveElement( elems[i] ); - } + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + nodeIds.push_back( nIt->next()->GetID() ); + + _impl->GetMeshDS()->RemoveElement( e ); } // Remove free nodes - for ( size_t i = 0 ; i < nodeIds.size(); ++i ) - if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] )) - if ( n->NbInverseElements() == 0 ) - _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 ); + if ( theGroup->GetType() != SMESH::NODE ) + for ( size_t i = 0 ; i < nodeIds.size(); ++i ) + if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] )) + if ( n->NbInverseElements() == 0 ) + _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 ); + + TPythonDump pyDump; // Suppress dump from RemoveGroup() // Update Python script (theGroup must be alive for this) pyDump << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroupWithContents( " << theGroup << " )"; + // Remove group + RemoveGroup( theGroup ); + SMESH_CATCH( SMESH::throwCorbaException ); } @@ -2563,7 +2552,7 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType const SMESH_PredicatePtr& thePredicate ) { std::string newName; - if ( !theName || !theName[0] ) + if ( !theName || strlen( theName ) == 0 ) { std::set< std::string > presentNames; std::map::const_iterator i_gr = _mapGroups.begin(); @@ -4110,14 +4099,14 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + if ( aSMESHDS_Mesh == NULL ) return aResult._retn(); long nbNodes = NbNodes(); aResult->length( nbNodes ); - SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator(); + SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true); for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); @@ -4337,12 +4326,12 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::double_array_var aResult = new SMESH::double_array(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return aResult._retn(); // find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); + const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(!aNode) return aResult._retn(); @@ -4368,12 +4357,12 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return aResult._retn(); // find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); + const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(!aNode) return aResult._retn(); @@ -4415,16 +4404,17 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) case SMDS_TOP_EDGE: aNodePosition->shapeType = GEOM::EDGE; aNodePosition->params.length(1); - aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter(); + aNodePosition->params[0] = + static_cast( pos )->GetUParameter(); break; - case SMDS_TOP_FACE: { - SMDS_FacePositionPtr fPos = pos; + case SMDS_TOP_FACE: aNodePosition->shapeType = GEOM::FACE; aNodePosition->params.length(2); - aNodePosition->params[0] = fPos->GetUParameter(); - aNodePosition->params[1] = fPos->GetVParameter(); + aNodePosition->params[0] = + static_cast( pos )->GetUParameter(); + aNodePosition->params[1] = + static_cast( pos )->GetVParameter(); break; - } case SMDS_TOP_VERTEX: aNodePosition->shapeType = GEOM::VERTEX; break; @@ -4499,12 +4489,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; // try to find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); + const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(aNode) { return aNode->getshapeId(); } @@ -4526,12 +4516,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; // try to find element - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return -1; @@ -4556,10 +4546,10 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return -1; + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; // try to find element - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return -1; return elem->NbNodes(); } @@ -4578,9 +4568,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return -1; - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return -1; if( index>=elem->NbNodes() || index<0 ) return -1; return elem->GetNode(index)->GetID(); @@ -4598,9 +4588,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) + if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) { - if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) ) + if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) ) { aResult->length( elem->NbNodes() ); for ( int i = 0; i < elem->NbNodes(); ++i ) @@ -4622,13 +4612,13 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return false; + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return false; // try to find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn); + const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn); if(!aNode) return false; // try to find element - const SMDS_MeshElement* elem = aMeshDS->FindElement(ide); + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide); if(!elem) return false; return elem->IsMediumNode(aNode); @@ -4648,11 +4638,11 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn, if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return false; + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return false; // try to find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn); + const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn); if(!aNode) return false; SMESH_MesherHelper aHelper( *(_impl) ); @@ -4678,9 +4668,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return -1; - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return -1; return elem->NbEdges(); } @@ -4697,9 +4687,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return -1; - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return -1; + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return -1; return elem->NbFaces(); } @@ -4716,9 +4706,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) + if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) { - if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) ) + if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) ) { SMDS_VolumeTool vtool( elem ); if ( faceIndex < vtool.NbFaces() ) @@ -4829,9 +4819,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return false; - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return false; + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return false; return elem->IsPoly(); } @@ -4848,9 +4838,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) return false; - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return false; + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return false; return elem->IsQuadratic(); } @@ -4867,7 +4857,7 @@ CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id) _preMeshInfo->FullLoadFromFile(); if ( const SMDS_BallElement* ball = - SMDS_Mesh::DownCast( _impl->GetMeshDS()->FindElement( id ))) + dynamic_cast( _impl->GetMeshDS()->FindElement( id ))) return ball->GetDiameter(); return 0; @@ -4885,11 +4875,11 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::double_array_var aResult = new SMESH::double_array(); - SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aMeshDS == NULL ) + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + if ( aSMESHDS_Mesh == NULL ) return aResult._retn(); - const SMDS_MeshElement* elem = aMeshDS->FindElement(id); + const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); if(!elem) return aResult._retn(); @@ -4949,14 +4939,12 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, { // compute error SMESH_ComputeErrorPtr error = sm->GetComputeError(); - if ( error && error->HasBadElems() ) + if ( error && !error->myBadElements.empty()) { // sort bad elements by type vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ]; - const list& badElems = - static_cast( error.get() )->myBadElements; - list::const_iterator elemIt = badElems.begin(); - list::const_iterator elemEnd = badElems.end(); + list::iterator elemIt = error->myBadElements.begin(); + list::iterator elemEnd = error->myBadElements.end(); for ( ; elemIt != elemEnd; ++elemIt ) { const SMDS_MeshElement* elem = *elemIt; @@ -5325,7 +5313,7 @@ SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream() { SALOMEDS::TMPFile_var SeqFile; if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) { - SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid(); + SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid(); if(aGrid) { vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); aWriter->WriteToOutputStringOn(); @@ -6124,24 +6112,6 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, } } -namespace // utils used by SMESH_MeshPartDS -{ - /*! - * \brief Class used to access to protected data of SMDS_MeshInfo - */ - struct TMeshInfo : public SMDS_MeshInfo - { - void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } - }; - /*! - * \brief Element holing its ID only - */ - struct TElemID : public SMDS_LinearEdge - { - TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); } - }; -} - //================================================================================ // // Implementation of SMESH_MeshPartDS @@ -6248,7 +6218,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType SMDS_MeshElement::GeomFilter > TIter; - SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType ); + SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType ); return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), _elements[type].end(), @@ -6266,7 +6236,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType SMDS_MeshElement::EntityFilter > TIter; - SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity ); + SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity ); return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), _elements[type].end(), @@ -6293,10 +6263,10 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type } // ------------------------------------------------------------------------------------- #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \ - iterType SMESH_MeshPartDS::methName() const \ + iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \ { \ typedef SMDS_SetIterator TIter; \ - return _meshDS ? _meshDS->methName() : iterType \ + return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \ ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \ } // ------------------------------------------------------------------------------------- diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx index c2181296c..c7e753d89 100644 --- a/src/SMESH_I/SMESH_PreMeshInfo.cxx +++ b/src/SMESH_I/SMESH_PreMeshInfo.cxx @@ -1059,7 +1059,8 @@ void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const // -- Most probably a bad study was saved when there were // not fixed bugs in SMDS_MeshInfo if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) { - SMDS_FacePositionPtr fPos = aPos; + SMDS_FacePosition* fPos = const_cast + ( static_cast( aPos )); fPos->SetUParameter( aUPos[ iNode ]); fPos->SetVParameter( aVPos[ iNode ]); } @@ -1067,8 +1068,9 @@ void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const else { // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182 if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) { - SMDS_EdgePositionPtr ePos = aPos; - ePos->SetUParameter( aUPos[ iNode ]); + SMDS_EdgePosition* fPos = const_cast + ( static_cast( aPos )); + fPos->SetUParameter( aUPos[ iNode ]); } } } diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index b9c2e393f..2c1beefc8 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -3619,7 +3619,7 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, for ( ; solidExp.More() && volIt->more(); solidExp.Next() ) { const SMDS_MeshElement* vol = volIt->next(); - sm1->RemoveElement( vol ); + sm1->RemoveElement( vol, /*isElemDeleted=*/false ); meshDS->SetMeshElementOnShape( vol, solidExp.Current() ); } } diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 0b6848622..b0d36a59c 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -549,7 +549,8 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons uvPt.normParam = u_node->first; uvPt.x = uvPt.y = uvPt.normParam; // -- U ---------------------------------------------- - SMDS_EdgePositionPtr epos = uvPt.node->GetPosition(); + const SMDS_EdgePosition* epos = + dynamic_cast(uvPt.node->GetPosition()); if ( epos && uvPt.node->getshapeId() == myEdgeID[iE] ) { uvPt.param = epos->GetUParameter(); } diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx index 403de38f6..a32b65891 100644 --- a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx @@ -386,7 +386,7 @@ namespace // Find a node at any block corner - SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator(); + SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator(/*idInceasingOrder=*/true); if ( !nIt->more() ) return error("Empty mesh"); const SMDS_MeshNode* nCorner = 0; diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx index b5da1cd52..949bd3a90 100644 --- a/src/StdMeshers/StdMeshers_Import_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -581,7 +581,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol ) // duplicated node on vertex return error("Source elements overlap one another"); - tgtFaceSM->RemoveNode( n ); + tgtFaceSM->RemoveNode( n, /*isNodeDeleted=*/false ); tgtMesh->SetNodeOnEdge( n, edges[iE], u ); break; } @@ -634,7 +634,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back()); helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true ); - tgtFaceSM->RemoveNode( link._medium ); + tgtFaceSM->RemoveNode( link._medium, /*isNodeDeleted=*/false ); tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u ); } else @@ -747,7 +747,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & seamHelper.AddEdge( node1, node2 ); if ( node2->getshapeId() == helper.GetSubShapeID() ) { - tgtFaceSM->RemoveNode( node2 ); + tgtFaceSM->RemoveNode( node2, /*isNodeDeleted=*/false ); tgtMesh->SetNodeOnEdge( const_cast( node2 ), seamEdge, n2->first ); } } diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 4ea62de3e..196dbe7da 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -516,7 +516,8 @@ static bool fixCommonVertexUV (R2 & theUV, // check if node is medium if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge )) continue; - SMDS_EdgePositionPtr epos = node->GetPosition(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition()); double u = epos->GetUParameter(); if ( u < umin ) umin = u; @@ -534,10 +535,10 @@ static bool fixCommonVertexUV (R2 & theUV, } R2 uv0, uv1, uv2; uv0.x = thisUV.X(); uv0.y = thisUV.Y(); - uv1.x = nextUV.X(); uv1.y = nextUV.Y(); + uv1.x = nextUV.X(); uv1.y = nextUV.Y(); uv2.x = thisUV.X(); uv2.y = thisUV.Y(); - uv1.x *= theScaleX; uv1.y *= theScaleY; + uv1.x *= theScaleX; uv1.y *= theScaleY; if ( fixOverlappedLinkUV( uv0, uv1, uv2 )) { diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index f22b5fe67..0223a7a07 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -234,7 +234,8 @@ void StdMeshers_Penta_3D::MakeNodes() aTNode.SetBaseNodeID(aNodeID); // if ( SMESH_Block::IsEdgeID (aSID)) { - SMDS_EdgePositionPtr epos = aNode->GetPosition(); + const SMDS_EdgePosition* epos = + static_cast(aNode->GetPosition()); myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); } else { @@ -1464,9 +1465,11 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, node = nIt->next(); if(myTool->IsMedium(node)) continue; - SMDS_EdgePositionPtr pos = node->GetPosition(); - if ( !pos ) + const SMDS_EdgePosition* pos = + dynamic_cast( node->GetPosition() ); + if ( !pos ) { return false; + } double u = ( pos->GetUParameter() - f ) / range; vector & nVec = theIJNodes[ u ]; nVec.resize( vsize, nullNode ); @@ -1485,9 +1488,11 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, node = nIt->next(); if(myTool->IsMedium(node)) continue; - SMDS_EdgePositionPtr pos = node->GetPosition(); - if ( !pos ) + const SMDS_EdgePosition* pos = + dynamic_cast( node->GetPosition() ); + if ( !pos ) { return false; + } sortedNodes.insert( make_pair( pos->GetUParameter(), node )); } loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() ); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index f5807f09a..9dde41365 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -1798,8 +1798,9 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism) if ( myHelper->GetIsQuadratic() ) { // fill myHelper with medium nodes built by quadAlgo - for ( SMDS_ElemIteratorPtr fIt = fSM->GetSubMeshDS()->GetElements(); fIt->more(); ) - myHelper->AddTLinks( SMDS_Mesh::DownCast( fIt->next() )); + SMDS_ElemIteratorPtr fIt = fSM->GetSubMeshDS()->GetElements(); + while ( fIt->more() ) + myHelper->AddTLinks( dynamic_cast( fIt->next() )); } } } @@ -4846,7 +4847,7 @@ TPCurveOnHorFaceAdaptor::TPCurveOnHorFaceAdaptor( const TSideFace* sideFace, } if ( !C2d.IsNull() ) { - double u = SMDS_EdgePositionPtr( n->GetPosition() )->GetUParameter(); + double u = static_cast< const SMDS_EdgePosition* >( n->GetPosition() )->GetUParameter(); if ( f <= u && u <= l ) { uv = C2d->Value( u ).XY(); diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 55a7214e8..2070ef108 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -2209,7 +2209,8 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, SMDS_NodeIteratorPtr nIt = edgeSM->GetNodes(); while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); - SMDS_EdgePositionPtr pos = node->GetPosition(); + const SMDS_EdgePosition* pos = + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); } if ((int) pos2nodes.size() != edgeSM->NbNodes() ) @@ -2885,6 +2886,7 @@ namespace StdMeshers_ProjectionUtils double bc[3]; // barycentric coordinates int nodeIDs[3]; // nodes of a delaunay triangle + const SMDS_FacePosition* pos; _delaunay.InitTraversal( nbSrcNodes ); @@ -2902,8 +2904,8 @@ namespace StdMeshers_ProjectionUtils tgtNode = n2n->second; tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() ); - if ( SMDS_FacePositionPtr pos = tgtNode->GetPosition() ) - pos->SetParameters( uvNew.X(), uvNew.Y() ); + if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() ))) + const_cast( pos )->SetParameters( uvNew.X(), uvNew.Y() ); --nbSrcNodes; } diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx index ae15730cd..c0e53ceeb 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx @@ -140,7 +140,7 @@ bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape { const SMDS_MeshElement* f = fIt->next(); //if ( !f->IsQuadratic() ) continue; - nodes.assign( SMDS_MeshElement::iterator( f->interlacedNodesIterator() ), + nodes.assign( SMDS_MeshElement::iterator( f->interlacedNodesElemIterator() ), SMDS_MeshElement::iterator() ); nodes.push_back( nodes[0] ); for ( size_t i = 2; i < nodes.size(); i += 2 ) @@ -149,8 +149,8 @@ bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape if ( idType.second == TopAbs_EDGE && idType.first != nodes[i-1]->getshapeId() ) { - faceSubMesh->RemoveNode( nodes[i-1] ); - meshDS->SetNodeOnEdge( nodes[i-1], idType.first ); + faceSubMesh->RemoveNode( nodes[i-1], /*isDeleted=*/false ); + meshDS->SetNodeOnEdge( (SMDS_MeshNode*) nodes[i-1], idType.first ); posFixer.SetSubShape( idType.first ); posFixer.CheckNodeU( TopoDS::Edge( posFixer.GetSubShape() ), nodes[i-1], dummyU=0., tol, /*force=*/true ); diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 68ae8ea47..0686b165a 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -371,7 +371,8 @@ namespace { if ( node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_EDGE ) RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() << " pos type " << node->GetPosition()->GetTypeOfPosition()); - SMDS_EdgePositionPtr pos = node->GetPosition(); + const SMDS_EdgePosition* pos = + static_cast(node->GetPosition()); u2nodes.insert( make_pair( pos->GetUParameter(), node )); seamNodes.insert( node ); } @@ -1586,7 +1587,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& break; } case SMDS_TOP_EDGE: { - SMDS_EdgePositionPtr pos = node->GetPosition(); + const SMDS_EdgePosition* pos = + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); break; } diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index 4284c1b36..43a6c4c09 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -31,6 +31,7 @@ #include "StdMeshers_ProjectionUtils.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Hypothesis.hxx" #include "SMESHDS_Mesh.hxx" @@ -407,7 +408,8 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS nodes[6], nodes[7], id, force3d); break; default: // polyhedron - const SMDS_MeshVolume * poly = tgtMeshDS->DownCast( srcVol ); + const SMDS_VtkVolume * poly = + dynamic_cast( srcVol ); if ( !poly ) RETURN_BAD_RESULT("Unexpected volume type"); if ( !poly->IsPoly()) diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index fd3a5bb10..2e4ea50b8 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -296,13 +296,12 @@ namespace SMESH_ComputeErrorPtr& err = sm->GetComputeError(); if ( !err || err->IsOK() ) { - SMESH_BadInputElements* badElems = - new SMESH_BadInputElements( mesh.GetMeshDS(),COMPERR_BAD_INPUT_MESH, msg, sm->GetAlgo() ); - badElems->add( face1 ); - badElems->add( face2 ); - err.reset( badElems ); + err = SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH, msg, sm->GetAlgo() ); + err->myBadElements.push_back( face1 ); + err->myBadElements.push_back( face2 ); } } + //throw SALOME_Exception( msg.c_str() ); return false; // == "algo fails" } @@ -1036,7 +1035,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) vector FNodes(5); TColgp_SequenceOfPnt aContour; - SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(); + SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true); while( fIt->more()) { const SMDS_MeshElement* face = fIt->next(); diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index a9d275cfb..ada3ab0cc 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -643,11 +643,9 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError(); if ( !err || err->IsOK() || err->myName < COMPERR_WARNING ) { - SMESH_BadInputElements* badElems = - new SMESH_BadInputElements( meshDS, COMPERR_WARNING, - "Bad quality quad created"); - badElems->add( face ); - err.reset( badElems ); + err.reset( new SMESH_ComputeError( COMPERR_WARNING, + "Bad quality quad created")); + err->myBadElements.push_back( face ); } } --i; @@ -820,11 +818,9 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError(); if ( !err || err->IsOK() || err->myName < COMPERR_WARNING ) { - SMESH_BadInputElements* badElems = - new SMESH_BadInputElements( meshDS, COMPERR_WARNING, - "Bad quality quad created"); - badElems->add( face ); - err.reset( badElems ); + err.reset( new SMESH_ComputeError( COMPERR_WARNING, + "Bad quality quad created")); + err->myBadElements.push_back( face ); } } --i; @@ -4672,11 +4668,9 @@ bool StdMeshers_Quadrangle_2D::check() { SMESH_subMesh* fSM = myHelper->GetMesh()->GetSubMesh( geomFace ); SMESH_ComputeErrorPtr& err = fSM->GetComputeError(); - SMESH_BadInputElements* badElems = - new SMESH_BadInputElements( meshDS, COMPERR_ALGO_FAILED, - "Inverted elements generated"); - badElems->myBadElements.swap( badFaces ); - err.reset( badElems ); + err.reset ( new SMESH_ComputeError( COMPERR_ALGO_FAILED, + "Inverted elements generated")); + err->myBadElements.swap( badFaces ); return !isOK; } diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index 72cdff35f..f68c3cbee 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -27,7 +27,6 @@ #include "SMDS_FaceOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_PolygonalFaceOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Hypothesis.hxx" @@ -94,7 +93,6 @@ #include #include #include -#include #ifdef _DEBUG_ #define __myDEBUG @@ -662,8 +660,7 @@ namespace VISCOUS_3D vector< _EdgesOnShape* > _eosConcaVer; // edges at concave VERTEXes of a FACE vector< _EdgesOnShape* > _eosC1; // to smooth together several C1 continues shapes - typedef std::unordered_map< const SMDS_MeshElement*, gp_XYZ > TFace2NormMap; - TFace2NormMap _faceNormals; // if _shape is FACE + vector< gp_XYZ > _faceNormals; // if _shape is FACE vector< _EdgesOnShape* > _faceEOS; // to get _faceNormals of adjacent FACEs Handle(ShapeAnalysis_Surface) _offsetSurf; @@ -1101,23 +1098,24 @@ namespace VISCOUS_3D * We can't use SMDS_FaceOfNodes since it's impossible to set it's ID which is * needed because SMESH_ElementSearcher internaly uses set of elements sorted by ID */ - struct _TmpMeshFace : public SMDS_PolygonalFaceOfNodes + struct _TmpMeshFace : public SMDS_MeshElement { - const SMDS_MeshElement* _srcFace; - + vector _nn; _TmpMeshFace( const vector& nodes, - int ID, - int faceID=-1, - const SMDS_MeshElement* srcFace=0 ): - SMDS_PolygonalFaceOfNodes(nodes), _srcFace( srcFace ) { setID( ID ); setShapeID( faceID ); } - virtual SMDSAbs_EntityType GetEntityType() const - { return _srcFace ? _srcFace->GetEntityType() : SMDSEntity_Quadrangle; } - virtual SMDSAbs_GeometryType GetGeomType() const - { return _srcFace ? _srcFace->GetGeomType() : SMDSGeom_QUADRANGLE; } + int id, int faceID=-1, int idInFace=-1): + SMDS_MeshElement(id), _nn(nodes) { setShapeId(faceID); setIdInShape(idInFace); } + virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nn[ind]; } + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } + virtual vtkIdType GetVtkType() const { return -1; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; } + virtual SMDSAbs_GeometryType GetGeomType() const + { return _nn.size() == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE; } + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType) const + { return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));} }; //-------------------------------------------------------------------------------- /*! - * \brief Class of temporary mesh quadrangle face storing _LayerEdge it's based on + * \brief Class of temporary mesh face storing _LayerEdge it's based on */ struct _TmpMeshFaceOnEdge : public _TmpMeshFace { @@ -1125,21 +1123,17 @@ namespace VISCOUS_3D _TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ): _TmpMeshFace( vector(4), ID ), _le1(le1), _le2(le2) { - myNodes[0]=_le1->_nodes[0]; - myNodes[1]=_le1->_nodes.back(); - myNodes[2]=_le2->_nodes.back(); - myNodes[3]=_le2->_nodes[0]; - } - const SMDS_MeshNode* n( size_t i ) const - { - return myNodes[ i ]; + _nn[0]=_le1->_nodes[0]; + _nn[1]=_le1->_nodes.back(); + _nn[2]=_le2->_nodes.back(); + _nn[3]=_le2->_nodes[0]; } gp_XYZ GetDir() const // return average direction of _LayerEdge's, normal to EDGE { - SMESH_TNodeXYZ p0s( myNodes[0] ); - SMESH_TNodeXYZ p0t( myNodes[1] ); - SMESH_TNodeXYZ p1t( myNodes[2] ); - SMESH_TNodeXYZ p1s( myNodes[3] ); + SMESH_TNodeXYZ p0s( _nn[0] ); + SMESH_TNodeXYZ p0t( _nn[1] ); + SMESH_TNodeXYZ p1t( _nn[2] ); + SMESH_TNodeXYZ p1s( _nn[3] ); gp_XYZ v0 = p0t - p0s; gp_XYZ v1 = p1t - p1s; gp_XYZ v01 = p1s - p0s; @@ -1150,10 +1144,10 @@ namespace VISCOUS_3D } gp_XYZ GetDir(_LayerEdge* le1, _LayerEdge* le2) // return average direction of _LayerEdge's { - myNodes[0]=le1->_nodes[0]; - myNodes[1]=le1->_nodes.back(); - myNodes[2]=le2->_nodes.back(); - myNodes[3]=le2->_nodes[0]; + _nn[0]=le1->_nodes[0]; + _nn[1]=le1->_nodes.back(); + _nn[2]=le2->_nodes.back(); + _nn[3]=le2->_nodes[0]; return GetDir(); } }; @@ -2647,7 +2641,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data) // create a temporary face const SMDS_MeshElement* newFace = - new _TmpMeshFace( newNodes, --_tmpFaceID, face->GetShapeID(), face ); + new _TmpMeshFace( newNodes, --_tmpFaceID, face->getshapeId(), face->getIdInShape() ); proxySub->AddElement( newFace ); // compute inflation step size by min size of element on a convex surface @@ -3319,18 +3313,19 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos, { SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); if ( !smDS ) return; - eos._faceNormals.reserve( smDS->NbElements() ); + eos._faceNormals.resize( smDS->NbElements() ); - double oriFactor = helper.IsReversedSubMesh( TopoDS::Face( eos._shape )) ? 1.: -1.; SMDS_ElemIteratorPtr eIt = smDS->GetElements(); - for ( ; eIt->more(); ) + for ( int iF = 0; eIt->more(); ++iF ) { const SMDS_MeshElement* face = eIt->next(); - gp_XYZ& norm = eos._faceNormals[face]; - if ( !SMESH_MeshAlgos::FaceNormal( face, norm, /*normalized=*/true )) - norm.SetCoord( 0,0,0 ); - norm *= oriFactor; + if ( !SMESH_MeshAlgos::FaceNormal( face, eos._faceNormals[iF], /*normalized=*/true )) + eos._faceNormals[iF].SetCoord( 0,0,0 ); } + + if ( !helper.IsReversedSubMesh( TopoDS::Face( eos._shape ))) + for ( size_t iF = 0; iF < eos._faceNormals.size(); ++iF ) + eos._faceNormals[iF].Reverse(); } else // find EOS of adjacent FACEs { @@ -3356,7 +3351,7 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos, bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm ) { bool ok = false; - _EdgesOnShape* eos = 0; + const _EdgesOnShape* eos = 0; if ( face->getshapeId() == _shapeID ) { @@ -3370,9 +3365,9 @@ bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm ) } if (( eos ) && - ( ok = ( eos->_faceNormals.count( face ) ))) + ( ok = ( face->getIdInShape() < (int) eos->_faceNormals.size() ))) { - norm = eos->_faceNormals[ face ]; + norm = eos->_faceNormals[ face->getIdInShape() ]; } else if ( !eos ) { @@ -3610,7 +3605,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, { const SMDS_MeshNode* tgtNode = edge._nodes.back(); if ( SMESHDS_SubMesh* sm = getMeshDS()->MeshElements( data._solid )) - sm->RemoveNode( tgtNode ); + sm->RemoveNode( tgtNode , /*isNodeDeleted=*/false ); // set initial position which is parameters on _sWOL in this case if ( eos.SWOLType() == TopAbs_EDGE ) @@ -5112,13 +5107,14 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, eos._edges[i]->Set( _LayerEdge::INTERSECTED ); // not to intersect eos._edges[i]->Block( data ); // not to inflate - //if ( _EdgesOnShape* eof = data.GetShapeEdges( intFace->getshapeId() )) + if ( _EdgesOnShape* eof = data.GetShapeEdges( intFace->getshapeId() )) { // block _LayerEdge's, on top of which intFace is if ( const _TmpMeshFace* f = dynamic_cast< const _TmpMeshFace*>( intFace )) { - const SMDS_MeshElement* srcFace = f->_srcFace; - SMDS_ElemIteratorPtr nIt = srcFace->nodesIterator(); + const SMDS_MeshElement* srcFace = + eof->_subMesh->GetSubMeshDS()->GetElement( f->getIdInShape() ); + SMDS_ElemIteratorPtr nIt = srcFace->nodesIterator(); while ( nIt->more() ) { const SMDS_MeshNode* srcNode = static_cast( nIt->next() ); @@ -5785,7 +5781,7 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData& data, tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); dumpMove( tgtNode ); - SMDS_FacePositionPtr pos = tgtNode->GetPosition(); + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); @@ -5897,7 +5893,7 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData& data, tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); dumpMove( tgtNode ); - SMDS_FacePositionPtr pos = tgtNode->GetPosition(); + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); @@ -6505,10 +6501,10 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute { edge->Set( _LayerEdge::SMOOTHED_C1 ); isCurved = true; - SMDS_FacePositionPtr fPos = edge->_nodes[0]->GetPosition(); + SMDS_FacePosition* fPos = dynamic_cast( edge->_nodes[0]->GetPosition() ); if ( !fPos ) for ( size_t iS = 0; iS < edge->_simplices.size() && !fPos; ++iS ) - fPos = edge->_simplices[iS]._nPrev->GetPosition(); + fPos = dynamic_cast( edge->_simplices[iS]._nPrev->GetPosition() ); if ( fPos ) edge->_curvature->_uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); } @@ -6805,9 +6801,9 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& ( f->_le2->IsOnEdge() && f->_le2->_2neibors->include( edge ))) continue; } dist1 = dist2 = Precision::Infinite(); - if ( !edge->SegTriaInter( lastSegment, f->n(0), f->n(1), f->n(2), dist1, eps )) + if ( !edge->SegTriaInter( lastSegment, f->_nn[0], f->_nn[1], f->_nn[2], dist1, eps )) dist1 = Precision::Infinite(); - if ( !edge->SegTriaInter( lastSegment, f->n(3), f->n(2), f->n(0), dist2, eps )) + if ( !edge->SegTriaInter( lastSegment, f->_nn[3], f->_nn[2], f->_nn[0], dist2, eps )) dist2 = Precision::Infinite(); if (( dist1 > segLen ) && ( dist2 > segLen )) continue; @@ -6815,7 +6811,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& if ( edge->IsOnEdge() ) { // skip perpendicular EDGEs - gp_Vec fSegDir = SMESH_TNodeXYZ( f->n(0) ) - SMESH_TNodeXYZ( f->n(3) ); + gp_Vec fSegDir = SMESH_TNodeXYZ( f->_nn[0] ) - SMESH_TNodeXYZ( f->_nn[3] ); bool isParallel = ( isLessAngle( eSegDir0, fSegDir, angle45 ) || isLessAngle( eSegDir1, fSegDir, angle45 ) || isLessAngle( eSegDir0, fSegDir.Reversed(), angle45 ) || @@ -8251,7 +8247,7 @@ void _LayerEdge::MoveNearConcaVer( const _EdgesOnShape* eov, prevPosV = surface.Value( prevPosV.X(), prevPosV.Y() ).XYZ(); } - SMDS_FacePositionPtr fPos; + SMDS_FacePosition* fPos; //double r = 1. - Min( 0.9, step / 10. ); for ( set< _LayerEdge* >::iterator e = edges.begin(); e != edges.end(); ++e ) { @@ -8265,7 +8261,7 @@ void _LayerEdge::MoveNearConcaVer( const _EdgesOnShape* eov, // set _curvature to make edgeF updated by putOnOffsetSurface() if ( !edgeF->_curvature ) - if (( fPos = edgeF->_nodes[0]->GetPosition() )) + if (( fPos = dynamic_cast( edgeF->_nodes[0]->GetPosition() ))) { edgeF->_curvature = new _Curvature; edgeF->_curvature->_r = 0; @@ -9486,7 +9482,7 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe _pos.back().SetCoord( u, 0, 0 ); if ( _nodes.size() > 1 && uvOK ) { - SMDS_EdgePositionPtr pos = n->GetPosition(); + SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); pos->SetUParameter( u ); } } @@ -9498,7 +9494,7 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe _pos.back().SetCoord( uv.X(), uv.Y(), 0 ); if ( _nodes.size() > 1 && uvOK ) { - SMDS_FacePositionPtr pos = n->GetPosition(); + SMDS_FacePosition* pos = static_cast( n->GetPosition() ); pos->SetUParameter( uv.X() ); pos->SetVParameter( uv.Y() ); } @@ -9614,7 +9610,7 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool TopLoc_Location loc; if ( eos.SWOLType() == TopAbs_EDGE ) { - SMDS_EdgePositionPtr pos = n->GetPosition(); + SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); pos->SetUParameter( nXYZ.X() ); double f,l; Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eos._sWOL ), loc, f,l); @@ -9622,7 +9618,7 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool } else { - SMDS_FacePositionPtr pos = n->GetPosition(); + SMDS_FacePosition* pos = static_cast( n->GetPosition() ); pos->SetUParameter( nXYZ.X() ); pos->SetVParameter( nXYZ.Y() ); Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(eos._sWOL), loc ); @@ -9987,12 +9983,12 @@ bool _ViscousBuilder::refine(_SolidData& data) SMDS_PositionPtr lastPos = tgtNode->GetPosition(); if ( isOnEdge ) { - SMDS_EdgePositionPtr epos = lastPos; + SMDS_EdgePosition* epos = static_cast( lastPos ); epos->SetUParameter( otherTgtPos.X() ); } else { - SMDS_FacePositionPtr fpos = lastPos; + SMDS_FacePosition* fpos = static_cast( lastPos ); fpos->SetUParameter( otherTgtPos.X() ); fpos->SetVParameter( otherTgtPos.Y() ); } @@ -10081,7 +10077,7 @@ bool _ViscousBuilder::refine(_SolidData& data) u = helper.GetNodeU( geomEdge, node ); pos = curve->Value( u ).Transformed(loc); - SMDS_EdgePositionPtr epos = node->GetPosition(); + SMDS_EdgePosition* epos = static_cast( node->GetPosition() ); epos->SetUParameter( u ); } else @@ -10091,7 +10087,7 @@ bool _ViscousBuilder::refine(_SolidData& data) uv = helper.GetNodeUV( geomFace, node ); pos = surface->Value( uv ); - SMDS_FacePositionPtr fpos = node->GetPosition(); + SMDS_FacePosition* fpos = static_cast( node->GetPosition() ); fpos->SetUParameter( uv.X() ); fpos->SetVParameter( uv.Y() ); } @@ -10266,11 +10262,10 @@ bool _ViscousBuilder::refine(_SolidData& data) SMESH_ComputeErrorPtr& err = _mesh->GetSubMesh( data._solid )->GetComputeError(); if ( !err || err->IsOK() ) { - SMESH_BadInputElements* badElems = - new SMESH_BadInputElements( getMeshDS(), COMPERR_WARNING, "Bad quality volumes created" ); - badElems->myBadElements.insert( badElems->myBadElements.end(), - degenVols.begin(),degenVols.end() ); - err.reset( badElems ); + err.reset( new SMESH_ComputeError( COMPERR_WARNING, + "Bad quality volumes created" )); + err->myBadElements.insert( err->myBadElements.end(), + degenVols.begin(),degenVols.end() ); } } @@ -10683,14 +10678,14 @@ bool _ViscousBuilder::shrink(_SolidData& theData) edge->Is( _LayerEdge::SHRUNK )) continue; if ( subEOS[iS]->SWOLType() == TopAbs_FACE ) { - SMDS_FacePositionPtr pos = tgtNode->GetPosition(); + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( edge->_pos[0].X() ); pos->SetVParameter( edge->_pos[0].Y() ); p = surface->Value( edge->_pos[0].X(), edge->_pos[0].Y() ); } else { - SMDS_EdgePositionPtr pos = tgtNode->GetPosition(); + SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( edge->_pos[0].Coord( U_TGT )); p = BRepAdaptor_Curve( TopoDS::Edge( subEOS[iS]->_sWOL )).Value( pos->GetUParameter() ); } @@ -10885,7 +10880,7 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge, edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 ); // set UV of source node to target node - SMDS_FacePositionPtr pos = tgtNode->GetPosition(); + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( srcUV.X() ); pos->SetVParameter( srcUV.Y() ); } @@ -10935,7 +10930,7 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge, edge._simplices[0]._nPrev = n2; // set U of source node to the target node - SMDS_EdgePositionPtr pos = tgtNode->GetPosition(); + SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( uSrc ); } return true; @@ -10968,7 +10963,7 @@ void _ViscousBuilder::restoreNoShrink( _LayerEdge& edge ) const TopLoc_Location loc; Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( S ), loc, f, l ); if ( curve.IsNull() ) return; - SMDS_EdgePositionPtr ePos = srcNode->GetPosition(); + SMDS_EdgePosition* ePos = static_cast( srcNode->GetPosition() ); p = curve->Value( ePos->GetUParameter() ); break; } @@ -11194,7 +11189,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface, { return true; } - SMDS_FacePositionPtr pos = tgtNode->GetPosition(); + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); pos->SetUParameter( newUV.X() ); pos->SetVParameter( newUV.Y() ); @@ -11208,7 +11203,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface, { const TopoDS_Edge& E = TopoDS::Edge( eos._sWOL ); const SMDS_MeshNode* n2 = _simplices[0]._nPrev; - SMDS_EdgePositionPtr tgtPos = tgtNode->GetPosition(); + SMDS_EdgePosition* tgtPos = static_cast( tgtNode->GetPosition() ); const double u2 = helper.GetNodeU( E, n2, tgtNode ); const double uSrc = _pos[0].Coord( U_SRC ); @@ -11328,7 +11323,7 @@ bool _SmoothNode::Smooth(int& nbBad, return false; } - SMDS_FacePositionPtr pos = _node->GetPosition(); + SMDS_FacePosition* pos = static_cast( _node->GetPosition() ); pos->SetUParameter( newPos.X() ); pos->SetVParameter( newPos.Y() ); @@ -11555,7 +11550,7 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper) if ( !discret.IsDone() ) return throw SALOME_Exception(LOCALIZED("GCPnts_AbscissaPoint failed")); double u = discret.Parameter(); - SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); pos->SetUParameter( u ); gp_Pnt p = C->Value( u ); const_cast< SMDS_MeshNode*>( _nodes[i] )->setXYZ( p.X(), p.Y(), p.Z() ); @@ -11573,7 +11568,7 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper) { if ( !_nodes[i] ) continue; double u = f * ( 1-_normPar[i] ) + l * _normPar[i]; - SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); pos->SetUParameter( u ); } } @@ -11591,7 +11586,7 @@ void _Shrinker1D::RestoreParams() for ( size_t i = 0; i < _nodes.size(); ++i ) { if ( !_nodes[i] ) continue; - SMDS_EdgePositionPtr pos = _nodes[i]->GetPosition(); + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); pos->SetUParameter( _initU[i] ); } _done = false; diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index 98a30fa22..6cb97c538 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -110,7 +110,7 @@ namespace VISCOUS_2D // Proxy sub-mesh of an EDGE. It contains nodes in _uvPtStructVec. struct _EdgeSubMesh : public SMESH_ProxyMesh::SubMesh { - _EdgeSubMesh(const SMDS_Mesh* mesh, int index=0): SubMesh(mesh,index) {} + _EdgeSubMesh(int index=0): SubMesh(index) {} //virtual int NbElements() const { return _elements.size()+1; } virtual int NbNodes() const { return Max( 0, _uvPtStructVec.size()-2 ); } void SetUVPtStructVec(UVPtStructVec& vec) { _uvPtStructVec.swap( vec ); } @@ -118,7 +118,7 @@ namespace VISCOUS_2D }; _ProxyMeshOfFace(const SMESH_Mesh& mesh): SMESH_ProxyMesh(mesh) {} _EdgeSubMesh* GetEdgeSubMesh(int ID) { return (_EdgeSubMesh*) getProxySubMesh(ID); } - virtual SubMesh* newSubmesh(int index=0) const { return new _EdgeSubMesh( GetMeshDS(), index); } + virtual SubMesh* newSubmesh(int index=0) const { return new _EdgeSubMesh(index); } }; //-------------------------------------------------------------------------------- /*! @@ -1998,7 +1998,7 @@ bool _ViscousBuilder2D::shrink() throw SALOME_Exception(SMESH_Comment("ViscousBuilder2D: not SMDS_TOP_EDGE node position: ") << oldNode->GetPosition()->GetTypeOfPosition() << " of node " << oldNode->GetID()); - SMDS_EdgePositionPtr pos = oldNode->GetPosition(); + SMDS_EdgePosition* pos = static_cast( oldNode->GetPosition() ); pos->SetUParameter( nodeDataVec[iP].param ); gp_Pnt newP = curve.Value( nodeDataVec[iP].param );