From da32f68aa4b650d3656a091f03d77517c5dbe6d3 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 6 Mar 2006 13:36:18 +0000 Subject: [PATCH] Merge from OCC_Quadric_Mesh_2006 --- Makefile.in | 9 +- idl/SMESH_BasicHypothesis.idl | 14 + idl/SMESH_Mesh.idl | 11 +- resources/StdMeshers.xml | 6 + src/Controls/SMESH_Controls.cxx | 394 ++- src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx | 4 +- src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx | 597 ++-- src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx | 261 +- src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx | 2 +- src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx | 117 +- src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx | 41 +- src/DriverUNV/UNV2412_Structure.cxx | 6 +- src/OBJECT/SMESH_Actor.cxx | 11 + src/OBJECT/SMESH_Object.cxx | 42 +- src/SMDS/Makefile.in | 39 +- src/SMDS/SMDS_ElemIterator.hxx | 16 + src/SMDS/SMDS_FaceOfEdges.cxx | 26 + src/SMDS/SMDS_FaceOfEdges.hxx | 11 + src/SMDS/SMDS_FaceOfNodes.cxx | 31 +- src/SMDS/SMDS_FaceOfNodes.hxx | 10 + src/SMDS/SMDS_Mesh.cxx | 1017 ++++++- src/SMDS/SMDS_Mesh.hxx | 226 +- src/SMDS/SMDS_MeshEdge.cxx | 12 + src/SMDS/SMDS_MeshEdge.hxx | 14 +- src/SMDS/SMDS_MeshElement.cxx | 26 + src/SMDS/SMDS_MeshElement.hxx | 74 +- src/SMDS/SMDS_MeshNode.hxx | 9 + src/SMDS/SMDS_PolygonalFaceOfNodes.cxx | 38 +- src/SMDS/SMDS_PolygonalFaceOfNodes.hxx | 9 + src/SMDS/SMDS_VolumeOfNodes.cxx | 34 +- src/SMDS/SMDS_VolumeOfNodes.hxx | 10 + src/SMDS/SMDS_VolumeTool.cxx | 454 ++- src/SMDS/SMDS_VolumeTool.hxx | 3 +- src/SMESH/Makefile.in | 1 + src/SMESH/SMESH_2D_Algo.cxx | 19 +- src/SMESH/SMESH_2D_Algo.hxx | 4 +- src/SMESH/SMESH_3D_Algo.cxx | 3 +- src/SMESH/SMESH_3D_Algo.hxx | 1 + src/SMESH/SMESH_Algo.cxx | 57 +- src/SMESH/SMESH_Algo.hxx | 25 +- src/SMESH/SMESH_Gen.cxx | 15 +- src/SMESH/SMESH_HypoFilter.cxx | 22 + src/SMESH/SMESH_HypoFilter.hxx | 6 + src/SMESH/SMESH_Hypothesis.cxx | 18 +- src/SMESH/SMESH_Hypothesis.hxx | 19 +- src/SMESH/SMESH_Mesh.cxx | 191 +- src/SMESH/SMESH_Mesh.hxx | 15 +- src/SMESH/SMESH_MeshEditor.cxx | 2704 ++++++++++++----- src/SMESH/SMESH_subMesh.cxx | 60 +- src/SMESH/SMESH_subMesh.hxx | 10 +- src/SMESHDS/SMESHDS_Command.cxx | 196 ++ src/SMESHDS/SMESHDS_Command.hxx | 22 + src/SMESHDS/SMESHDS_CommandType.hxx | 40 +- src/SMESHDS/SMESHDS_Mesh.cxx | 457 +++ src/SMESHDS/SMESHDS_Mesh.hxx | 195 ++ src/SMESHDS/SMESHDS_Script.cxx | 95 + src/SMESHDS/SMESHDS_Script.hxx | 21 + src/SMESHGUI/Makefile.in | 7 +- src/SMESHGUI/SMESHGUI.cxx | 64 + .../SMESHGUI_AddQuadraticElementDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx | 30 + src/SMESHGUI/SMESH_icons.po | 26 + src/SMESHGUI/SMESH_images.po | 29 + src/SMESHGUI/SMESH_msg_en.po | 137 + src/SMESH_I/SMESH_2smeshpy.cxx | 40 + src/SMESH_I/SMESH_Hypothesis_i.cxx | 2 +- src/SMESH_I/SMESH_MEDMesh_i.cxx | 2 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 69 +- src/SMESH_I/SMESH_MeshEditor_i.hxx | 1 + src/SMESH_SWIG/smesh.py | 12 + src/StdMeshers/Makefile.in | 8 +- src/StdMeshers/StdMeshers_Hexa_3D.cxx | 1067 ++++--- src/StdMeshers/StdMeshers_Hexa_3D.hxx | 7 + src/StdMeshers/StdMeshers_MEFISTO_2D.cxx | 308 +- src/StdMeshers/StdMeshers_MEFISTO_2D.hxx | 4 + src/StdMeshers/StdMeshers_Penta_3D.cxx | 484 ++- src/StdMeshers/StdMeshers_Penta_3D.hxx | 16 +- src/StdMeshers/StdMeshers_Propagation.cxx | 2 +- src/StdMeshers/StdMeshers_Quadrangle_2D.cxx | 231 +- src/StdMeshers/StdMeshers_Quadrangle_2D.hxx | 16 +- src/StdMeshers/StdMeshers_QuadraticMesh.cxx | 11 + src/StdMeshers/StdMeshers_QuadraticMesh.hxx | 11 + src/StdMeshers/StdMeshers_Regular_1D.cxx | 168 +- src/StdMeshers/StdMeshers_Regular_1D.hxx | 2 +- src/StdMeshersGUI/StdMeshers_images.po | 6 +- src/StdMeshers_I/Makefile.in | 6 +- src/StdMeshers_I/StdMeshers_i.cxx | 3 + 87 files changed, 7999 insertions(+), 2541 deletions(-) diff --git a/Makefile.in b/Makefile.in index f3a90dfb5..c01512951 100644 --- a/Makefile.in +++ b/Makefile.in @@ -131,7 +131,14 @@ mesh_pattern.png \ pattern_sample_2d.png \ pattern_sample_3D.png \ mesh_add.png \ -mesh_remove.png +mesh_remove.png \ +mesh_quad_edge.png \ +mesh_quad_triangle.png \ +mesh_quad_quadrangle.png \ +mesh_quad_tetrahedron.png \ +mesh_quad_pyramid.png \ +mesh_quad_pentahedron.png \ +mesh_quad_hexahedron.png BIN_SCRIPT= \ VERSION diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index b6367b75d..7880020e7 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -286,6 +286,20 @@ module StdMeshers { }; + /*! + * StdMeshers_QuadraticMesh: interface of "QuadraticMesh" hypothesis. + * This is an auxiliary 1D hypothesis whose presence forces construction + * of quadratic edges. + * If the 2D mesher sees that all boundary edges are quadratic ones, + * it generates quadratic faces, else it generates linear faces using + * medium nodes as if they were vertex ones. + * The 3D mesher generates quadratic volumes only if all boundary faces + * are quadratic ones, else it fails. + */ + interface StdMeshers_QuadraticMesh : SMESH::SMESH_Hypothesis + { + }; + /*! * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 5a2915c8d..4b7b54707 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -69,7 +69,14 @@ module SMESH MOVE_NODE, CHANGE_ELEMENT_NODES, CHANGE_POLYHEDRON_NODES, - RENUMBER + RENUMBER, + ADD_QUADEDGE, + ADD_QUADTRIANGLE, + ADD_QUADQUADRANGLE, + ADD_QUADTETRAHEDRON, + ADD_QUADPYRAMID, + ADD_QUADPENTAHEDRON, + ADD_QUADHEXAHEDRON }; struct log_block @@ -526,6 +533,8 @@ module SMESH boolean AddFace(in long_array IDsOfNodes); + boolean AddPolygonalFace(in long_array IdsOfNodes); + boolean AddVolume(in long_array IDsOfNodes); /*! diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index 2c1cd12cc..6daf06253 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -57,6 +57,12 @@ icon-id="mesh_algo_quad.png" dim="2"/> + + FindElement( theId ); - if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) + if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge/* || anEdge->NbNodes() != 2 */) return 0; - TColStd_MapOfInteger aMap; - - int aResult = 0; - SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); - if ( anIter != 0 ) { - while( anIter->more() ) { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode == 0 ) - return 0; - SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); - while( anElemIter->more() ) { - const SMDS_MeshElement* anElem = anElemIter->next(); - if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { - int anId = anElem->GetID(); - - if ( anIter->more() ) // i.e. first node - aMap.Add( anId ); - else if ( aMap.Contains( anId ) ) - aResult++; - } - } + // for each pair of nodes in anEdge (there are 2 pairs in a quadratic edge) + // count elements containing both nodes of the pair. + // Note that there may be such cases for a quadratic edge (a horizontal line): + // + // Case 1 Case 2 + // | | | | | + // | | | | | + // +-----+------+ +-----+------+ + // | | | | + // | | | | + // result sould be 2 in both cases + // + int aResult0 = 0, aResult1 = 0; + // last node, it is a medium one in a quadratic edge + const SMDS_MeshNode* aLastNode = anEdge->GetNode( anEdge->NbNodes() - 1 ); + const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 ); + const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 ); + if ( aNode1 == aLastNode ) aNode1 = 0; + + SMDS_ElemIteratorPtr anElemIter = aLastNode->GetInverseElementIterator(); + while( anElemIter->more() ) { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + while ( anIter->more() ) { + if ( const SMDS_MeshElement* anElemNode = anIter->next() ) { + if ( anElemNode == aNode0 ) { + aResult0++; + if ( !aNode1 ) break; // not a quadratic edge + } + else if ( anElemNode == aNode1 ) + aResult1++; + } + } } } + int aResult = max ( aResult0, aResult1 ); + +// TColStd_MapOfInteger aMap; + +// SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); +// if ( anIter != 0 ) { +// while( anIter->more() ) { +// const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); +// if ( aNode == 0 ) +// return 0; +// SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); +// while( anElemIter->more() ) { +// const SMDS_MeshElement* anElem = anElemIter->next(); +// if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { +// int anId = anElem->GetID(); + +// if ( anIter->more() ) // i.e. first node +// aMap.Add( anId ); +// else if ( aMap.Contains( anId ) ) +// aResult++; +// } +// } +// } +// } return aResult; } @@ -154,23 +193,41 @@ bool NumericalFunctor::GetPoints(const int theId, } bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, - TSequenceOfXYZ& theRes ) + TSequenceOfXYZ& theRes ) { theRes.clear(); if ( anElem == 0) return false; + theRes.reserve( anElem->NbNodes() ); + // Get nodes of the element - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - if ( anIter != 0 ) - { - while( anIter->more() ) - { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode != 0 ){ + SMDS_ElemIteratorPtr anIter; + + if ( anElem->IsQuadratic() ) { + switch ( anElem->GetType() ) { + case SMDSAbs_Edge: + anIter = static_cast + (anElem)->interlacedNodesElemIterator(); + break; + case SMDSAbs_Face: + anIter = static_cast + (anElem)->interlacedNodesElemIterator(); + break; + default: + anIter = anElem->nodesIterator(); + //return false; + } + } + else { + anIter = anElem->nodesIterator(); + } + + if ( anIter ) { + while( anIter->more() ) { + if ( const SMDS_MeshNode* aNode = static_cast( anIter->next() )) theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); - } } } @@ -285,6 +342,7 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) // According to "Mesh quality control" by Nadir Bouhamau referring to // Pascal Jean Frey and Paul-Louis George. Maillages, applications aux elements finis. // Hermes Science publications, Paris 1999 ISBN 2-7462-0024-4 + // PAL10872 int nbNodes = P.size(); @@ -840,22 +898,21 @@ SMDSAbs_ElementType Skew::GetType() const */ double Area::GetValue( const TSequenceOfXYZ& P ) { - double aArea = 0; - if ( P.size() == 3 ) - return getArea( P( 1 ), P( 2 ), P( 3 ) ); - else if (P.size() > 3) - aArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); - else - return 0; - - for (int i=4; i<=P.size(); i++) - aArea += getArea(P(1),P(i-1),P(i)); - return aArea; + gp_Vec aVec1( P(2) - P(1) ); + gp_Vec aVec2( P(3) - P(1) ); + gp_Vec SumVec = aVec1 ^ aVec2; + for (int i=4; i<=P.size(); i++) { + gp_Vec aVec1( P(i-1) - P(1) ); + gp_Vec aVec2( P(i) - P(1) ); + gp_Vec tmp = aVec1 ^ aVec2; + SumVec.Add(tmp); + } + return SumVec.Magnitude() * 0.5; } double Area::GetBadRate( double Value, int /*nbNodes*/ ) const { - // meaningless as it is not quality control functor + // meaningless as it is not a quality control functor return Value; } @@ -871,7 +928,11 @@ SMDSAbs_ElementType Area::GetType() const */ double Length::GetValue( const TSequenceOfXYZ& P ) { - return ( P.size() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0 ); + switch ( P.size() ) { + case 2: return getDistance( P( 1 ), P( 2 ) ); + case 3: return getDistance( P( 1 ), P( 2 ) ) + getDistance( P( 2 ), P( 3 ) ); + default: return 0.; + } } double Length::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -894,7 +955,10 @@ double Length2D::GetValue( long theElementId) { TSequenceOfXYZ P; + //cout<<"Length2D::GetValue"<FindElement( theElementId ); @@ -908,7 +972,11 @@ double Length2D::GetValue( long theElementId) case SMDSAbs_Edge: if (len == 2){ aVal = getDistance( P( 1 ), P( 2 ) ); - break; + break; + } + else if (len == 3){ // quadratic edge + aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); + break; } case SMDSAbs_Face: if (len == 3){ // triangles @@ -926,6 +994,22 @@ double Length2D::GetValue( long theElementId) aVal = Max(Max(L1,L2),Max(L3,L4)); break; } + if (len == 6){ // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + //cout<<"L1="<NbNodes(); /* Combien de mailles, faces ou aretes ? */ - int nb_of_nodes, nb_of_edges, nb_of_faces, nb_of_volumes; + int /*nb_of_nodes,*/ nb_of_edges, nb_of_faces, nb_of_volumes; nb_of_edges = myMesh->NbEdges(); nb_of_faces = myMesh->NbFaces(); nb_of_volumes = myMesh->NbVolumes(); diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 9a9a31c23..49c645f47 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -311,242 +311,385 @@ DriverMED_R_SMESHDS_Mesh break; } default: { - PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom); - EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX; - TInt aNbElems = aCellInfo->GetNbElem(); - if(MYDEBUG) MESSAGE("Perform - anEntity = "<GetFamNum(iElem); + }catch(const std::exception& exc){ + //INFOS("Follow exception was cought:\n\t"<GetFamNum(iElem); #ifndef _DEXCEPT_ - try{ + try{ #endif - //MESSAGE("Try to create element # " << iElem << " with id = " - // << aCellInfo->GetElemNum(iElem)); - switch(aGeom){ - case eSEG2: - case eSEG3: - if(anIsElemNum) - anElement = myMesh->AddEdgeWithID(aNodeIds[0], - aNodeIds[1], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1])); - isRenum = anIsElemNum; - } - break; - case eTRIA3: - case eTRIA6: - aNbNodes = 3; - if(anIsElemNum) - anElement = myMesh->AddFaceWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2])); - isRenum = anIsElemNum; - } - break; - case eQUAD4: - case eQUAD8: - aNbNodes = 4; - // There is some differnce between SMDS and MED - if(anIsElemNum) - anElement = myMesh->AddFaceWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3])); - isRenum = anIsElemNum; - } - break; - case eTETRA4: - case eTETRA10: - aNbNodes = 4; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3])); - isRenum = anIsElemNum; - } - break; - case ePYRA5: - case ePYRA13: - aNbNodes = 5; - // There is some differnce between SMDS and MED - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3]), - FindNode(myMesh,aNodeIds[4])); - isRenum = anIsElemNum; - } - break; - case ePENTA6: - case ePENTA15: - aNbNodes = 6; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - aNodeIds[5], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3]), - FindNode(myMesh,aNodeIds[4]), - FindNode(myMesh,aNodeIds[5])); - isRenum = anIsElemNum; - } - break; - case eHEXA8: - case eHEXA20: - aNbNodes = 8; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - aNodeIds[5], - aNodeIds[6], - aNodeIds[7], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3]), - FindNode(myMesh,aNodeIds[4]), - FindNode(myMesh,aNodeIds[5]), - FindNode(myMesh,aNodeIds[6]), - FindNode(myMesh,aNodeIds[7])); - isRenum = anIsElemNum; - } - break; - } + //MESSAGE("Try to create element # " << iElem << " with id = " + // << aCellInfo->GetElemNum(iElem)); + switch(aGeom){ + case eSEG2: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds[0], + aNodeIds[1], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1])); + isRenum = anIsElemNum; + } + break; + case eSEG3: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2])); + isRenum = anIsElemNum; + } + break; + case eTRIA3: + aNbNodes = 3; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2])); + isRenum = anIsElemNum; + } + break; + case eTRIA6: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5])); + isRenum = anIsElemNum; + } + break; + case eQUAD4: + aNbNodes = 4; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3])); + isRenum = anIsElemNum; + } + break; + case eQUAD8: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7])); + isRenum = anIsElemNum; + } + break; + case eTETRA4: + aNbNodes = 4; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3])); + isRenum = anIsElemNum; + } + break; + case eTETRA10: + aNbNodes = 10; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9])); + isRenum = anIsElemNum; + } + break; + case ePYRA5: + aNbNodes = 5; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4])); + isRenum = anIsElemNum; + } + break; + case ePYRA13: + aNbNodes = 13; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12])); + isRenum = anIsElemNum; + } + break; + case ePENTA6: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aNodeIds[3], + aNodeIds[4], + aNodeIds[5], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5])); + isRenum = anIsElemNum; + } + break; + case ePENTA15: + aNbNodes = 15; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], aNodeIds[13], + aNodeIds[14], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12]), + FindNode(myMesh,aNodeIds[13]), + FindNode(myMesh,aNodeIds[14])); + isRenum = anIsElemNum; + } + break; + case eHEXA8: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aNodeIds[3], + aNodeIds[4], + aNodeIds[5], + aNodeIds[6], + aNodeIds[7], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7])); + isRenum = anIsElemNum; + } + break; + case eHEXA20: + aNbNodes = 20; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], aNodeIds[13], + aNodeIds[14], aNodeIds[15], + aNodeIds[16], aNodeIds[17], + aNodeIds[18], aNodeIds[19], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12]), + FindNode(myMesh,aNodeIds[13]), + FindNode(myMesh,aNodeIds[14]), + FindNode(myMesh,aNodeIds[15]), + FindNode(myMesh,aNodeIds[16]), + FindNode(myMesh,aNodeIds[17]), + FindNode(myMesh,aNodeIds[18]), + FindNode(myMesh,aNodeIds[19])); + isRenum = anIsElemNum; + } + break; + } #ifndef _DEXCEPT_ - }catch(const std::exception& exc){ - //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); - myFamilies[aFamNum]->SetType(anElement->GetType()); - } - } - } - }} - } - } + }catch(const std::exception& exc){ + //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); + myFamilies[aFamNum]->SetType(anElement->GetType()); + } + } + } + }} + } + } } } #ifndef _DEXCEPT_ diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 22b33cf63..877c24a67 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -393,39 +393,90 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() #ifdef _ELEMENTS_BY_DIM_ SMDS_MED_ENTITY = eARETE; #endif + // count edges of diff types + int aNbSeg3 = 0, aNbSeg2 = 0; SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator(); - TInt aNbConnectivity = MED::GetNbNodes(eSEG2); - MED::TIntVector anElemNums(aNbElems); - MED::TIntVector aFamilyNums(aNbElems); - MED::TIntVector aConnectivity(aNbElems*aNbConnectivity); - - for(TInt iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){ + while ( anIter->more() ) + if ( anIter->next()->NbNodes() == 3 ) + ++aNbSeg3; + aNbSeg2 = aNbElems - aNbSeg3; + + TInt aNbSeg2Conn = MED::GetNbNodes(eSEG2); + MED::TIntVector aSeg2ElemNums, aSeg2FamilyNums, aSeg2Conn; + aSeg2ElemNums .reserve( aNbSeg2 ); + aSeg2FamilyNums.reserve( aNbSeg2 ); + aSeg2Conn .reserve( aNbSeg2*aNbSeg2Conn ); + + TInt aNbSeg3Conn = MED::GetNbNodes(eSEG3); + MED::TIntVector aSeg3ElemNums, aSeg3FamilyNums, aSeg3Conn; + aSeg3ElemNums .reserve( aNbSeg3 ); + aSeg3FamilyNums.reserve( aNbSeg3 ); + aSeg3Conn .reserve( aNbSeg3*aNbSeg3Conn ); + + anIter = myMesh->edgesIterator(); + while ( anIter->more() ) { const SMDS_MeshEdge* anElem = anIter->next(); - SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); - for(TInt iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){ - const SMDS_MeshElement* aNode = aNodesIter->next(); + TInt aNbNodes = anElem->NbNodes(); + + TInt aNbConnectivity; + MED::TIntVector* anElemNums; + MED::TIntVector* aFamilyNums; + MED::TIntVector* aConnectivity; + switch(aNbNodes){ + case 2: + aNbConnectivity = aNbSeg2Conn; + anElemNums = &aSeg2ElemNums; + aFamilyNums = &aSeg2FamilyNums; + aConnectivity = &aSeg2Conn; + break; + case 3: + aNbConnectivity = aNbSeg3Conn; + anElemNums = &aSeg3ElemNums; + aFamilyNums = &aSeg3FamilyNums; + aConnectivity = &aSeg3Conn; + break; + default: + break; + } + + for(TInt iNode = 0; iNode < aNbNodes; iNode++) { + const SMDS_MeshElement* aNode = anElem->GetNode( iNode ); #ifdef _EDF_NODE_IDS_ - aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()]; + aConnectivity->push_back( aNodeIdMap[aNode->GetID()] ); #else - aConnectivity[iConn+iNode] = aNode->GetID(); + aConnectivity->push_back( aNode->GetID() ); #endif - } - anElemNums[iElem] = anElem->GetID(); + } - if (anElemFamMap.find(anElem) != anElemFamMap.end()) - aFamilyNums[iElem] = anElemFamMap[anElem]; + anElemNums->push_back(anElem->GetID()); + + map::iterator edge_fam = anElemFamMap.find( anElem ); + if ( edge_fam != anElemFamMap.end() ) + aFamilyNums->push_back( edge_fam->second ); else - aFamilyNums[iElem] = myEdgesDefaultFamilyId; + aFamilyNums->push_back( myFacesDefaultFamilyId ); } - PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, - SMDS_MED_ENTITY, - eSEG2, - aConnectivity, - SMDS_MED_CONNECTIVITY, - aFamilyNums, - anElemNums); - myMed->SetCellInfo(aCellInfo); + if ( aNbSeg2 ) { + PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + eSEG2, + aSeg2Conn, + SMDS_MED_CONNECTIVITY, + aSeg2FamilyNums, + aSeg2ElemNums); + myMed->SetCellInfo(aCellInfo); + } + if ( aNbSeg3 ) { + PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + eSEG3, + aSeg3Conn, + SMDS_MED_CONNECTIVITY, + aSeg3FamilyNums, + aSeg3ElemNums); + myMed->SetCellInfo(aCellInfo); + } } // Storing SMDS Faces @@ -442,6 +493,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MED::TIntVector aTriaConn; aTriaConn.reserve(aNbElems*aNbTriaConn); + TInt aNbTria6Conn = MED::GetNbNodes(eTRIA6); + MED::TIntVector anTria6ElemNums; + anTria6ElemNums.reserve(aNbElems); + MED::TIntVector aTria6FamilyNums; + aTria6FamilyNums.reserve(aNbElems); + MED::TIntVector aTria6Conn; + aTria6Conn.reserve(aNbElems*aNbTria6Conn); + TInt aNbQuadConn = MED::GetNbNodes(eQUAD4); MED::TIntVector aQuadElemNums; aQuadElemNums.reserve(aNbElems); @@ -450,6 +509,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MED::TIntVector aQuadConn; aQuadConn.reserve(aNbElems*aNbQuadConn); + TInt aNbQuad8Conn = MED::GetNbNodes(eQUAD8); + MED::TIntVector aQuad8ElemNums; + aQuad8ElemNums.reserve(aNbElems); + MED::TIntVector aQuad8FamilyNums; + aQuad8FamilyNums.reserve(aNbElems); + MED::TIntVector aQuad8Conn; + aQuad8Conn.reserve(aNbElems*aNbQuad8Conn); + MED::TIntVector aPolygoneElemNums; aPolygoneElemNums.reserve(aNbElems); MED::TIntVector aPolygoneInds; @@ -473,7 +540,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() anElemNums = &aPolygoneElemNums; aFamilyNums = &aPolygoneFamilyNums; aConnectivity = &aPolygoneConn; - } else { + } + else { switch(aNbNodes){ case 3: aNbConnectivity = aNbTriaConn; @@ -487,6 +555,18 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() aFamilyNums = &aQuadFamilyNums; aConnectivity = &aQuadConn; break; + case 6: + aNbConnectivity = aNbTria6Conn; + anElemNums = &anTria6ElemNums; + aFamilyNums = &aTria6FamilyNums; + aConnectivity = &aTria6Conn; + break; + case 8: + aNbConnectivity = aNbQuad8Conn; + anElemNums = &aQuad8ElemNums; + aFamilyNums = &aQuad8FamilyNums; + aConnectivity = &aQuad8Conn; + break; default: break; } @@ -550,6 +630,28 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() MESSAGE("Perform - anEntity = "<first; const TRecord& aRec = anIter->second; - if(IsBeam(aRec.fe_descriptor_id)){ - anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], - aRec.node_labels[1], - aLabel); - }else if(IsFace(aRec.fe_descriptor_id)){ + if(IsBeam(aRec.fe_descriptor_id)) { + if(aRec.fe_descriptor_id == 11) { + // edge with two nodes + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aLabel); + } + else { + // quadratic edge (with 3 nodes) + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + } + } + else if(IsFace(aRec.fe_descriptor_id)) { switch(aRec.fe_descriptor_id){ case 71: // TRI3 case 72: @@ -76,18 +87,31 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() case 41: // Plane Stress Linear Triangle - TRI3 case 91: // Thin Shell Linear Triangle - TRI3 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + break; case 42: // Plane Stress Quadratic Triangle - TRI6 case 92: // Thin Shell Quadratic Triangle - TRI6 - anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], + aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], aLabel); break; case 44: // Plane Stress Linear Quadrilateral - QUAD4 case 94: // Thin Shell Linear Quadrilateral - QUAD4 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aRec.node_labels[3], + aLabel); + break; case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 @@ -95,24 +119,40 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[1], aRec.node_labels[2], aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], + aRec.node_labels[6], + aRec.node_labels[7], aLabel); break; } - }else if(IsVolume(aRec.fe_descriptor_id)){ + } + else if(IsVolume(aRec.fe_descriptor_id)){ switch(aRec.fe_descriptor_id){ case 111: // Solid Linear Tetrahedron - TET4 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aLabel); + break; + case 118: // Solid Quadratic Tetrahedron - TET10 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], aRec.node_labels[3], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[9], + aRec.node_labels[8], aLabel); break; case 112: // Solid Linear Prism - PRISM6 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], @@ -123,13 +163,21 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 113: // Solid Quadratic Prism - PRISM15 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[4], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[11], + aRec.node_labels[10], aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[14], aRec.node_labels[13], - aRec.node_labels[11], aLabel); break; @@ -146,26 +194,57 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 116: // Solid Quadratic Brick - HEX20 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[6], - aRec.node_labels[4], + aRec.node_labels[3], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[11], + aRec.node_labels[10], + aRec.node_labels[9], + aRec.node_labels[8], + aRec.node_labels[15], + aRec.node_labels[14], + aRec.node_labels[13], aRec.node_labels[12], - aRec.node_labels[18], aRec.node_labels[16], - aRec.node_labels[14], + aRec.node_labels[19], + aRec.node_labels[18], + aRec.node_labels[17], + aLabel); + break; + + case 114: // pyramid of 13 nodes (quadratic) - PIRA13 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[3], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[11], + aRec.node_labels[10], aLabel); break; + } } if(!anElement) MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<next(); aRec.node_labels.push_back(aNode->GetID()); } - aRec.fe_descriptor_id = 11; + if(aNbNodes==2) + aRec.fe_descriptor_id = 11; + else + aRec.fe_descriptor_id = 21; aDataSet2412.insert(TDataSet::value_type(aLabel,aRec)); } MESSAGE("Perform - aDataSet2412.size() = "<RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); my3DActor = SMESH_DeviceActor::New(); my3DActor->SetUserMatrix(aMatrix); @@ -164,6 +166,8 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); //Definition 1D divice of the actor @@ -185,6 +189,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); my1DProp = vtkProperty::New(); my1DProp->DeepCopy(myEdgeProp); @@ -210,6 +215,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DExtActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); //Definition 0D divice of the actor @@ -1017,6 +1023,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ if(myEntityMode & eEdges){ if (MYDEBUG) MESSAGE("EDGES"); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); } if(myEntityMode & eFaces){ @@ -1024,6 +1031,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); } if(myEntityMode & eVolumes){ @@ -1033,6 +1042,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); } aFilter->Update(); diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 4727832dd..7355e4b2b 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -90,12 +90,16 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, switch( theType ) { case SMDSAbs_Edge: - return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL; + 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 return VTK_EMPTY_CELL; case SMDSAbs_Volume: @@ -104,6 +108,15 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, else if ( theNbNodes == 5 ) return VTK_PYRAMID; else if ( theNbNodes == 6 ) return VTK_WEDGE; else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON; + else if ( theNbNodes == 10 ) { + return VTK_QUADRATIC_TETRA; + } + else if ( theNbNodes == 20 ) { + return VTK_QUADRATIC_HEXAHEDRON; + } + else if ( theNbNodes==13 || theNbNodes==15 ) { + return VTK_CONVEX_POINT_SET; + } else return VTK_EMPTY_CELL; default: return VTK_EMPTY_CELL; @@ -391,11 +404,34 @@ void SMESH_VisualObjDef::buildElemPrs() static int anIds[] = {0,1,2,3,4,5}; for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); - } else if (aNbNodes == 8) { + } + else if (aNbNodes == 8) { static int anIds[] = {0,3,2,1,4,7,6,5}; for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); - } else { + } + else if (aNbNodes == 10) { + static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + } + else if (aNbNodes == 13) { + static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + } + else if (aNbNodes == 15) { + static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + //for (int k = 0; k < aNbNodes; k++) { + // int nn = aConnectivities[k]; + // const SMDS_MeshNode* N = static_cast (aConnect[nn]); + // cout<<"k="<X()<<","<Y()<<","<Z()<<")"< 0) { diff --git a/src/SMDS/Makefile.in b/src/SMDS/Makefile.in index e066e25e0..7ecaf313a 100644 --- a/src/SMDS/Makefile.in +++ b/src/SMDS/Makefile.in @@ -59,21 +59,10 @@ LIB_SRC = \ SMDS_FaceOfEdges.cxx \ SMDS_FaceOfNodes.cxx \ SMDS_PolygonalFaceOfNodes.cxx \ - SMDS_VolumeTool.cxx -# SMDS_Tria3OfNodes.cxx \ -# SMDS_HexahedronOfNodes.cxx - -#SMDSControl_BoundaryEdges.cxx \ -#SMDSControl_BoundaryFaces.cxx \ -#SMDSControl.cxx \ -#SMDSControl_MeshBoundary.cxx \ -#SMDSEdit_Transform.cxx \ -#SMDS_MeshNodeIDFactory.cxx \ -#SMDS_MeshPrism.cxx \ -#SMDS_MeshPyramid.cxx \ -#SMDS_MeshQuadrangle.cxx \ -#SMDS_MeshTetrahedron.cxx \ -#SMDS_MeshTriangle.cxx \ + SMDS_VolumeTool.cxx \ + SMDS_QuadraticEdge.cxx \ + SMDS_QuadraticFaceOfNodes.cxx \ + SMDS_QuadraticVolumeOfNodes.cxx LIB_CLIENT_IDL = @@ -113,21 +102,11 @@ EXPORT_HEADERS= \ SMDS_FaceOfEdges.hxx \ SMDS_FaceOfNodes.hxx \ SMDS_PolygonalFaceOfNodes.hxx \ - SMDS_VolumeTool.hxx -# SMDS_Tria3OfNodes.hxx \ -# SMDS_HexahedronOfNodes.hxx - -#SMDSControl_BoundaryEdges.hxx \ -#SMDSControl_BoundaryFaces.hxx \ -#SMDSControl.hxx \ -#SMDSControl_MeshBoundary.hxx \ -#SMDSEdit_Transform.hxx \ -#SMDS_MeshPrism.hxx \ -#SMDS_MeshPyramid.hxx \ -#SMDS_MeshQuadrangle.hxx \ -#SMDS_MeshTetrahedron.hxx \ -#SMDS_MeshTriangle.hxx \ -#SMDS_MeshNodeIDFactory.hxx + SMDS_VolumeTool.hxx \ + SMDS_QuadraticEdge.hxx \ + SMDS_QuadraticFaceOfNodes.hxx \ + SMDS_QuadraticVolumeOfNodes.hxx \ + SMDS_SetIterator.hxx # additionnal information to compil and link file CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome $(OCC_INCLUDES) $(BOOST_CPPFLAGS) diff --git a/src/SMDS/SMDS_ElemIterator.hxx b/src/SMDS/SMDS_ElemIterator.hxx index c8432afdd..6ff098644 100755 --- a/src/SMDS/SMDS_ElemIterator.hxx +++ b/src/SMDS/SMDS_ElemIterator.hxx @@ -33,8 +33,24 @@ #include class SMDS_MeshElement; +class SMDS_MeshNode; +class SMDS_MeshEdge; +class SMDS_MeshFace; +class SMDS_MeshVolume; typedef SMDS_Iterator SMDS_ElemIterator; typedef boost::shared_ptr > SMDS_ElemIteratorPtr; +typedef SMDS_Iterator SMDS_NodeIterator; +typedef boost::shared_ptr > SMDS_NodeIteratorPtr; + +typedef SMDS_Iterator SMDS_EdgeIterator; +typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; + +typedef SMDS_Iterator SMDS_FaceIterator; +typedef boost::shared_ptr > SMDS_FaceIteratorPtr; + +typedef SMDS_Iterator SMDS_VolumeIterator; +typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; + #endif diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx index 640c55d30..7a014afb8 100644 --- a/src/SMDS/SMDS_FaceOfEdges.cxx +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -155,3 +155,29 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, }*/ + +int SMDS_FaceOfEdges::NbNodes() const +{ + return myEdges[0]->NbNodes() + 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 + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const +{ + int index = WrappedIndex( 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; +} + diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx index cd8e5dd8f..54a9a688f 100644 --- a/src/SMDS/SMDS_FaceOfEdges.hxx +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -42,10 +42,21 @@ class SMDS_FaceOfEdges:public SMDS_MeshFace const SMDS_MeshEdge* edge4); SMDSAbs_ElementType GetType() const; + int NbNodes() const; int NbEdges() const; int NbFaces() const; // friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2); + + /*! + * \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 + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index aa6870824..018bd88a0 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -23,6 +23,7 @@ #pragma warning(disable:4786) #endif +#include "SMDS_SetIterator.hxx" #include "SMDS_FaceOfNodes.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" @@ -68,25 +69,11 @@ void SMDS_FaceOfNodes::Print(ostream & OS) const //purpose : //======================================================================= -class SMDS_FaceOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { - const SMDS_MeshNode* const *mySet; - int myLength; - int index; public: SMDS_FaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l): - mySet(s),myLength(l),index(0) {} - - bool more() - { - return index set1,set2; diff --git a/src/SMDS/SMDS_FaceOfNodes.hxx b/src/SMDS/SMDS_FaceOfNodes.hxx index 290195107..8cbdf6f33 100644 --- a/src/SMDS/SMDS_FaceOfNodes.hxx +++ b/src/SMDS/SMDS_FaceOfNodes.hxx @@ -44,6 +44,16 @@ class SMDS_FaceOfNodes:public SMDS_MeshFace 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 + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 58f3e52c2..5df2090e9 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -31,6 +31,9 @@ #include "SMDS_FaceOfEdges.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_QuadraticVolumeOfNodes.hxx" #include #include @@ -1084,19 +1087,32 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, if ( edge ) Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); } + else if ( nbnodes == 3 ) { + const SMDS_QuadraticEdge* edge = dynamic_cast( elem ); + if ( edge ) + Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + } break; } case SMDSAbs_Face: { const SMDS_FaceOfNodes* face = dynamic_cast( elem ); if ( face ) { Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); - } else { - /// ??? begin - const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - if (face) { - Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + else { + const SMDS_QuadraticFaceOfNodes* QF = + dynamic_cast( elem ); + if ( QF ) { + Ok = const_cast( QF )->ChangeNodes( nodes, nbnodes ); + } + else { + /// ??? begin + const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + if (face) { + Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + /// ??? end } - /// ??? end } break; } @@ -1109,8 +1125,15 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //} case SMDSAbs_Volume: { const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); - if ( vol ) + if ( vol ) { Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); + } + else { + const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem ); + if ( QV ) { + Ok = const_cast( QV )->ChangeNodes( nodes, nbnodes ); + } + } break; } default: @@ -1200,6 +1223,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, return Ok; } + //======================================================================= //function : FindEdge //purpose : @@ -1207,54 +1231,95 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, 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); + 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) { - const SMDS_MeshEdge * toReturn=NULL; - //PROFILER_Init(); - //PROFILER_Set(); - SMDS_ElemIteratorPtr it1=node1->edgesIterator(); - //PROFILER_Get(0); - //PROFILER_Set(); - while(it1->more()) - { - const SMDS_MeshEdge * e=static_cast - (it1->next()); - SMDS_ElemIteratorPtr it2=e->nodesIterator(); - while(it2->more()) - { - if(it2->next()->GetID()==node2->GetID()) - { - toReturn=e; - break; - } - } - } - //PROFILER_Get(1); - return toReturn; + const SMDS_MeshEdge * toReturn=NULL; + //PROFILER_Init(); + //PROFILER_Set(); + SMDS_ElemIteratorPtr it1=node1->edgesIterator(); + //PROFILER_Get(0); + //PROFILER_Set(); + while(it1->more()) { + const SMDS_MeshEdge * e=static_cast (it1->next()); + SMDS_ElemIteratorPtr it2=e->nodesIterator(); + while(it2->more()) { + if(it2->next()->GetID()==node2->GetID()) { + toReturn = e; + break; + } + } + } + //PROFILER_Get(1); + return toReturn; } +//======================================================================= +//function : FindEdgeOrCreate +//purpose : +//======================================================================= + SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - SMDS_MeshEdge * toReturn=NULL; - toReturn=const_cast(FindEdge(node1,node2)); - if(toReturn==NULL) - { - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.Add(toReturn); - } - return toReturn; + SMDS_MeshEdge * toReturn=NULL; + toReturn=const_cast(FindEdge(node1,node2)); + if(toReturn==NULL) { + toReturn=new SMDS_MeshEdge(node1,node2); + myEdges.Add(toReturn); + } + 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); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; + return FindEdge(node1,node2,node3); +} + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) +{ + const SMDS_MeshEdge * toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node1->edgesIterator(); + while(it1->more()) { + const SMDS_MeshEdge * e = static_cast (it1->next()); + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + int tmp = 0; + while(it2->more()) { + int nID = it2->next()->GetID(); + if( nID==node2->GetID() || nID==node3->GetID() ) { + tmp++; + if(tmp==2) { + toReturn = e; + break; + } + } + } + } + return toReturn; +} + + //======================================================================= //function : FindFace //purpose : @@ -1263,118 +1328,219 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, 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); - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - return FindFace(node1, node2, node3); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; + return FindFace(node1, node2, node3); } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found; - - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=3) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - } - if(node2found&&node3found) - return face; - } - return NULL; + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found; + + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=3) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + node2found = false; + node3found = false; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) node2found = true; + if(node->GetID()==node3->GetID()) node3found = true; + } + if( node2found && node3found ) + return face; + } + return NULL; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) +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) - { - toReturn=createTriangle(node1,node2,node3); - } - return toReturn; + SMDS_MeshFace * toReturn=NULL; + toReturn = const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) { + toReturn = createTriangle(node1,node2,node3); + } + return toReturn; } + //======================================================================= //function : FindFace //purpose : //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3, - int idnode4) const +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); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL; - return FindFace(node1, node2, node3, node4); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + const SMDS_MeshNode * node4=FindNode(idnode4); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ) + return NULL; + return FindFace(node1, node2, node3, node4); } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found, node4found; - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=4) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - node4found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - if(node->GetID()==node4->GetID()) node4found=true; - } - if(node2found&&node3found&&node4found) - return face; - } - return NULL; + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found, node4found; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=4) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + node2found = false; + node3found = false; + node4found = false; + while(it2->more()) { + node=it2->next(); + if(node->GetID()==node2->GetID()) node2found = true; + if(node->GetID()==node3->GetID()) node3found = true; + if(node->GetID()==node4->GetID()) node4found = true; + } + if( node2found && node3found && node4found ) + return face; + } + return NULL; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) +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) - { - toReturn=createQuadrangle(node1,node2,node3,node4); - } - return toReturn; + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3,node4)); + if(toReturn==NULL) { + toReturn=createQuadrangle(node1,node2,node3,node4); + } + 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); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || + (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL; + 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, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=6) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + int tmp = 0; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) tmp++; + if(node->GetID()==node3->GetID()) tmp++; + if(node->GetID()==node4->GetID()) tmp++; + if(node->GetID()==node5->GetID()) tmp++; + if(node->GetID()==node6->GetID()) tmp++; + } + if( tmp==5 ) + return static_cast(face); + } + return NULL; } + +//======================================================================= +//function : FindFace +//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); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) || + (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) ) + return NULL; + 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, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6, + const SMDS_MeshNode *node7, + const SMDS_MeshNode *node8) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=8) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + int tmp = 0; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) tmp++; + if(node->GetID()==node3->GetID()) tmp++; + if(node->GetID()==node4->GetID()) tmp++; + if(node->GetID()==node5->GetID()) tmp++; + if(node->GetID()==node6->GetID()) tmp++; + if(node->GetID()==node7->GetID()) tmp++; + if(node->GetID()==node8->GetID()) tmp++; + } + if( tmp==7 ) + return face; + } + return NULL; +} + + //======================================================================= //function : FindElement //purpose : @@ -1382,7 +1548,7 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + return myElementIDFactory->MeshElement(IDelem); } //======================================================================= @@ -2252,3 +2418,588 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) else return elem->GetType(); } + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + SMDS_MeshNode* node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode* node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode* node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + if(!node1 || !node2 || !node12) return NULL; + return SMDS_Mesh::AddEdgeWithID(node1, node2, node12, ID); +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12); + if(myElementIDFactory->BindID(ID, edge)) { + SMDS_MeshNode *node1,*node2, *node12; + node1 = const_cast(n1); + node2 = const_cast(n2); + node12 = const_cast(n12); + node1->AddInverseElement(edge); + node2->AddInverseElement(edge); + node12->AddInverseElement(edge); + myEdges.Add(edge); + return edge; + } + else { + delete edge; + return NULL; + } +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); + SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); + SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); + SMDS_MeshNode * node31 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31); + if(!node1 || !node2 || !node3 || !node12 || !node23 || !node31) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, + node12, node23, node31, ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); + myFaces.Add(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(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) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); + SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4); + SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); + SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); + SMDS_MeshNode * node34 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34); + SMDS_MeshNode * node41 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41); + if(!node1 || !node2 || !node3 || !node4 || + !node12 || !node23 || !node34 || !node41) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, + node12, node23, node34, node41, ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(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, + int ID) +{ + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); + myFaces.Add(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(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) +{ + 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; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +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) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node12, *node23; + SMDS_MeshNode *node31, *node14, *node24, *node34; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); + node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); + node24 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + if( !node1 || !node2 || !node3 || !node4 || !node12 || !node23 || + !node31 || !node14 || !node24 || !node34 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node12, node23, + node31, node14, node24, node34, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(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) +{ + 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; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + SMDS_MeshNode *node12, *node23, *node34, *node41; + SMDS_MeshNode *node15, *node25, *node35, *node45; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); + node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); + node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); + node35 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35); + node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); + if( !node1 || !node2 || !node3 || !node4 || !node5 || + !node12 || !node23 || !node34 || !node41 || + !node15 || !node25 || !node35 || !node45 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, + node12, node23, node34, node41, + node15, node25, node35, node45, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, + n34,n41,n15,n25,n35,n45); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(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) +{ + 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; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + SMDS_MeshNode *node12, *node23, *node31; + SMDS_MeshNode *node45, *node56, *node64; + SMDS_MeshNode *node14, *node25, *node36; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); + node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); + node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); + node64 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64); + node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); + node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); + node36 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36); + if( !node1 || !node2 || !node3 || !node4 || !node5 || !node6 || + !node12 || !node23 || !node31 || !node45 || !node56 || + !node64 || !node14 || !node25 || !node36 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node12, node23, node31, node45, node56, + node64, node14, node25, node36, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron with 15 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(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) +{ + 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; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4; + SMDS_MeshNode *node5, *node6, *node7, *node8; + SMDS_MeshNode *node12, *node23, *node34, *node41; + SMDS_MeshNode *node56, *node67, *node78, *node85; + SMDS_MeshNode *node15, *node26, *node37, *node48; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); + node7 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7); + node8 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); + node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); + node67 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67); + node78 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78); + node85 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85); + node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); + node26 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26); + node37 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37); + node48 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48); + if( !node1 || !node2 || !node3 || !node4 || + !node5 || !node6 || !node7 || !node8 || + !node12 || !node23 || !node34 || !node41 || + !node56 || !node67 || !node78 || !node85 || + !node15 || !node26 || !node37 || !node48 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, + node5, node6, node7, node8, + node12, node23, node34, node41, + node56, node67, node78, node85, + node15, node26, node37, node48, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 11f201cc8..00db00fa1 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -50,15 +50,6 @@ #include #include -typedef SMDS_Iterator SMDS_NodeIterator; -typedef boost::shared_ptr > SMDS_NodeIteratorPtr; -typedef SMDS_Iterator SMDS_EdgeIterator; -typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; -typedef SMDS_Iterator SMDS_FaceIterator; -typedef boost::shared_ptr > SMDS_FaceIteratorPtr; -typedef SMDS_Iterator SMDS_VolumeIterator; -typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; - class SMDS_WNT_EXPORT SMDS_Mesh:public SMDS_MeshObject{ public: @@ -84,6 +75,16 @@ public: virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -120,6 +121,44 @@ public: const SMDS_MeshEdge * e3, const SMDS_MeshEdge * e4); + // 2d order triangle of 6 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + // 2d order quadrangle + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID); + virtual SMDS_MeshFace* AddFaceWithID(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, + int ID); + virtual SMDS_MeshFace* AddFace(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 SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -214,6 +253,153 @@ public: const SMDS_MeshFace * f5, const SMDS_MeshFace * f6); + // 2d order tetrahedron of 10 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d order pyramid of 13 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d order Pentahedron with 15 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d oreder Hexahedrons with 20 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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 SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, const int ID); @@ -267,11 +453,19 @@ public: const SMDS_MeshNode *FindNode(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; const SMDS_MeshElement *FindElement(int IDelem) const; static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3); @@ -279,6 +473,20 @@ public: const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4); + static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4, + const SMDS_MeshNode *n5, + const SMDS_MeshNode *n6); + static const SMDS_MeshFace* FindFace(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_MeshFace *FindFace(std::vector nodes_ids) const; static const SMDS_MeshFace* FindFace(std::vector nodes); diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx index 66c8ae3d5..dc1dab968 100644 --- a/src/SMDS/SMDS_MeshEdge.cxx +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -135,6 +135,18 @@ bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2) else return false; } +/*! + * \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 + */ +const SMDS_MeshNode* SMDS_MeshEdge::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + //======================================================================= //function : ChangeNodes //purpose : diff --git a/src/SMDS/SMDS_MeshEdge.hxx b/src/SMDS/SMDS_MeshEdge.hxx index 290210ca3..c99b08198 100644 --- a/src/SMDS/SMDS_MeshEdge.hxx +++ b/src/SMDS/SMDS_MeshEdge.hxx @@ -44,12 +44,22 @@ class SMDS_MeshEdge:public SMDS_MeshElement int NbNodes() const; int NbEdges() const; friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2); + + /*! + * \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 + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; - private: - const SMDS_MeshNode* myNodes[2]; + protected: + const SMDS_MeshNode* myNodes[3]; }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 8d4d9b75d..83f073fdb 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -192,3 +192,29 @@ bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) } return false; } + +bool SMDS_MeshElement::IsValidIndex(const int ind) const +{ + return ( ind>-1 && indnext(); + if ( it->more() ) + return static_cast (it->next()); + return 0; +} + +bool SMDS_MeshElement::IsQuadratic() const +{ + return false; +} + +bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const +{ + return false; +} diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 73870b707..67ac8f247 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -56,32 +56,64 @@ class SMDS_MeshFace; /////////////////////////////////////////////////////////////////////////////// class SMDS_WNT_EXPORT SMDS_MeshElement:public SMDS_MeshObject { +public: - public: - SMDS_ElemIteratorPtr nodesIterator() const; - SMDS_ElemIteratorPtr edgesIterator() const; - SMDS_ElemIteratorPtr facesIterator() const; - virtual SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; + SMDS_ElemIteratorPtr nodesIterator() const; + SMDS_ElemIteratorPtr edgesIterator() const; + SMDS_ElemIteratorPtr facesIterator() const; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; - virtual int NbNodes() const; - virtual int NbEdges() const; - virtual int NbFaces() const; - int GetID() const; + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + int GetID() const; - ///Return the type of the current element - virtual SMDSAbs_ElementType GetType() const = 0; - virtual bool IsPoly() const { return false; }; + ///Return the type of the current element + virtual SMDSAbs_ElementType GetType() const = 0; + virtual bool IsPoly() const { return false; }; + virtual bool IsQuadratic() const; - friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); - friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; - protected: - SMDS_MeshElement(int ID=-1); - virtual void Print(std::ostream & OS) const; - - private: - int myID; + friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); + friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + + // =========================== + // Access to nodes by index + // =========================== + /*! + * \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 + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + /*! + * \brief Return true if index of node is valid (0 <= ind < NbNodes()) + * \param ind - node index + * \retval bool - index check result + */ + virtual bool IsValidIndex(const int ind) const; + + /*! + * \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 { + if ( ind < 0 ) return -( ind % NbNodes()); + if ( ind >= NbNodes() ) return ind % NbNodes(); + return ind; + } + +protected: + SMDS_MeshElement(int ID=-1); + virtual void Print(std::ostream & OS) const; + +private: + int myID; }; #endif diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index 042a1734a..fad622534 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -64,6 +64,15 @@ class SMDS_WNT_EXPORT SMDS_MeshNode:public SMDS_MeshElement void setXYZ(double x, double y, double z); friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); + /*! + * \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 + */ + virtual const SMDS_MeshNode* GetNode(const int) const { return this; } + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx index 38abf18c2..568bd34d0 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx @@ -26,7 +26,7 @@ #include "SMDS_PolygonalFaceOfNodes.hxx" #include "SMDS_IteratorOfElements.hxx" -//#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" #include "utilities.h" using namespace std; @@ -128,28 +128,11 @@ void SMDS_PolygonalFaceOfNodes::Print(ostream & OS) const //function : elementsIterator //purpose : //======================================================================= -class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator { - //const SMDS_MeshNode* const *mySet; - const std::vector mySet; - //int myLength; - int index; public: - //SMDS_PolygonalFaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l): - // mySet(s),myLength(l),index(0) {} - SMDS_PolygonalFaceOfNodes_MyIterator(const std::vector s): - mySet(s),index(0) {} - - bool more() - { - return index < mySet.size(); - } - - const SMDS_MeshElement* next() - { - index++; - return mySet[index-1]; - } + SMDS_PolygonalFaceOfNodes_MyIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} }; SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator @@ -172,3 +155,16 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator } return SMDS_ElemIteratorPtr(); } + +/*! + * \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 + */ +const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx index 567746259..c8884b319 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx @@ -50,6 +50,15 @@ class SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace virtual void Print (std::ostream & OS) 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 + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index cd893f484..941f538c3 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -25,6 +25,7 @@ #include "SMDS_VolumeOfNodes.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" #include "utilities.h" using namespace std; @@ -170,29 +171,14 @@ int SMDS_VolumeOfNodes::NbEdges() const return 0; } -class SMDS_VolumeOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { - const SMDS_MeshNode* const* mySet; - int myLength; - int index; public: SMDS_VolumeOfNodes_MyIterator(const SMDS_MeshNode* const* s, int l): - mySet(s),myLength(l),index(0) {} - - bool more() - { - return index EXTERNAL { 1, 2, 6, 5, 1 }}; static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; + +/* +// N3 +// + +// /|\ +// 7/ | \8 +// / |4 \ QUADRATIC +// N0 +---|---+ N1 TETRAHEDRON +// \ +9 / +// \ | / +// 6\ | /5 +// \|/ +// + +// N2 +*/ +static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL + { 0, 4, 1, 5, 2, 6, 0 }, // All faces have external normals + { 0, 7, 3, 8, 1, 4, 0 }, + { 1, 8, 3, 9, 2, 5, 1 }, + { 0, 6, 2, 9, 3, 7, 0 }}; +static int QuadTetra_R [4][7] = { // REVERSED + { 0, 4, 1, 5, 2, 6, 0 }, // All faces but a bottom have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 6, 2, 5, 1, 4, 0 }, // All faces have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_nbN [] = { 6, 6, 6, 6 }; + +// +// QUADRATIC +// PYRAMID +// +// +4 +// +// +// 10+-----+11 +// | | 9 - middle point for (0,4) etc. +// | | +// 9+-----+12 +// +// 6 +// 1+----+----+2 +// | | +// | | +// 5+ +7 +// | | +// | | +// 0+----+----+3 +// 8 +static int QuadPyram_F [5][9] = { // FORWARD == EXTERNAL + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces have external normals + { 0, 9, 4, 10,1, 5, 0, 4, 4 }, + { 1, 10,4, 11,2, 6, 1, 4, 4 }, + { 2, 11,4, 12,3, 7, 2, 4, 4 }, + { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; +static int QuadPyram_R [5][9] = { // REVERSED + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 8, 3, 7, 2, 6, 1, 5, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 }; + +/* +// + N4 +// /|\ +// 9/ | \10 +// / | \ +// / | \ +// N3 +----+----+ N5 +// | |11 | +// | | | +// | +13 | QUADRATIC +// | | | PENTAHEDRON +// | | | +// | | | +// | | | +// 12+ | +14 +// | | | +// | | | +// | + N1 | +// | / \ | +// | 6/ \7 | +// | / \ | +// |/ \| +// N0 +---------+ N2 +// 8 +*/ +static int QuadPenta_F [5][9] = { // FORWARD + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Top face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_R [5][9] = { // REVERSED + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Bottom face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, + { 3,11, 5, 10,4, 9, 3, 3, 3 }, + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL + { 0, 8, 2, 7, 1, 6, 0, 0, 0 }, + { 3, 9, 4, 10,5, 11,3, 3, 3 }, + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 }; + +/* +// 13 +// N5+-----+-----+N6 +// /| /| +// 12+ | 14+ | +// / | / | +// N4+-----+-----+N7 | QUADRATIC +// | | 15 | | HEXAHEDRON +// | | | | +// | 17+ | +18 +// | | | | +// | | | | +// | | | | +// 16+ | +19 | +// | | | | +// | | 9 | | +// | N1+-----+-|---+N2 +// | / | / +// | +8 | +10 +// |/ |/ +// N0+-----+-----+N3 +// 11 +*/ +static int QuadHexa_F [6][9] = { // FORWARD + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // odd face(1,3,5) normal is internal, even(0,2,4) - external + { 1, 8, 0, 16,4, 12,5, 17,1 }, // same index nodes of opposite faces are linked + { 2, 10,3, 19,7, 14,6, 18,2 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +// static int Hexa_R [6][5] = { // REVERSED +// { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, +// { 4, 7, 6, 5, 4 }, // odd face(1,3,5) normal is external, even(0,2,4) - internal +// { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked +// { 2, 6, 7, 3, 2 }, +// { 0, 4, 7, 3, 0 }, +// { 1, 5, 6, 2, 1 }}; +static int QuadHexa_FE [6][9] = { // FORWARD -> EXTERNAL + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 15,7, 14,6, 13,5, 12,4 }, // all face normals are external, + { 0, 16,4, 12,5, 17,1, 8, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 10,2, 18,6, 14,7, 19,3 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 17,5, 13,6, 18,2, 9, 1 }}; +static int QuadHexa_RE [6][9] = { // REVERSED -> EXTERNAL + { 0, 11,3, 10,2, 9, 1, 8, 0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // all face normals are external, + { 0, 8, 1, 17,5, 12,4, 16,0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 19,7, 14,6, 18,2, 10,3 }, + { 0, 16,4, 15,7, 19,3, 11,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 }; + + // ======================================================== // to perform some calculations without linkage to CASCADE // ======================================================== @@ -323,12 +501,17 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) MESSAGE("Warning: bad volumic element"); return false; } - } else { + } + else { switch ( myVolumeNbNodes ) { case 4: case 5: case 6: - case 8: { + case 8: + case 10: + case 13: + case 15: + case 20: { // define volume orientation XYZ botNormal; GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); @@ -387,6 +570,34 @@ void SMDS_VolumeTool::Inverse () SWAP_NODES( myVolumeNodes, 1, 3 ); SWAP_NODES( myVolumeNodes, 5, 7 ); break; + + case 10: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 6 ); + SWAP_NODES( myVolumeNodes, 8, 9 ); + break; + case 13: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 8 ); + SWAP_NODES( myVolumeNodes, 6, 7 ); + SWAP_NODES( myVolumeNodes, 10, 12 ); + break; + case 15: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 5 ); + SWAP_NODES( myVolumeNodes, 6, 8 ); + SWAP_NODES( myVolumeNodes, 9, 11 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + break; + case 20: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 7 ); + SWAP_NODES( myVolumeNodes, 8, 11 ); + SWAP_NODES( myVolumeNodes, 9, 10 ); + SWAP_NODES( myVolumeNodes, 12, 15 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + SWAP_NODES( myVolumeNodes, 17, 19 ); + break; default:; } } @@ -402,14 +613,25 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const return POLYHEDA; if ( myVolume ) { - static const VolumeType types[] = { - TETRA, // myVolumeNbNodes = 4 - PYRAM, // myVolumeNbNodes = 5 - PENTA, // myVolumeNbNodes = 6 - UNKNOWN, // myVolumeNbNodes = 7 - HEXA // myVolumeNbNodes = 8 - }; - return types[ myVolumeNbNodes - 4 ]; +// static const VolumeType types[] = { +// TETRA, // myVolumeNbNodes = 4 +// PYRAM, // myVolumeNbNodes = 5 +// PENTA, // myVolumeNbNodes = 6 +// UNKNOWN, // myVolumeNbNodes = 7 +// HEXA // myVolumeNbNodes = 8 +// }; +// return types[ myVolumeNbNodes - 4 ]; + switch(myVolumeNbNodes) { + case 4: return TETRA; break; + case 5: return PYRAM; break; + case 6: return PENTA; break; + case 8: return HEXA; break; + case 10: return QUAD_TETRA; break; + case 13: return QUAD_PYRAM; break; + case 15: return QUAD_PENTA; break; + case 20: return QUAD_HEXA; break; + default: break; + } } return UNKNOWN; @@ -491,7 +713,7 @@ double SMDS_VolumeTool::GetSize() const else { const static int ind[] = { - 0, 1, 3, 6, 11 }; + 0, 1, 3, 6, 11, 19, 32, 46, 66}; const static int vtab[][4] = { // tetrahedron { 0, 1, 2, 3 }, @@ -507,15 +729,80 @@ double SMDS_VolumeTool::GetSize() const { 4, 1, 6, 5 }, { 1, 3, 6, 2 }, { 4, 6, 3, 7 }, - { 1, 4, 6, 3 } + { 1, 4, 6, 3 }, + + // quadratic tetrahedron + { 0, 4, 6, 7 }, + { 1, 5, 4, 8 }, + { 2, 6, 5, 9 }, + { 7, 8, 9, 3 }, + { 4, 6, 7, 9 }, + { 4, 5, 6, 9 }, + { 4, 7, 8, 9 }, + { 4, 5, 9, 8 }, + + // quadratic pyramid + { 0, 5, 8, 9 }, + { 1, 5,10, 6 }, + { 2, 6,11, 7 }, + { 3, 7,12, 8 }, + { 4, 9,11,10 }, + { 4, 9,12,11 }, + { 10, 5, 9, 8 }, + { 10, 8, 9,12 }, + { 10, 8,12, 7 }, + { 10, 7,12,11 }, + { 10, 7,11, 6 }, + { 10, 5, 8, 6 }, + { 10, 6, 8, 7 }, + + // quadratic pentahedron + { 12, 0, 8, 6 }, + { 12, 8, 7, 6 }, + { 12, 8, 2, 7 }, + { 12, 6, 7, 1 }, + { 12, 1, 7,13 }, + { 12, 7, 2,13 }, + { 12, 2,14,13 }, + + { 12, 3, 9,11 }, + { 12,11, 9,10 }, + { 12,11,10, 5 }, + { 12, 9, 4,10 }, + { 12,14, 5,10 }, + { 12,14,10, 4 }, + { 12,14, 4,13 }, + + // quadratic hexahedron + { 16, 0,11, 8 }, + { 16,11, 9, 8 }, + { 16, 8, 9, 1 }, + { 16,11, 3,10 }, + { 16,11,10, 9 }, + { 16,10, 2, 9 }, + { 16, 3,19, 2 }, + { 16, 2,19,18 }, + { 16, 2,18,17 }, + { 16, 2,17, 1 }, + + { 16, 4,12,15 }, + { 16,12, 5,13 }, + { 16,12,13,15 }, + { 16,13, 6,14 }, + { 16,13,14,15 }, + { 16,14, 7,15 }, + { 16, 6, 5,17 }, + { 16,18, 6,17 }, + { 16,18, 7, 6 }, + { 16,18,19, 7 }, + }; int type = GetVolumeType(); int n1 = ind[type]; int n2 = ind[type+1]; - for (int i = n1; i < n2; i++) - { + for (int i = n1; i < n2; i++) { V -= getTetraVolume( myVolumeNodes[ vtab[i][0] ], myVolumeNodes[ vtab[i][1] ], myVolumeNodes[ vtab[i][2] ], @@ -647,12 +934,16 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) switch ( myVolumeNbNodes ) { case 4: case 5: + case 10: + case 13: // only the bottom of a reversed tetrahedron can be internal return ( myVolForward || faceIndex != 0 ); case 6: + case 15: // in a forward pentahedron, the top is internal, in a reversed one - bottom return ( myVolForward ? faceIndex != 1 : faceIndex != 0 ); - case 8: { + case 8: + case 20: { // in a forward hexahedron, even face normal is external, odd - internal bool odd = faceIndex % 2; return ( myVolForward ? !odd : odd ); @@ -679,7 +970,8 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub XYZ aVec13( p3 - p1 ); XYZ cross = aVec12.Crossed( aVec13 ); - if ( myFaceNbNodes == 4 ) { + //if ( myFaceNbNodes == 4 ) { + if ( myFaceNbNodes >3 ) { XYZ p4 ( myFaceNodes[3] ); XYZ aVec14( p4 - p1 ); XYZ cross2 = aVec13.Crossed( aVec14 ); @@ -815,7 +1107,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, bool SMDS_VolumeTool::IsLinked (const int theNode1Index, const int theNode2Index) const { - if (myVolume->IsPoly()) { + if ( myVolume->IsPoly() ) { return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]); } @@ -853,6 +1145,57 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; + case 10: + { + switch ( minInd ) { + case 0: if( maxInd==4 || maxInd==6 || maxInd==7 ) return true; + case 1: if( maxInd==4 || maxInd==5 || maxInd==8 ) return true; + case 2: if( maxInd==5 || maxInd==6 || maxInd==9 ) return true; + case 3: if( maxInd==7 || maxInd==8 || maxInd==9 ) return true; + default:; + } + break; + } + case 13: + { + switch ( minInd ) { + case 0: if( maxInd==5 || maxInd==8 || maxInd==9 ) return true; + case 1: if( maxInd==5 || maxInd==6 || maxInd==10 ) return true; + case 2: if( maxInd==6 || maxInd==7 || maxInd==11 ) return true; + case 3: if( maxInd==7 || maxInd==8 || maxInd==12 ) return true; + case 4: if( maxInd==9 || maxInd==10 || maxInd==11 || maxInd==12 ) return true; + default:; + } + break; + } + case 15: + { + switch ( minInd ) { + case 0: if( maxInd==6 || maxInd==8 || maxInd==12 ) return true; + case 1: if( maxInd==6 || maxInd==7 || maxInd==13 ) return true; + case 2: if( maxInd==7 || maxInd==8 || maxInd==14 ) return true; + case 3: if( maxInd==9 || maxInd==11 || maxInd==12 ) return true; + case 4: if( maxInd==9 || maxInd==10 || maxInd==13 ) return true; + case 5: if( maxInd==10 || maxInd==11 || maxInd==14 ) return true; + default:; + } + break; + } + case 20: + { + switch ( minInd ) { + case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; + case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; + case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; + case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; + case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; + case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; + case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; + case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; + default:; + } + break; + } default:; } return false; @@ -894,8 +1237,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) typedef map< const SMDS_MeshElement*, int > TElemIntMap; TElemIntMap volNbShared; TElemIntMap::iterator vNbIt; - for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) - { + for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { const SMDS_MeshNode* n = nodes[ iNode ]; SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(); while ( eIt->more() ) { @@ -903,10 +1245,12 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) { int nbShared = 1; vNbIt = volNbShared.find( elem ); - if ( vNbIt == volNbShared.end() ) + if ( vNbIt == volNbShared.end() ) { volNbShared.insert ( TElemIntMap::value_type( elem, nbShared )); - else + } + else { nbShared = ++(*vNbIt).second; + } if ( nbShared > maxNbShared ) maxNbShared = nbShared; } @@ -922,8 +1266,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) if ( IsFaceExternal( faceIndex )) intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z ); XYZ p0 ( nodes[0] ), baryCenter; - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) - { + for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { int nbShared = (*vNbIt).second; if ( nbShared >= 3 ) { SMDS_VolumeTool volume( (*vNbIt).first ); @@ -935,20 +1278,20 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) // remove a volume from volNbShared map volNbShared.erase( vNbIt ); } + // here volNbShared contains only volumes laying on the // opposite side of the face - if ( volNbShared.empty() ) + if ( volNbShared.empty() ) { return free; // is free + } // check if the whole area of a face is shared bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) - { + for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { SMDS_VolumeTool volume( (*vNbIt).first ); bool prevLinkShared = false; int nbSharedLinks = 0; - for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) - { + for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] ); if ( linkShared ) nbSharedLinks++; @@ -1059,7 +1402,8 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) } myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first - } else { + } + else { // choose face node indices switch ( myVolumeNbNodes ) { case 4: @@ -1090,6 +1434,34 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) else myFaceNodeIndices = Hexa_F[ faceIndex ]; break; + case 10: + myFaceNbNodes = QuadTetra_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ]; + break; + case 13: + myFaceNbNodes = QuadPyram_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ]; + break; + case 15: + myFaceNbNodes = QuadPenta_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ]; + break; + case 20: + myFaceNbNodes = QuadHexa_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ]; + else + myFaceNodeIndices = QuadHexa_F[ faceIndex ]; + break; default: return false; } @@ -1118,6 +1490,10 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes) case 5: return PYRAM; case 6: return PENTA; case 8: return HEXA; + case 10: return QUAD_TETRA; + case 13: return QUAD_PYRAM; + case 15: return QUAD_PENTA; + case 20: return QUAD_HEXA; default:return UNKNOWN; } } @@ -1130,10 +1506,14 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes) int SMDS_VolumeTool::NbFaces( VolumeType type ) { switch ( type ) { - case TETRA: return 4; - case PYRAM: return 5; - case PENTA: return 5; - case HEXA : return 6; + case TETRA : + case QUAD_TETRA: return 4; + case PYRAM : + case QUAD_PYRAM: return 5; + case PENTA : + case QUAD_PENTA: return 5; + case HEXA : + case QUAD_HEXA : return 6; default: return 0; } } @@ -1155,6 +1535,10 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type, case PYRAM: return Pyramid_F[ faceIndex ]; case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ]; case HEXA: return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ]; + case QUAD_TETRA: return QuadTetra_F[ faceIndex ]; + case QUAD_PYRAM: return QuadPyram_F[ faceIndex ]; + case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ]; + case QUAD_HEXA: return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ]; default:; } return 0; @@ -1173,6 +1557,10 @@ int SMDS_VolumeTool::NbFaceNodes(VolumeType type, case PYRAM: return Pyramid_nbN[ faceIndex ]; case PENTA: return Penta_nbN[ faceIndex ]; case HEXA: return Hexa_nbN[ faceIndex ]; + case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ]; + case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ]; + case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ]; + case QUAD_HEXA: return QuadHexa_nbN[ faceIndex ]; default:; } return 0; diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index beec061b7..b5528c10e 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -61,7 +61,8 @@ class SMDS_WNT_EXPORT SMDS_VolumeTool { public: - enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, POLYHEDA }; + enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, QUAD_TETRA, + QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, POLYHEDA }; SMDS_VolumeTool (); ~SMDS_VolumeTool (); diff --git a/src/SMESH/Makefile.in b/src/SMESH/Makefile.in index a311488eb..12c077a7d 100644 --- a/src/SMESH/Makefile.in +++ b/src/SMESH/Makefile.in @@ -39,6 +39,7 @@ EXPORT_HEADERS= \ SMESH_Mesh.hxx \ SMESH_subMesh.hxx \ SMESH_Hypothesis.hxx \ + SMESH_HypoFilter.hxx \ SMESH_Algo.hxx \ SMESH_1D_Algo.hxx \ SMESH_2D_Algo.hxx \ diff --git a/src/SMESH/SMESH_2D_Algo.cxx b/src/SMESH/SMESH_2D_Algo.cxx index d1084f7d4..1c9af478a 100644 --- a/src/SMESH/SMESH_2D_Algo.cxx +++ b/src/SMESH/SMESH_2D_Algo.cxx @@ -29,7 +29,7 @@ using namespace std; #include "SMESH_2D_Algo.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_subMesh.hxx" +#include #include "utilities.h" @@ -80,13 +80,14 @@ int SMESH_2D_Algo::NumberOfWires(const TopoDS_Shape& S) int SMESH_2D_Algo::NumberOfPoints(SMESH_Mesh& aMesh, const TopoDS_Wire& W) { int nbPoints = 0; - for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) - { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - //SCRUTE(nb); - nbPoints += nb +1; // internal points plus 1 vertex of 2 (last point ?) - } - //SCRUTE(nbPoints); + for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + if(_quadraticMesh) + nb = nb/2; + nbPoints += nb + 1; // internal points plus 1 vertex of 2 (last point ?) + } return nbPoints; } + + diff --git a/src/SMESH/SMESH_2D_Algo.hxx b/src/SMESH/SMESH_2D_Algo.hxx index 5c904e22e..259a51157 100644 --- a/src/SMESH/SMESH_2D_Algo.hxx +++ b/src/SMESH/SMESH_2D_Algo.hxx @@ -30,7 +30,8 @@ #define _SMESH_2D_ALGO_HXX_ #include "SMESH_Algo.hxx" -#include +#include "SMESH_subMesh.hxx" +#include "TopoDS_Wire.hxx" class SMESH_2D_Algo: public SMESH_Algo @@ -41,6 +42,7 @@ public: int NumberOfWires(const TopoDS_Shape& S); int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W); + }; #endif diff --git a/src/SMESH/SMESH_3D_Algo.cxx b/src/SMESH/SMESH_3D_Algo.cxx index d42680f62..6a05c16af 100644 --- a/src/SMESH/SMESH_3D_Algo.cxx +++ b/src/SMESH/SMESH_3D_Algo.cxx @@ -29,7 +29,6 @@ using namespace std; #include "SMESH_3D_Algo.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_subMesh.hxx" #include "utilities.h" @@ -56,3 +55,5 @@ SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen) SMESH_3D_Algo::~SMESH_3D_Algo() { } + + diff --git a/src/SMESH/SMESH_3D_Algo.hxx b/src/SMESH/SMESH_3D_Algo.hxx index 62621ce3c..21c53ca0f 100644 --- a/src/SMESH/SMESH_3D_Algo.hxx +++ b/src/SMESH/SMESH_3D_Algo.hxx @@ -37,6 +37,7 @@ class SMESH_3D_Algo: public: SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen); virtual ~SMESH_3D_Algo(); + }; #endif diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 3cddc41e7..94803ac7c 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -69,6 +69,7 @@ SMESH_Algo::SMESH_Algo(int hypId, int studyId, gen->_mapAlgo[hypId] = this; _onlyUnaryInput = _requireDescretBoundary = true; + _quadraticMesh = false; } //============================================================================= @@ -102,18 +103,17 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis() */ //============================================================================= -const list & SMESH_Algo::GetUsedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _usedHypList.clear(); - if ( !_compatibleHypothesis.empty() ) + SMESH_HypoFilter filter; + if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) { - SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] )); - for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) - filter.Or( filter.HasName( _compatibleHypothesis[ i ] )); - aMesh.GetHypotheses( aShape, filter, _usedHypList, true ); - if ( _usedHypList.size() > 1 ) + if ( ignoreAuxiliary && _usedHypList.size() > 1 ) _usedHypList.clear(); //only one compatible hypothesis allowed } return _usedHypList; @@ -127,18 +127,16 @@ const list & SMESH_Algo::GetUsedHypothesis( */ //============================================================================= -const list & SMESH_Algo::GetAppliedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +SMESH_Algo::GetAppliedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _appliedHypList.clear(); - if ( !_compatibleHypothesis.empty() ) - { - SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] )); - for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) - filter.Or( filter.HasName( _compatibleHypothesis[ i ] )); - + SMESH_HypoFilter filter; + if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) aMesh.GetHypotheses( aShape, filter, _appliedHypList, false ); - } + return _appliedHypList; } @@ -344,3 +342,28 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, return theParams.size() > 1; } + +//================================================================================ +/*! + * \brief Make filter recognize only compatible hypotheses + * \param theFilter - the filter to initialize + * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses + */ +//================================================================================ + +bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, + const bool ignoreAuxiliary) const +{ + if ( !_compatibleHypothesis.empty() ) + { + theFilter.Init( theFilter.HasName( _compatibleHypothesis[0] )); + for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) + theFilter.Or( theFilter.HasName( _compatibleHypothesis[ i ] )); + + if ( ignoreAuxiliary ) + theFilter.AndNot( theFilter.IsAuxiliary() ); + + return true; + } + return false; +} diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index c92b5893f..57bc4245a 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -33,16 +33,20 @@ #include #include +#include #include #include #include +#include class SMESH_Gen; class SMESH_Mesh; +class SMESH_HypoFilter; class TopoDS_Face; class TopoDS_Shape; class SMESHDS_Mesh; +class SMDS_MeshNode; class SMESH_Algo:public SMESH_Hypothesis { @@ -58,13 +62,27 @@ class SMESH_Algo:public SMESH_Hypothesis virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0; virtual const std::list & - GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary=true); const list & - GetAppliedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetAppliedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary=true); static double EdgeLength(const TopoDS_Edge & E); + + /*! + * \brief Make filter recognize only compatible hypotheses + * \param theFilter - the filter to initialize + * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses + * \retval bool - true if the algo has compatible hypotheses + */ + bool InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, + const bool ignoreAuxiliary) const; + /*! * \brief Fill vector of node parameters on geometrical edge, including vertex nodes * \param theMesh - The mesh containing nodes @@ -121,6 +139,9 @@ class SMESH_Algo:public SMESH_Hypothesis std::vector _compatibleHypothesis; std::list _appliedHypList; std::list _usedHypList; + + // quadratic mesh creation required + bool _quadraticMesh; }; #endif diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index a93b1a4b4..b615ad566 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -633,13 +633,14 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) if ( algoList.empty() ) return NULL; - if (algoList.size() > 1 ) { // check if there is one algo several times - list ::iterator algo = algoList.begin(); - for ( ; algo != algoList.end(); ++algo ) - if ( (*algo) != algoList.front() && - (*algo)->GetName() != algoList.front()->GetName() ) - return NULL; - } + // Now it is checked in SMESH_Mesh::GetHypotheses() +// if (algoList.size() > 1 ) { // check if there is one algo several times +// list ::iterator algo = algoList.begin(); +// for ( ; algo != algoList.end(); ++algo ) +// if ( (*algo) != algoList.front() && +// (*algo)->GetName() != algoList.front()->GetName() ) +// return NULL; +// } return const_cast ( static_cast( algoList.front() )); } diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx index ff14016d8..3482b1d57 100644 --- a/src/SMESH/SMESH_HypoFilter.cxx +++ b/src/SMESH/SMESH_HypoFilter.cxx @@ -75,6 +75,17 @@ bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp, return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType ); }; +//======================================================================= +//function : IsAuxiliaryPredicate::IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::IsAuxiliaryPredicate::IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& /*aShape*/) const +{ + return aHyp->IsAuxiliary(); +}; + //======================================================================= //function : ApplicablePredicate::ApplicablePredicate //purpose : @@ -190,6 +201,17 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo() return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO ); } +//======================================================================= +//function : IsAuxiliary +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::IsAuxiliary() +{ + return new IsAuxiliaryPredicate(); +} + + //======================================================================= //function : IsGlobal //purpose : diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx index 6bc34bf53..9638495d1 100644 --- a/src/SMESH/SMESH_HypoFilter.hxx +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -67,6 +67,7 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate // Create predicates static SMESH_HypoPredicate* IsAlgo(); + static SMESH_HypoPredicate* IsAuxiliary(); static SMESH_HypoPredicate* IsApplicableTo(const TopoDS_Shape& theShape); static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape); static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo); @@ -158,6 +159,11 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate const TopoDS_Shape& aShape) const; }; + struct IsAuxiliaryPredicate : public SMESH_HypoPredicate { + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + }; diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 0107c3e36..268581791 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -72,13 +72,14 @@ SMESH_Hypothesis::~SMESH_Hypothesis() int SMESH_Hypothesis::GetDim() const { - int dim = -1; + int dim = 0; switch (_type) { case ALGO_1D: dim = 1; break; case ALGO_2D: dim = 2; break; case ALGO_3D: dim = 3; break; - case PARAM_ALGO: dim = _param_algo_dim; break; + case PARAM_ALGO: + dim = ( _param_algo_dim < 0 ) ? -_param_algo_dim : _param_algo_dim; break; } return dim; } @@ -124,14 +125,15 @@ void SMESH_Hypothesis::NotifySubMeshesHypothesisModification() itm++) { SMESH_Mesh* mesh = (*itm).second; - const list& subMeshes = - mesh->GetSubMeshUsingHypothesis(this); + mesh->NotifySubMeshesHypothesisModification( this ); +// const list& subMeshes = +// mesh->GetSubMeshUsingHypothesis(this); - //for all subMeshes using hypothesis +// //for all subMeshes using hypothesis - list::const_iterator its; - for (its = subMeshes.begin(); its != subMeshes.end(); its++) - (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); +// list::const_iterator its; +// for (its = subMeshes.begin(); its != subMeshes.end(); its++) +// (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); } } diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx index 2ebd25a39..d7a12f9a0 100644 --- a/src/SMESH/SMESH_Hypothesis.hxx +++ b/src/SMESH/SMESH_Hypothesis.hxx @@ -57,11 +57,11 @@ public: SMESH_Hypothesis(int hypId, int studyId, SMESH_Gen* gen); virtual ~SMESH_Hypothesis(); - int GetDim() const; + virtual int GetDim() const; int GetStudyId() const; - void NotifySubMeshesHypothesisModification(); - int GetShapeType() const; - const char* GetLibName() const; + virtual void NotifySubMeshesHypothesisModification(); + virtual int GetShapeType() const; + virtual const char* GetLibName() const; void SetLibName(const char* theLibName); /*! @@ -72,6 +72,17 @@ public: */ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape)=0; + /*! + * \brief Return true if me is an auxiliary hypothesis + * \retval bool - auxiliary or not + * + * An auxiliary hypothesis is optional, i.e. an algorithm + * can work without it and another hypothesis of the same + * dimention can be assigned to the shape + */ + virtual bool IsAuxiliary() const + { return GetType() == PARAM_ALGO && _param_algo_dim <= 0; } + protected: SMESH_Gen* _gen; int _studyId; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a8089b04f..cd33d40a3 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -526,45 +526,62 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS //purpose : //======================================================================= -bool SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors) const +//================================================================================ +/*! + * \brief Return hypothesis assigned to the shape + * \param aSubShape - the shape to check + * \param aFilter - the hypothesis filter + * \param aHypList - the list of the found hypotheses + * \param andAncestors - flag to check hypos assigned to ancestors of the shape + * \retval int - number of unique hypos in aHypList + */ +//================================================================================ + +int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + list & aHypList, + const bool andAncestors) const { - int nbHyp = 0; + set hypTypes; // to exclude same type hypos from the result list + int nbHyps = 0; + + // fill in hypTypes + list::const_iterator hyp; + for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) + if ( hypTypes.insert( (*hyp)->GetName() ).second ) + nbHyps++; + + // get hypos from aSubShape { const list& hypList = _myMeshDS->GetHypothesis(aSubShape); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if ( aFilter.IsOk (static_cast( *hyp ), aSubShape)) { + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if ( aFilter.IsOk (static_cast( *hyp ), aSubShape) && + hypTypes.insert( (*hyp)->GetName() ).second ) + { aHypList.push_back( *hyp ); - nbHyp++; + nbHyps++; } } - // get hypos from shape of one type only: if any hypo is found on edge, do - // not look up on faces - if ( !nbHyp && andAncestors ) + + // get hypos from ancestors of aSubShape + if ( andAncestors ) { TopTools_MapOfShape map; TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - int shapeType = it.More() ? it.Value().ShapeType() : TopAbs_SHAPE; for (; it.More(); it.Next() ) { - if ( nbHyp && shapeType != it.Value().ShapeType() ) - break; - shapeType = it.Value().ShapeType(); - if ( !map.Add( it.Value() )) + if ( !map.Add( it.Value() )) continue; const list& hypList = _myMeshDS->GetHypothesis(it.Value()); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if (aFilter.IsOk( static_cast( *hyp ), it.Value() )) { - aHypList.push_back( *hyp ); - nbHyp++; - } + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if (aFilter.IsOk( static_cast( *hyp ), it.Value() ) && + hypTypes.insert( (*hyp)->GetName() ).second ) { + aHypList.push_back( *hyp ); + nbHyps++; + } } } - return nbHyp; + return !aHypList.empty(); } //============================================================================= @@ -696,15 +713,17 @@ throw(SALOME_Exception) //======================================================================= bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape) + const SMESH_subMesh* aSubMesh) { SMESH_Hypothesis* hyp = static_cast(anHyp); - // check if anHyp is applicable to aSubShape - SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape ); - if ( !subMesh || !subMesh->IsApplicableHypotesis( hyp )) + + // check if anHyp can be used to mesh aSubMesh + if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp )) return false; - SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape); + const TopoDS_Shape & aSubShape = const_cast( aSubMesh )->GetSubShape(); + + SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape ); // algorithm if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) @@ -714,17 +733,19 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, if (algo) { // look trough hypotheses used by algo - const list &usedHyps = - algo->GetUsedHypothesis(*this, aSubShape); - return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + SMESH_HypoFilter hypoKind; + if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) { + list usedHyps; + if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true )) + return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + } } // look through all assigned hypotheses - SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); - return GetHypothesis( aSubShape, filter, true ); + //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); + return false; //GetHypothesis( aSubShape, filter, true ); } - //============================================================================= /*! * @@ -732,20 +753,78 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, //============================================================================= const list < SMESH_subMesh * >& - SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) -throw(SALOME_Exception) +SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) + throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); + map < int, SMESH_subMesh * >::iterator itsm; + _subMeshesUsingHypothesisList.clear(); + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( IsUsedHypothesis ( anHyp, aSubMesh )) + _subMeshesUsingHypothesisList.push_back(aSubMesh); + } + return _subMeshesUsingHypothesisList; +} + +//======================================================================= +//function : NotifySubMeshesHypothesisModification +//purpose : Say all submeshes using theChangedHyp that it has been modified +//======================================================================= + +void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp) { Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); - map < int, SMESH_subMesh * >::iterator itsm; - _subMeshesUsingHypothesisList.clear(); - for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) - { - SMESH_subMesh *aSubMesh = (*itsm).second; - if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() )) - _subMeshesUsingHypothesisList.push_back(aSubMesh); - } - return _subMeshesUsingHypothesisList; + + const SMESH_Hypothesis* hyp = static_cast(theChangedHyp); + + const SMESH_Algo *foundAlgo = 0; + SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() ); + SMESH_HypoFilter compatibleHypoKind; + list usedHyps; + + + map < int, SMESH_subMesh * >::iterator itsm; + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( aSubMesh->IsApplicableHypotesis( hyp )) + { + const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); + + if ( !foundAlgo ) // init filter for algo search + algoKind.And( algoKind.IsApplicableTo( aSubShape )); + + const SMESH_Algo *algo = static_cast + ( GetHypothesis( aSubShape, algoKind, true )); + + if ( algo ) + { + bool sameAlgo = ( algo == foundAlgo ); + if ( !sameAlgo && foundAlgo ) + sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0); + + if ( !sameAlgo ) { // init filter for used hypos search + if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() )) + continue; // algo does not use any hypothesis + foundAlgo = algo; + } + + // check if hyp is used by algo + usedHyps.clear(); + if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) && + find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ) + { + aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); + + if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape )) + CleanMeshOnPropagationChain( aSubShape ); + } + } + } + } } //============================================================================= @@ -895,7 +974,8 @@ int SMESH_Mesh::NbTriangles() throw(SALOME_Exception) const SMDS_MeshFace * curFace; while (itFaces->more()) { curFace = itFaces->next(); - if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++; + if ( !curFace->IsPoly() && + ( curFace->NbNodes()==3 || curFace->NbNodes()==6 ) ) Nb++; } return Nb; } @@ -913,7 +993,8 @@ int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception) const SMDS_MeshFace * curFace; while (itFaces->more()) { curFace = itFaces->next(); - if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++; + if ( !curFace->IsPoly() && + ( curFace->NbNodes() == 4 || curFace->NbNodes()==8 ) ) Nb++; } return Nb; } @@ -951,7 +1032,8 @@ int SMESH_Mesh::NbTetras() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 4 || curVolume->NbNodes()==10 ) ) Nb++; } return Nb; } @@ -965,7 +1047,8 @@ int SMESH_Mesh::NbHexas() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 8 || curVolume->NbNodes()==20 ) ) Nb++; } return Nb; } @@ -979,7 +1062,8 @@ int SMESH_Mesh::NbPyramids() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 5 || curVolume->NbNodes()==13 ) ) Nb++; } return Nb; } @@ -993,7 +1077,8 @@ int SMESH_Mesh::NbPrisms() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 6 || curVolume->NbNodes()==15 ) ) Nb++; } return Nb; } diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 5d4e16bae..27d2a182b 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -110,10 +110,10 @@ public: const SMESH_HypoFilter& aFilter, const bool andAncestors) const; - bool GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors) const; + int GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + list & aHypList, + const bool andAncestors) const; const list & GetLog() throw(SALOME_Exception); @@ -134,12 +134,15 @@ public: SMESH_subMesh *GetSubMeshContaining(const int aShapeID) throw(SALOME_Exception); + void NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp); + // Say all submeshes that theChangedHyp has been modified + const list < SMESH_subMesh * >& GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) throw(SALOME_Exception); - bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape); + bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, + const SMESH_subMesh * aSubMesh); // Return True if anHyp is used to mesh aSubShape bool IsNotConformAllowed() const; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index d75adf3e7..ea1334bfb 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -34,6 +34,7 @@ #include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" @@ -75,8 +76,12 @@ typedef map > TElemOfNode typedef map > TElemOfElemListMap; typedef map > TNodeOfNodeListMap; typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr; +//typedef map > TNodeOfNodeVecMap; +//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr; typedef map > TElemOfVecOfNnlmiMap; +//typedef map > TElemOfVecOfMapNodesMap; +typedef pair NLink; //======================================================================= //function : SMESH_MeshEditor @@ -102,8 +107,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, set< SMESH_subMesh *> smmap; list::const_iterator it = theIDs.begin(); - for ( ; it != theIDs.end(); it++ ) - { + for ( ; it != theIDs.end(); it++ ) { const SMDS_MeshElement * elem; if ( isNodes ) elem = aMesh->FindNode( *it ); @@ -114,8 +118,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, // Find sub-meshes to notify about modification SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) - { + while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); const SMDS_PositionPtr& aPosition = node->GetPosition(); if ( aPosition.get() ) { @@ -142,6 +145,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, for ( smIt = smmap.begin(); smIt != smmap.end(); smIt++ ) (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); } + return true; } @@ -157,8 +161,7 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) if ( aMesh->ShapeToMesh().IsNull() ) return 0; - if ( theElem->GetType() == SMDSAbs_Node ) - { + if ( theElem->GetType() == SMDSAbs_Node ) { const SMDS_PositionPtr& aPosition = static_cast( theElem )->GetPosition(); if ( aPosition.get() ) @@ -169,25 +172,22 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) TopoDS_Shape aShape; // the shape a node is on SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); - while ( nodeIt->more() ) - { + while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); const SMDS_PositionPtr& aPosition = node->GetPosition(); if ( aPosition.get() ) { - int aShapeID = aPosition->GetShapeId(); - SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); - if ( sm ) - { - if ( sm->Contains( theElem )) - return aShapeID; - if ( aShape.IsNull() ) - aShape = aMesh->IndexToShape( aShapeID ); - } - else - { - //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID ); - } + int aShapeID = aPosition->GetShapeId(); + SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); + if ( sm ) { + if ( sm->Contains( theElem )) + return aShapeID; + if ( aShape.IsNull() ) + aShape = aMesh->IndexToShape( aShapeID ); + } + else { + //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID ); } + } } // None of nodes is on a proper shape, @@ -197,17 +197,89 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) return 0; } TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape )); - for ( ; ancIt.More(); ancIt.Next() ) - { - SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); - if ( sm && sm->Contains( theElem )) - return aMesh->ShapeToIndex( ancIt.Value() ); + for ( ; ancIt.More(); ancIt.Next() ) { + SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); + if ( sm && sm->Contains( theElem )) + return aMesh->ShapeToIndex( ancIt.Value() ); } //MESSAGE ("::FindShape() - SHAPE NOT FOUND") return 0; } +//======================================================================= +//function : ShiftNodesQuadTria +//purpose : auxilary +// Shift nodes in the array corresponded to quadratic triangle +// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3) +//======================================================================= +static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[]) +{ + const SMDS_MeshNode* nd1 = aNodes[0]; + aNodes[0] = aNodes[1]; + aNodes[1] = aNodes[2]; + aNodes[2] = nd1; + const SMDS_MeshNode* nd2 = aNodes[3]; + aNodes[3] = aNodes[4]; + aNodes[4] = aNodes[5]; + aNodes[5] = nd2; +} + +//======================================================================= +//function : GetNodesFromTwoTria +//purpose : auxilary +// Shift nodes in the array corresponded to quadratic triangle +// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3) +//======================================================================= +static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1, + const SMDS_MeshElement * theTria2, + const SMDS_MeshNode* N1[], + const SMDS_MeshNode* N2[]) +{ + SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); + int i=0; + while(i<6) { + N1[i] = static_cast( it->next() ); + i++; + } + if(it->more()) return false; + it = theTria2->nodesIterator(); + i=0; + while(i<6) { + N2[i] = static_cast( it->next() ); + i++; + } + if(it->more()) return false; + + int sames[3] = {-1,-1,-1}; + int nbsames = 0; + int j; + for(i=0; i<3; i++) { + for(j=0; j<3; j++) { + if(N1[i]==N2[j]) { + sames[i] = j; + nbsames++; + break; + } + } + } + if(nbsames!=2) return false; + if(sames[0]>-1) { + ShiftNodesQuadTria(N1); + if(sames[1]>-1) { + ShiftNodesQuadTria(N1); + } + } + i = sames[0] + sames[1] + sames[2]; + for(; i<2; i++) { + ShiftNodesQuadTria(N2); + } + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + return true; +} + //======================================================================= //function : InverseDiag //purpose : Replace two neighbour triangles with ones built on the same 4 nodes @@ -220,71 +292,116 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, { if (!theTria1 || !theTria2) return false; + const SMDS_FaceOfNodes* F1 = dynamic_cast( theTria1 ); - if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( theTria2 ); - if (!F2) return false; + if (F1 && F2) { - // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A - // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | - // |/ | | \| - // B +--+ 2 B +--+ 2 + // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A + // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | + // |/ | | \| + // B +--+ 2 B +--+ 2 - // put nodes in array and find out indices of the same ones - const SMDS_MeshNode* aNodes [6]; - int sameInd [] = { 0, 0, 0, 0, 0, 0 }; - int i = 0; - SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); - while ( it->more() ) - { - aNodes[ i ] = static_cast( it->next() ); - - if ( i > 2 ) // theTria2 - // find same node of theTria1 - for ( int j = 0; j < 3; j++ ) - if ( aNodes[ i ] == aNodes[ j ]) { - sameInd[ j ] = i; - sameInd[ i ] = j; - break; - } - // next - i++; - if ( i == 3 ) { - if ( it->more() ) - return false; // theTria1 is not a triangle - it = theTria2->nodesIterator(); + // put nodes in array and find out indices of the same ones + const SMDS_MeshNode* aNodes [6]; + int sameInd [] = { 0, 0, 0, 0, 0, 0 }; + int i = 0; + SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); + while ( it->more() ) { + aNodes[ i ] = static_cast( it->next() ); + + if ( i > 2 ) // theTria2 + // find same node of theTria1 + for ( int j = 0; j < 3; j++ ) + if ( aNodes[ i ] == aNodes[ j ]) { + sameInd[ j ] = i; + sameInd[ i ] = j; + break; + } + // next + i++; + if ( i == 3 ) { + if ( it->more() ) + return false; // theTria1 is not a triangle + it = theTria2->nodesIterator(); + } + if ( i == 6 && it->more() ) + return false; // theTria2 is not a triangle } - if ( i == 6 && it->more() ) - return false; // theTria2 is not a triangle - } + + // find indices of 1,2 and of A,B in theTria1 + int iA = 0, iB = 0, i1 = 0, i2 = 0; + for ( i = 0; i < 6; i++ ) { + if ( sameInd [ i ] == 0 ) + if ( i < 3 ) i1 = i; + else i2 = i; + else if (i < 3) + if ( iA ) iB = i; + else iA = i; + } + // nodes 1 and 2 should not be the same + if ( aNodes[ i1 ] == aNodes[ i2 ] ) + return false; + + // theTria1: A->2 + aNodes[ iA ] = aNodes[ i2 ]; + // theTria2: B->1 + aNodes[ sameInd[ iB ]] = aNodes[ i1 ]; + + //MESSAGE( theTria1 << theTria2 ); + + GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 ); + GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 ); + + //MESSAGE( theTria1 << theTria2 ); - // find indices of 1,2 and of A,B in theTria1 - int iA = 0, iB = 0, i1 = 0, i2 = 0; - for ( i = 0; i < 6; i++ ) - { - if ( sameInd [ i ] == 0 ) - if ( i < 3 ) i1 = i; - else i2 = i; - else if (i < 3) - if ( iA ) iB = i; - else iA = i; - } - // nodes 1 and 2 should not be the same - if ( aNodes[ i1 ] == aNodes[ i2 ] ) + return true; + + } // end if(F1 && F2) + + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (theTria1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (theTria2); + if(!QF2) return false; + + // 5 + // 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) + // | /| theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8) + // | / | + // 7 + + + 6 + // | /9 | + // |/ | + // 4 +--+--+ 3 + // 8 + + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2)) return false; - - - // theTria1: A->2 - aNodes[ iA ] = aNodes[ i2 ]; - // theTria2: B->1 - aNodes[ sameInd[ iB ]] = aNodes[ i1 ]; - - //MESSAGE( theTria1 << theTria2 ); - - GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 ); - GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 ); - - //MESSAGE( theTria1 << theTria2 ); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + + const SMDS_MeshNode* N1new [6]; + const SMDS_MeshNode* N2new [6]; + N1new[0] = N1[0]; + N1new[1] = N2[0]; + N1new[2] = N2[1]; + N1new[3] = N1[4]; + N1new[4] = N2[3]; + N1new[5] = N1[5]; + N2new[0] = N1[0]; + N2new[1] = N1[1]; + N2new[2] = N2[0]; + N2new[3] = N1[3]; + N2new[4] = N2[5]; + N2new[5] = N1[4]; + // replaces nodes in faces + GetMeshDS()->ChangeElementNodes( theTria1, N1new, 6 ); + GetMeshDS()->ChangeElementNodes( theTria2, N2new, 6 ); return true; } @@ -318,7 +435,8 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, if ( theTria1 ) { theTria2 = elem; break; - } else { + } + else { theTria1 = elem; } } @@ -342,55 +460,65 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, return false; const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - if (!F1) return false; + //if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - if (!F2) return false; - - // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A - // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | - // |/ | | \| - // B +--+ 2 B +--+ 2 - - // put nodes in array - // and find indices of 1,2 and of A in tr1 and of B in tr2 - int i, iA1 = 0, i1 = 0; - const SMDS_MeshNode* aNodes1 [3]; - SMDS_ElemIteratorPtr it; - for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) { - aNodes1[ i ] = static_cast( it->next() ); - if ( aNodes1[ i ] == theNode1 ) - iA1 = i; // node A in tr1 - else if ( aNodes1[ i ] != theNode2 ) - i1 = i; // node 1 - } - int iB2 = 0, i2 = 0; - const SMDS_MeshNode* aNodes2 [3]; - for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) { - aNodes2[ i ] = static_cast( it->next() ); - if ( aNodes2[ i ] == theNode2 ) - iB2 = i; // node B in tr2 - else if ( aNodes2[ i ] != theNode1 ) - i2 = i; // node 2 - } - - // nodes 1 and 2 should not be the same - if ( aNodes1[ i1 ] == aNodes2[ i2 ] ) - return false; - - // tr1: A->2 - aNodes1[ iA1 ] = aNodes2[ i2 ]; - // tr2: B->1 - aNodes2[ iB2 ] = aNodes1[ i1 ]; + //if (!F2) return false; + if (F1 && F2) { + + // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A + // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | + // |/ | | \| + // B +--+ 2 B +--+ 2 + + // put nodes in array + // and find indices of 1,2 and of A in tr1 and of B in tr2 + int i, iA1 = 0, i1 = 0; + const SMDS_MeshNode* aNodes1 [3]; + SMDS_ElemIteratorPtr it; + for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) { + aNodes1[ i ] = static_cast( it->next() ); + if ( aNodes1[ i ] == theNode1 ) + iA1 = i; // node A in tr1 + else if ( aNodes1[ i ] != theNode2 ) + i1 = i; // node 1 + } + int iB2 = 0, i2 = 0; + const SMDS_MeshNode* aNodes2 [3]; + for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) { + aNodes2[ i ] = static_cast( it->next() ); + if ( aNodes2[ i ] == theNode2 ) + iB2 = i; // node B in tr2 + else if ( aNodes2[ i ] != theNode1 ) + i2 = i; // node 2 + } + + // nodes 1 and 2 should not be the same + if ( aNodes1[ i1 ] == aNodes2[ i2 ] ) + return false; - //MESSAGE( tr1 << tr2 ); + // tr1: A->2 + aNodes1[ iA1 ] = aNodes2[ i2 ]; + // tr2: B->1 + aNodes2[ iB2 ] = aNodes1[ i1 ]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); - GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); + //MESSAGE( tr1 << tr2 ); - //MESSAGE( tr1 << tr2 ); + GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); + GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); - return true; + //MESSAGE( tr1 << tr2 ); + + return true; + } + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (tr1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (tr2); + if(!QF2) return false; + return InverseDiag(tr1,tr2); } //======================================================================= @@ -406,12 +534,16 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], const SMDS_MeshElement * tr1, const SMDS_MeshElement * tr2 ) { + if( tr1->NbNodes() != tr2->NbNodes() ) + return false; // find the 4-th node to insert into tr1 const SMDS_MeshNode* n4 = 0; SMDS_ElemIteratorPtr it = tr2->nodesIterator(); - while ( !n4 && it->more() ) - { + int i=0; + //while ( !n4 && it->more() ) { + while ( !n4 && i<3 ) { const SMDS_MeshNode * n = static_cast( it->next() ); + i++; bool isDiag = ( n == theNode1 || n == theNode2 ); if ( !isDiag ) n4 = n; @@ -419,19 +551,19 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], // Make an array of nodes to be in a quadrangle int iNode = 0, iFirstDiag = -1; it = tr1->nodesIterator(); - while ( it->more() ) - { + i=0; + //while ( it->more() ) { + while ( i<3 ) { const SMDS_MeshNode * n = static_cast( it->next() ); + i++; bool isDiag = ( n == theNode1 || n == theNode2 ); - if ( isDiag ) - { + if ( isDiag ) { if ( iFirstDiag < 0 ) iFirstDiag = iNode; else if ( iNode - iFirstDiag == 1 ) theQuadNodes[ iNode++ ] = n4; // insert the 4-th node between diagonal nodes } - else if ( n == n4 ) - { + else if ( n == n4 ) { return false; // tr1 and tr2 should not have all the same nodes } theQuadNodes[ iNode++ ] = n; @@ -459,20 +591,66 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, return false; const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - if (!F1) return false; + //if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - if (!F2) return false; + //if (!F2) return false; + if (F1 && F2) { - const SMDS_MeshNode* aNodes [ 4 ]; - if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) - return false; + const SMDS_MeshNode* aNodes [ 4 ]; + if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) + return false; + + //MESSAGE( endl << tr1 << tr2 ); + + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); + GetMeshDS()->RemoveElement( tr2 ); - //MESSAGE( endl << tr1 << tr2 ); + //MESSAGE( endl << tr1 ); - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); + return true; + } + + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (tr1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (tr2); + if(!QF2) return false; + + // 5 + // 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) + // | /| tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8) + // | / | + // 7 + + + 6 + // | /9 | + // |/ | + // 4 +--+--+ 3 + // 8 + + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + if(!GetNodesFromTwoTria(tr1,tr2,N1,N2)) + return false; + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); GetMeshDS()->RemoveElement( tr2 ); - //MESSAGE( endl << tr1 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); return true; } @@ -493,16 +671,39 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) switch ( theElem->GetType() ) { case SMDSAbs_Edge: - case SMDSAbs_Face: - { - int i = theElem->NbNodes(); - vector aNodes( i ); - while ( it->more() ) - aNodes[ --i ]= static_cast( it->next() ); - return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() ); + case SMDSAbs_Face: { + if(!theElem->IsQuadratic()) { + int i = theElem->NbNodes(); + vector aNodes( i ); + while ( it->more() ) + aNodes[ --i ]= static_cast( it->next() ); + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() ); + } + else { + // quadratic elements + if(theElem->GetType()==SMDSAbs_Edge) { + vector aNodes(3); + aNodes[1]= static_cast( it->next() ); + aNodes[0]= static_cast( it->next() ); + aNodes[2]= static_cast( it->next() ); + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], 3 ); + } + else { + int nbn = theElem->NbNodes(); + vector aNodes(nbn); + aNodes[0]= static_cast( it->next() ); + int i=1; + for(; i( it->next() ); + } + for(i=0; i( it->next() ); + } + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], nbn ); + } + } } - case SMDSAbs_Volume: - { + case SMDSAbs_Volume: { if (theElem->IsPoly()) { const SMDS_PolyhedralVolumeOfNodes* aPolyedre = static_cast( theElem ); @@ -519,16 +720,17 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) for (int iface = 1; iface <= nbFaces; iface++) { int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); quantities[iface - 1] = nbFaceNodes; - + for (inode = nbFaceNodes; inode >= 1; inode--) { const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); poly_nodes.push_back(curNode); } } - + return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities ); - } else { + } + else { SMDS_VolumeTool vTool; if ( !vTool.Set( theElem )) return false; @@ -574,54 +776,119 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, SMESHDS_Mesh * aMesh = GetMeshDS(); set< const SMDS_MeshElement * >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 ) + if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) - aNodes[ i++ ] = static_cast( itN->next() ); - - // compare two sets of possible triangles - double aBadRate1, aBadRate2; // to what extent a set is bad - SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); - SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); - aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + if(elem->NbNodes()==4) { - SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); - SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); - aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) + aNodes[ i++ ] = static_cast( itN->next() ); + + // compare two sets of possible triangles + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); - int aShapeId = FindShape( elem ); - //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2 + int aShapeId = FindShape( elem ); + //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2 // << " ShapeID = " << aShapeId << endl << elem ); - if ( aBadRate1 <= aBadRate2 ) { - // tr1 + tr2 is better - aMesh->ChangeElementNodes( elem, aNodes, 3 ); + if ( aBadRate1 <= aBadRate2 ) { + // tr1 + tr2 is better + aMesh->ChangeElementNodes( elem, aNodes, 3 ); + //MESSAGE( endl << elem ); + + elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + } + else { + // tr3 + tr4 is better + aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); + //MESSAGE( endl << elem ); + + elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + } //MESSAGE( endl << elem ); - elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + // put a new triangle on the same shape + if ( aShapeId ) + aMesh->SetMeshElementOnShape( elem, aShapeId ); } - else { - // tr3 + tr4 is better - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - //MESSAGE( endl << elem ); - elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + if( elem->NbNodes()==8 && elem->IsQuadratic() ) { + const SMDS_MeshNode* aNodes [8]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) { + aNodes[ i++ ] = static_cast( itN->next() ); + } + + // compare two sets of possible triangles + // use for comparing simple triangles (not quadratic) + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + + int aShapeId = FindShape( elem ); + + // find middle point for (0,1,2,3) + // and create node in this point; + double x=0., y=0., z=0.; + for(i=0; i<4; i++) { + x += aNodes[i]->X(); + y += aNodes[i]->Y(); + z += aNodes[i]->Z(); + } + const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); + + if ( aBadRate1 <= aBadRate2 ) { + // tr1 + tr2 is better + const SMDS_MeshNode* N[6]; + N[0] = aNodes[0]; + N[1] = aNodes[1]; + N[2] = aNodes[2]; + N[3] = aNodes[4]; + N[4] = aNodes[5]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + } + else { + // tr3 + tr4 is better + const SMDS_MeshNode* N[6]; + N[0] = aNodes[1]; + N[1] = aNodes[2]; + N[2] = aNodes[3]; + N[3] = aNodes[5]; + N[4] = aNodes[6]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + } + // put a new triangle on the same shape + if ( aShapeId ) { + aMesh->SetMeshElementOnShape( elem, aShapeId ); + } } - //MESSAGE( endl << elem ); - // put a new triangle on the same shape - if ( aShapeId ) - aMesh->SetMeshElementOnShape( elem, aShapeId ); } - return true; } @@ -635,30 +902,36 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, if (!theCrit.get()) return -1; - if (!theQuad || theQuad->GetType() != SMDSAbs_Face || theQuad->NbNodes() != 4) + if (!theQuad || theQuad->GetType() != SMDSAbs_Face ) return -1; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = theQuad->nodesIterator(); - int i = 0; - while (itN->more()) - aNodes[ i++ ] = static_cast( itN->next() ); + if( theQuad->NbNodes()==4 || + (theQuad->NbNodes()==8 && theQuad->IsQuadratic()) ) { - // compare two sets of possible triangles - double aBadRate1, aBadRate2; // to what extent a set is bad - SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); - SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); - aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = theQuad->nodesIterator(); + int i = 0; + //while (itN->more()) + while (i<4) { + aNodes[ i++ ] = static_cast( itN->next() ); + } + // compare two sets of possible triangles + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); - SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); - SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); - aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); - if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better - return 1; // diagonal 1-3 + if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better + return 1; // diagonal 1-3 - return 2; // diagonal 2-4 + return 2; // diagonal 2-4 + } + return -1; } //======================================================================= @@ -693,38 +966,86 @@ bool SMESH_MeshEditor::QuadToTri (std::set & theElems, SMESHDS_Mesh * aMesh = GetMeshDS(); set< const SMDS_MeshElement * >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 ) + if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; + bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8; + if(!isquad) continue; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) - aNodes[ i++ ] = static_cast( itN->next() ); + if(elem->NbNodes()==4) { + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) + aNodes[ i++ ] = static_cast( itN->next() ); - int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; - if ( the13Diag ) - { - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); - } - else - { - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + int aShapeId = FindShape( elem ); + const SMDS_MeshElement* newElem = 0; + if ( the13Diag ) { + aMesh->ChangeElementNodes( elem, aNodes, 3 ); + newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + } + else { + aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); + newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + } + // put a new triangle on the same shape and add to the same groups + if ( aShapeId ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + AddToSameGroups( newElem, elem, aMesh ); } - // put a new triangle on the same shape and add to the same groups + if( elem->NbNodes()==8 && elem->IsQuadratic() ) { + const SMDS_MeshNode* aNodes [8]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) { + aNodes[ i++ ] = static_cast( itN->next() ); + } - if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + // find middle point for (0,1,2,3) + // and create node in this point; + double x=0., y=0., z=0.; + for(i=0; i<4; i++) { + x += aNodes[i]->X(); + y += aNodes[i]->Y(); + z += aNodes[i]->Z(); + } + const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); - AddToSameGroups( newElem, elem, aMesh ); + int aShapeId = FindShape( elem ); + const SMDS_MeshElement* newElem = 0; + if ( the13Diag ) { + const SMDS_MeshNode* N[6]; + N[0] = aNodes[0]; + N[1] = aNodes[1]; + N[2] = aNodes[2]; + N[3] = aNodes[4]; + N[4] = aNodes[5]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + } + else { + const SMDS_MeshNode* N[6]; + N[0] = aNodes[1]; + N[1] = aNodes[2]; + N[2] = aNodes[3]; + N[3] = aNodes[5]; + N[4] = aNodes[6]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + } + // put a new triangle on the same shape and add to the same groups + if ( aShapeId ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + AddToSameGroups( newElem, elem, aMesh ); + } } return true; @@ -747,18 +1068,24 @@ double getAngle(const SMDS_MeshElement * tr1, if ( !SMESH::Controls::NumericalFunctor::GetPoints( tr1, P1 ) || !SMESH::Controls::NumericalFunctor::GetPoints( tr2, P2 )) return angle; - gp_Vec N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) ); + gp_Vec N1,N2; + if(!tr1->IsQuadratic()) + N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) ); + else + N1 = gp_Vec( P1(3) - P1(1) ) ^ gp_Vec( P1(5) - P1(1) ); if ( N1.SquareMagnitude() <= gp::Resolution() ) return angle; - gp_Vec N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) ); + if(!tr2->IsQuadratic()) + N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) ); + else + N2 = gp_Vec( P2(3) - P2(1) ) ^ gp_Vec( P2(5) - P2(1) ); if ( N2.SquareMagnitude() <= gp::Resolution() ) return angle; // find the first diagonal node n1 in the triangles: // take in account a diagonal link orientation const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 }; - for ( int t = 0; t < 2; t++ ) - { + for ( int t = 0; t < 2; t++ ) { SMDS_ElemIteratorPtr it = tr[ t ]->nodesIterator(); int i = 0, iDiag = -1; while ( it->more()) { @@ -788,7 +1115,6 @@ double getAngle(const SMDS_MeshElement * tr1, // class generating a unique ID for a pair of nodes // and able to return nodes by that ID // ================================================= - class LinkID_Gen { public: @@ -819,6 +1145,7 @@ class LinkID_Gen { long myMaxID; }; + //======================================================================= //function : TriToQuad //purpose : Fuse neighbour triangles into quadrangles. @@ -837,65 +1164,76 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, return false; SMESHDS_Mesh * aMesh = GetMeshDS(); - LinkID_Gen aLinkID_Gen( aMesh ); - + //LinkID_Gen aLinkID_Gen( aMesh ); // Prepare data for algo: build // 1. map of elements with their linkIDs // 2. map of linkIDs with their elements - map< long, list< const SMDS_MeshElement* > > mapLi_listEl; - map< long, list< const SMDS_MeshElement* > >::iterator itLE; - map< const SMDS_MeshElement*, set< long > > mapEl_setLi; - map< const SMDS_MeshElement*, set< long > >::iterator itEL; + //map< long, list< const SMDS_MeshElement* > > mapLi_listEl; + //map< long, list< const SMDS_MeshElement* > >::iterator itLE; + //map< const SMDS_MeshElement*, set< long > > mapEl_setLi; + //map< const SMDS_MeshElement*, set< long > >::iterator itEL; + + map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl; + map< NLink, list< const SMDS_MeshElement* > >::iterator itLE; + map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi; + map< const SMDS_MeshElement*, set< NLink > >::iterator itEL; set::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->NbNodes() != 3 ) - continue; + //if ( !elem || elem->NbNodes() != 3 ) + // continue; + if(!elem || elem->GetType() != SMDSAbs_Face ) continue; + bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic()); + if(!IsTria) continue; // retrieve element nodes const SMDS_MeshNode* aNodes [4]; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); int i = 0; - while ( itN->more() ) + //while ( itN->more() ) + while ( i<3 ) aNodes[ i++ ] = static_cast( itN->next() ); ASSERT( i == 3 ); aNodes[ 3 ] = aNodes[ 0 ]; // fill maps - for ( i = 0; i < 3; i++ ) - { - long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] ); + for ( i = 0; i < 3; i++ ) { + //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] ); + NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ), + ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] )); // check if elements sharing a link can be fused - itLE = mapLi_listEl.find( linkID ); - if ( itLE != mapLi_listEl.end() ) - { + //itLE = mapLi_listEl.find( linkID ); + itLE = mapLi_listEl.find( link ); + if ( itLE != mapLi_listEl.end() ) { if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link continue; const SMDS_MeshElement* elem2 = (*itLE).second.front(); -// if ( FindShape( elem ) != FindShape( elem2 )) -// continue; // do not fuse triangles laying on different shapes + //if ( FindShape( elem ) != FindShape( elem2 )) + // continue; // do not fuse triangles laying on different shapes if ( getAngle( elem, elem2, aNodes[i], aNodes[i+1] ) > theMaxAngle ) continue; // avoid making badly shaped quads (*itLE).second.push_back( elem ); } - else - mapLi_listEl[ linkID ].push_back( elem ); - mapEl_setLi [ elem ].insert( linkID ); + else { + //mapLi_listEl[ linkID ].push_back( elem ); + mapLi_listEl[ link ].push_back( elem ); + } + //mapEl_setLi [ elem ].insert( linkID ); + mapEl_setLi [ elem ].insert( link ); } } // Clean the maps from the links shared by a sole element, ie // links to which only one element is bound in mapLi_listEl - for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) - { + for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) { int nbElems = (*itLE).second.size(); if ( nbElems < 2 ) { const SMDS_MeshElement* elem = (*itLE).second.front(); - long link = (*itLE).first; + //long link = (*itLE).first; + NLink link = (*itLE).first; mapEl_setLi[ elem ].erase( link ); if ( mapEl_setLi[ elem ].empty() ) mapEl_setLi.erase( elem ); @@ -904,18 +1242,15 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, // Algo: fuse triangles into quadrangles - while ( ! mapEl_setLi.empty() ) - { + while ( ! mapEl_setLi.empty() ) { // Look for the start element: // the element having the least nb of shared links const SMDS_MeshElement* startElem = 0; int minNbLinks = 4; - for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) - { + for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) { int nbLinks = (*itEL).second.size(); - if ( nbLinks < minNbLinks ) - { + if ( nbLinks < minNbLinks ) { startElem = (*itEL).first; minNbLinks = nbLinks; if ( minNbLinks == 1 ) @@ -925,17 +1260,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, // search elements to fuse starting from startElem or links of elements // fused earlyer - startLinks - list< long > startLinks; - while ( startElem || !startLinks.empty() ) - { - while ( !startElem && !startLinks.empty() ) - { + //list< long > startLinks; + list< NLink > startLinks; + while ( startElem || !startLinks.empty() ) { + while ( !startElem && !startLinks.empty() ) { // Get an element to start, by a link - long linkId = startLinks.front(); + //long linkId = startLinks.front(); + NLink linkId = startLinks.front(); startLinks.pop_front(); itLE = mapLi_listEl.find( linkId ); - if ( itLE != mapLi_listEl.end() ) - { + if ( itLE != mapLi_listEl.end() ) { list< const SMDS_MeshElement* > & listElem = (*itLE).second; list< const SMDS_MeshElement* >::iterator itE = listElem.begin(); for ( ; itE != listElem.end() ; itE++ ) @@ -945,69 +1279,83 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, } } - if ( startElem ) - { + if ( startElem ) { // Get candidates to be fused - const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0; - long link12, link13; + //long link12, link13; + NLink link12, link13; startElem = 0; ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() ); - set< long >& setLi = mapEl_setLi[ tr1 ]; + //set< long >& setLi = mapEl_setLi[ tr1 ]; + set< NLink >& setLi = mapEl_setLi[ tr1 ]; ASSERT( !setLi.empty() ); - set< long >::iterator itLi; - for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) - { - long linkID = (*itLi); + //set< long >::iterator itLi; + set< NLink >::iterator itLi; + for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) { + //long linkID = (*itLi); + NLink linkID = (*itLi); itLE = mapLi_listEl.find( linkID ); if ( itLE == mapLi_listEl.end() ) continue; + const SMDS_MeshElement* elem = (*itLE).second.front(); if ( elem == tr1 ) elem = (*itLE).second.back(); mapLi_listEl.erase( itLE ); if ( mapEl_setLi.find( elem ) == mapEl_setLi.end()) continue; - if ( tr2 ) - { + if ( tr2 ) { tr3 = elem; link13 = linkID; } - else - { + else { tr2 = elem; link12 = linkID; } // add other links of elem to list of links to re-start from - set< long >& links = mapEl_setLi[ elem ]; - set< long >::iterator it; - for ( it = links.begin(); it != links.end(); it++ ) - { - long linkID2 = (*it); + //set< long >& links = mapEl_setLi[ elem ]; + //set< long >::iterator it; + set< NLink >& links = mapEl_setLi[ elem ]; + set< NLink >::iterator it; + for ( it = links.begin(); it != links.end(); it++ ) { + //long linkID2 = (*it); + NLink linkID2 = (*it); if ( linkID2 != linkID ) startLinks.push_back( linkID2 ); } } // Get nodes of possible quadrangles - const SMDS_MeshNode *n12 [4], *n13 [4]; bool Ok12 = false, Ok13 = false; + //const SMDS_MeshNode *linkNode1, *linkNode2; const SMDS_MeshNode *linkNode1, *linkNode2; - if ( tr2 && - aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) && - getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) - Ok12 = true; - if ( tr3 && - aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) && - getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) - Ok13 = true; + if(tr2) { + //const SMDS_MeshNode *linkNode1 = link12.first; + //const SMDS_MeshNode *linkNode2 = link12.second; + linkNode1 = link12.first; + linkNode2 = link12.second; + //if ( tr2 && + // aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) && + // getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) + // Ok12 = true; + if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) + Ok12 = true; + } + if(tr3) { + linkNode1 = link13.first; + linkNode2 = link13.second; + //if ( tr3 && + // aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) && + // getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) + // Ok13 = true; + if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) + Ok13 = true; + } // Choose a pair to fuse - - if ( Ok12 && Ok13 ) - { + if ( Ok12 && Ok13 ) { SMDS_FaceOfNodes quad12 ( n12[ 0 ], n12[ 1 ], n12[ 2 ], n12[ 3 ] ); SMDS_FaceOfNodes quad13 ( n13[ 0 ], n13[ 1 ], n13[ 2 ], n13[ 3 ] ); double aBadRate12 = getBadRate( &quad12, theCrit ); @@ -1018,24 +1366,66 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, Ok13 = false; } - // Make quadrangles // and remove fused elems and removed links from the maps - mapEl_setLi.erase( tr1 ); - if ( Ok12 ) - { + if ( Ok12 ) { mapEl_setLi.erase( tr2 ); mapLi_listEl.erase( link12 ); - aMesh->ChangeElementNodes( tr1, n12, 4 ); - aMesh->RemoveElement( tr2 ); + if(tr1->NbNodes()==3) { + aMesh->ChangeElementNodes( tr1, n12, 4 ); + aMesh->RemoveElement( tr2 ); + } + else { + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + GetNodesFromTwoTria(tr1,tr2,N1,N2); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + GetMeshDS()->RemoveElement( tr2 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); + } } - else if ( Ok13 ) - { + else if ( Ok13 ) { mapEl_setLi.erase( tr3 ); mapLi_listEl.erase( link13 ); - aMesh->ChangeElementNodes( tr1, n13, 4 ); - aMesh->RemoveElement( tr3 ); + if(tr1->NbNodes()==3) { + aMesh->ChangeElementNodes( tr1, n13, 4 ); + aMesh->RemoveElement( tr3 ); + } + else { + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + GetNodesFromTwoTria(tr1,tr3,N1,N2); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + GetMeshDS()->RemoveElement( tr3 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); + } } // Next element to fuse: the rejected one @@ -1352,13 +1742,25 @@ void laplacianSmooth(const SMDS_MeshNode* theNode, // put all nodes in array int nbNodes = 0, iNode = 0; vector< const SMDS_MeshNode*> aNodes( elem->NbNodes() ); - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { - aNodes[ nbNodes ] = static_cast( itN->next() ); - if ( aNodes[ nbNodes ] == theNode ) - iNode = nbNodes; // index of theNode within aNodes - nbNodes++; + if(!elem->IsQuadratic()) { + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + aNodes[ nbNodes ] = static_cast( itN->next() ); + if ( aNodes[ nbNodes ] == theNode ) + iNode = nbNodes; // index of theNode within aNodes + nbNodes++; + } + } + else { + int nbn = elem->NbNodes()/2; + aNodes.resize(nbn); + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( nbNodes( itN->next() ); + if ( aNodes[ nbNodes ] == theNode ) + iNode = nbNodes; // index of theNode within aNodes + nbNodes++; + } } // add linked nodes int iAfter = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; @@ -1435,9 +1837,13 @@ void centroidalSmooth(const SMDS_MeshNode* theNode, gp_XYZ elemCenter(0.,0.,0.); SMESH::Controls::TSequenceOfXYZ aNodePoints; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + int nn = elem->NbNodes(); + if(elem->IsQuadratic()) nn = nn/2; + int i=0; + //while ( itN->more() ) { + while ( i( itN->next() ); + i++; gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() ); aNodePoints.push_back( aP ); if ( !theSurface.IsNull() ) { // smooth in 2D @@ -1509,6 +1915,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, if ( theTgtAspectRatio < 1.0 ) theTgtAspectRatio = 1.0; + double disttol = 1.e-16; + SMESH::Controls::AspectRatio aQualityFunc; SMESHDS_Mesh* aMesh = GetMeshDS(); @@ -1540,9 +1948,10 @@ void SMESH_MeshEditor::Smooth (set & theElems, // smooth elements on each TopoDS_Face separately // =============================================== + set QuadElems; + set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end - for ( ; fId != faceIdSet.rend(); ++fId ) - { + for ( ; fId != faceIdSet.rend(); ++fId ) { // get face surface and submesh Handle(Geom_Surface) surface; SMESHDS_SubMesh* faceSubMesh = 0; @@ -1583,8 +1992,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, int nbElemOnFace = 0; itElem = theElems.begin(); // loop on not yet smoothed elements: look for elems on a face - while ( itElem != theElems.end() ) - { + while ( itElem != theElems.end() ) { if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() ) break; // all elements found @@ -1595,6 +2003,9 @@ void SMESH_MeshEditor::Smooth (set & theElems, continue; } elemsOnFace.push_back( elem ); + if(elem->IsQuadratic()) { + QuadElems.insert(elem); + } theElems.erase( itElem++ ); nbElemOnFace++; @@ -1602,7 +2013,13 @@ void SMESH_MeshEditor::Smooth (set & theElems, const SMDS_MeshNode* node; SMDS_TypeOfPosition posType; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { + int nbn = elem->NbNodes(); + if(elem->IsQuadratic()) + nbn = nbn/2; + int nn = 0; + //while ( itN->more() ) { + while ( nn( itN->next() ); const SMDS_PositionPtr& pos = node->GetPosition(); posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; @@ -1657,8 +2074,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // check UV on face list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin(); - for ( ; n != uvCheckNodes.end(); ++n ) - { + for ( ; n != uvCheckNodes.end(); ++n ) { node = *n; gp_XY uv( 0, 0 ); const SMDS_PositionPtr& pos = node->GetPosition(); @@ -1725,21 +2141,31 @@ void SMESH_MeshEditor::Smooth (set & theElems, // fix nodes on mesh boundary - if ( checkBoundaryNodes ) - { + if ( checkBoundaryNodes ) { typedef pair TLink; map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace map< TLink, int >::iterator link_nb; // put all elements links to linkNbMap list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); - for ( ; elemIt != elemsOnFace.end(); ++elemIt ) - { + for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { + const SMDS_MeshElement* elem = (*elemIt); // put elem nodes in array vector< const SMDS_MeshNode* > nodes; - nodes.reserve( (*elemIt)->NbNodes() + 1 ); - SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator(); - while ( itN->more() ) - nodes.push_back( static_cast( itN->next() )); + if(!elem->IsQuadratic()) { + nodes.reserve( elem->NbNodes() + 1 ); + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) + nodes.push_back( static_cast( itN->next() )); + } + else { + nodes.reserve( elem->NbNodes()/2 + 1 ); + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int nbn = 0; + while ( nbnNbNodes()/2 ) { + nbn++; + nodes.push_back( static_cast( itN->next() )); + } + } nodes.push_back( nodes.front() ); // loop on elem links: insert them in linkNbMap for ( int iN = 1; iN < nodes.size(); ++iN ) { @@ -1771,11 +2197,9 @@ void SMESH_MeshEditor::Smooth (set & theElems, // ----------------------------------------------------- set nodesNearSeam; // to smooth using uvMap2 - if ( !surface.IsNull() ) - { + if ( !surface.IsNull() ) { TopExp_Explorer eExp( face, TopAbs_EDGE ); - for ( ; eExp.More(); eExp.Next() ) - { + for ( ; eExp.More(); eExp.Next() ) { TopoDS_Edge edge = TopoDS::Edge( eExp.Current() ); if ( !BRep_Tool::IsClosed( edge, face )) continue; @@ -1812,8 +2236,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // loop on nodes on seam list< const SMDS_MeshNode* >::iterator noSeIt = seamNodes.begin(); - for ( ; noSeIt != seamNodes.end(); ++noSeIt ) - { + for ( ; noSeIt != seamNodes.end(); ++noSeIt ) { const SMDS_MeshNode* nSeam = *noSeIt; map< const SMDS_MeshNode*, gp_XY* >::iterator n_uv = uvMap.find( nSeam ); if ( n_uv == uvMap.end() ) @@ -1829,8 +2252,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, // collect movable nodes linked to ones on seam in nodesNearSeam SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator(); - while ( eIt->more() ) - { + while ( eIt->more() ) { const SMDS_MeshElement* e = eIt->next(); if ( e->GetType() != SMDSAbs_Face ) continue; @@ -1858,8 +2280,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // for centroidalSmooth all element nodes must // be on one side of a seam - if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) - { + if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) { SMDS_ElemIteratorPtr nIt = e->nodesIterator(); while ( nIt->more() ) { const SMDS_MeshNode* n = @@ -1884,12 +2305,10 @@ void SMESH_MeshEditor::Smooth (set & theElems, int it = -1; double maxRatio = -1., maxDisplacement = -1.; set::iterator nodeToMove; - for ( it = 0; it < theNbIterations; it++ ) - { + for ( it = 0; it < theNbIterations; it++ ) { maxDisplacement = 0.; nodeToMove = setMovableNodes.begin(); - for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) - { + for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) { const SMDS_MeshNode* node = (*nodeToMove); gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() ); @@ -1907,7 +2326,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, maxDisplacement = aDispl; } // no node movement => exit - if ( maxDisplacement < 1.e-16 ) { + //if ( maxDisplacement < 1.e-16 ) { + if ( maxDisplacement < disttol ) { MESSAGE("-- no node movement --"); break; } @@ -1915,8 +2335,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, // check elements quality maxRatio = 0; list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); - for ( ; elemIt != elemsOnFace.end(); ++elemIt ) - { + for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { const SMDS_MeshElement* elem = (*elemIt); if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; @@ -1945,10 +2364,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, // new nodes positions are computed, // record movement in DS and set new UV // --------------------------------------- - nodeToMove = setMovableNodes.begin(); - for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) - { + for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) { SMDS_MeshNode* node = const_cast< SMDS_MeshNode* > (*nodeToMove); aMesh->MoveNode( node, node->X(), node->Y(), node->Z() ); map< const SMDS_MeshNode*, gp_XY* >::iterator node_uv = uvMap.find( node ); @@ -1960,6 +2377,38 @@ void SMESH_MeshEditor::Smooth (set & theElems, } } // loop on face ids + + set< const SMDS_MeshElement* >::iterator itq; + for ( itq = QuadElems.begin(); itq != QuadElems.end(); itq++ ) { + const SMDS_QuadraticFaceOfNodes* QF = + dynamic_cast (*itq); + if(QF) { + vector Ns(QF->NbNodes()+1); + SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator(); + int nn = 0; + while( anIter->more() ) { + Ns[nn++] = anIter->next(); + //Ns.push_back(anIter->next()); + } + Ns[nn] = Ns[0]; + //Ns.push_back(Ns[0]); + int i=0; + for(; iNbNodes(); i=i+2) { + double x = (Ns[i]->X() + Ns[i+2]->X())/2; + double y = (Ns[i]->Y() + Ns[i+2]->Y())/2; + double z = (Ns[i]->Z() + Ns[i+2]->Z())/2; + if( fabs( Ns[i+1]->X() - x ) > disttol || + fabs( Ns[i+1]->Y() - y ) > disttol || + fabs( Ns[i+1]->Z() - z ) > disttol ) { + // we have to move i+1 node + const_cast(Ns[i+1])->setXYZ(x,y,z); + aMesh->MoveNode( Ns[i+1], x, y, z ); + } + } + } + } + QuadElems.clear(); + } //======================================================================= @@ -2000,38 +2449,57 @@ static bool isReverse(const SMDS_MeshNode* prevNodes[], static void sweepElement(SMESHDS_Mesh* aMesh, const SMDS_MeshElement* elem, const vector & newNodesItVec, - list& newElems) + list& newElems, + const int nbSteps) { // Loop on elem nodes: // find new nodes and detect same nodes indices int nbNodes = elem->NbNodes(); list::const_iterator itNN[ nbNodes ]; - const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ]; + const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ], *midlNod[ nbNodes ]; int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0; + vector sames(nbNodes); - for ( iNode = 0; iNode < nbNodes; iNode++ ) - { + bool issimple[nbNodes]; + + for ( iNode = 0; iNode < nbNodes; iNode++ ) { TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; const SMDS_MeshNode* node = nnIt->first; const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second; if ( listNewNodes.empty() ) return; + if(listNewNodes.size()==nbSteps) { + issimple[iNode] = true; + } + else { + issimple[iNode] = false; + } + itNN[ iNode ] = listNewNodes.begin(); prevNod[ iNode ] = node; nextNod[ iNode ] = listNewNodes.front(); +//cout<<"iNode="<GetID() ); return; } +// if( elem->IsQuadratic() && nbSame>0 ) { +// MESSAGE( "Can not rotate quadratic element " << elem->GetID() ); +// return; +// } + int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0; if ( nbSame > 0 ) { iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 ); @@ -2039,6 +2507,12 @@ static void sweepElement(SMESHDS_Mesh* aMesh, iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 ); } +//if(nbNodes==8) +//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1] +// <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4] +// <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5] +// <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]< 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) { @@ -2053,82 +2527,195 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } // make new elements - int iStep, nbSteps = newNodesItVec[ 0 ]->second.size(); - for (iStep = 0; iStep < nbSteps; iStep++ ) - { + int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size(); + for (iStep = 0; iStep < nbSteps; iStep++ ) { // get next nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) { - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; + if(issimple[iNode]) { + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else { + if( elem->GetType()==SMDSAbs_Node ) { + // we have to use two nodes + midlNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else if(!elem->IsQuadratic() || + elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) { + // we have to use each second node + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else { + // we have to use two nodes + midlNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + } } SMDS_MeshElement* aNewElem = 0; - switch ( nbNodes ) - { - case 0: - return; - case 1: { // NODE - if ( nbSame == 0 ) - aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] ); - break; - } - case 2: { // EDGE - - if ( nbSame == 0 ) - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ 1 ], nextNod[ 0 ] ); - else - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ iNotSameNode ] ); - break; - } - case 3: { // TRIANGLE - - if ( nbSame == 0 ) // --- pentahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] ); + if(!elem->IsPoly()) { + switch ( nbNodes ) { + case 0: + return; + case 1: { // NODE + if ( nbSame == 0 ) { + if(issimple[0]) + aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] ); + else + aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] ); + } + break; + } + case 2: { // EDGE + if ( nbSame == 0 ) + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ 1 ], nextNod[ 0 ] ); + else + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ iNotSameNode ] ); + break; + } - else if ( nbSame == 1 ) // --- pyramid - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], - nextNod[ iSameNode ]); + case 3: { // TRIANGLE or quadratic edge + if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE - else // 2 same nodes: --- tetrahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], - nextNod[ iNotSameNode ]); - break; - } - case 4: { // QUADRANGLE + if ( nbSame == 0 ) // --- pentahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], + nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] ); - if ( nbSame == 0 ) // --- hexahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]); + else if ( nbSame == 1 ) // --- pyramid + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + nextNod[ iSameNode ]); - else if ( nbSame == 1 ) // --- pyramid + pentahedron - { - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], - nextNod[ iSameNode ]); - newElems.push_back( aNewElem ); - aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], - prevNod[ iBeforeSame ], nextNod[ iAfterSame ], - nextNod[ iOpposSame ], nextNod[ iBeforeSame ] ); - } - else if ( nbSame == 2 ) // pentahedron - { - if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) - // iBeforeSame is same too - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ], - nextNod[ iOpposSame ], prevNod[ iSameNode ], - prevNod[ iAfterSame ], nextNod[ iAfterSame ]); - else - // iAfterSame is same too - aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], - nextNod[ iBeforeSame ], prevNod[ iAfterSame ], - prevNod[ iOpposSame ], nextNod[ iOpposSame ]); + else // 2 same nodes: --- tetrahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], + nextNod[ iNotSameNode ]); + } + else { // quadratic edge + if(nbSame==0) { // quadratic quadrangle + aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1], + midlNod[0], nextNod[2], midlNod[1], prevNod[2]); + } + else if(nbSame==1) { // quadratic triangle + if(sames[0]==2) + return; // medium node on axis + else if(sames[0]==0) { + aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], + nextNod[2], midlNod[1], prevNod[2]); + } + else { // sames[0]==1 + aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1], + midlNod[0], nextNod[2], prevNod[2]); + } + } + else + return; + } + break; + } + case 4: { // QUADRANGLE + + if ( nbSame == 0 ) // --- hexahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ], + nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]); + + else if ( nbSame == 1 ) { // --- pyramid + pentahedron + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + nextNod[ iSameNode ]); + newElems.push_back( aNewElem ); + aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], + prevNod[ iBeforeSame ], nextNod[ iAfterSame ], + nextNod[ iOpposSame ], nextNod[ iBeforeSame ] ); + } + else if ( nbSame == 2 ) { // pentahedron + if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) + // iBeforeSame is same too + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ], + nextNod[ iOpposSame ], prevNod[ iSameNode ], + prevNod[ iAfterSame ], nextNod[ iAfterSame ]); + else + // iAfterSame is same too + aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], + nextNod[ iBeforeSame ], prevNod[ iAfterSame ], + prevNod[ iOpposSame ], nextNod[ iOpposSame ]); + } + break; + } + case 6: { // quadratic triangle + // create pentahedron with 15 nodes + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1], + nextNod[0], nextNod[2], nextNod[1], + prevNod[5], prevNod[4], prevNod[3], + nextNod[5], nextNod[4], nextNod[3], + midlNod[0], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], + nextNod[0], nextNod[1], nextNod[2], + prevNod[3], prevNod[4], prevNod[5], + nextNod[3], nextNod[4], nextNod[5], + midlNod[0], midlNod[1], midlNod[2]); + } + break; + } + case 8: { // quadratic quadrangle + // create hexahedron with 20 nodes + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1], + nextNod[0], nextNod[3], nextNod[2], nextNod[1], + prevNod[7], prevNod[6], prevNod[5], prevNod[4], + nextNod[7], nextNod[6], nextNod[5], nextNod[4], + midlNod[0], midlNod[3], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], + nextNod[0], nextNod[1], nextNod[2], nextNod[3], + prevNod[4], prevNod[5], prevNod[6], prevNod[7], + nextNod[4], nextNod[5], nextNod[6], nextNod[7], + midlNod[0], midlNod[1], midlNod[2], midlNod[3]); + } + break; + } + default: { + // realized for extrusion only + //vector polyedre_nodes (nbNodes*2 + 4*nbNodes); + //vector quantities (nbNodes + 2); + + //quantities[0] = nbNodes; // bottom of prism + //for (int inode = 0; inode < nbNodes; inode++) { + // polyedre_nodes[inode] = prevNod[inode]; + //} + + //quantities[1] = nbNodes; // top of prism + //for (int inode = 0; inode < nbNodes; inode++) { + // polyedre_nodes[nbNodes + inode] = nextNod[inode]; + //} + + //for (int iface = 0; iface < nbNodes; iface++) { + // quantities[iface + 2] = 4; + // int inextface = (iface == nbNodes - 1) ? 0 : iface + 1; + // polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface]; + // polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface]; + // polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface]; + // polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface]; + //} + //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); + break; + } } - break; } - default: { + + if(!aNewElem) { // realized for extrusion only vector polyedre_nodes (nbNodes*2 + 4*nbNodes); vector quantities (nbNodes + 2); @@ -2153,9 +2740,10 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); } - } - if ( aNewElem ) + + if ( aNewElem ) { newElems.push_back( aNewElem ); + } // set new prev nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) @@ -2173,26 +2761,33 @@ static void makeWalls (SMESHDS_Mesh* aMesh, TNodeOfNodeListMap & mapNewNodes, TElemOfElemListMap & newElemsMap, TElemOfVecOfNnlmiMap & elemNewNodesMap, - set& elemSet) + set& elemSet, + const int nbSteps) { ASSERT( newElemsMap.size() == elemNewNodesMap.size() ); // Find nodes belonging to only one initial element - sweep them to get edges. TNodeOfNodeListMapItr nList = mapNewNodes.begin(); - for ( ; nList != mapNewNodes.end(); nList++ ) - { + for ( ; nList != mapNewNodes.end(); nList++ ) { const SMDS_MeshNode* node = static_cast( nList->first ); SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(); int nbInitElems = 0; - while ( eIt->more() && nbInitElems < 2 ) - if ( elemSet.find( eIt->next() ) != elemSet.end() ) + const SMDS_MeshElement* el; + while ( eIt->more() && nbInitElems < 2 ) { + el = eIt->next(); + //if ( elemSet.find( eIt->next() ) != elemSet.end() ) + if ( elemSet.find(el) != elemSet.end() ) nbInitElems++; + } if ( nbInitElems < 2 ) { - vector newNodesItVec( 1, nList ); - list newEdges; - sweepElement( aMesh, node, newNodesItVec, newEdges ); + bool NotCreateEdge = el->IsQuadratic() && el->IsMediumNode(node); + if(!NotCreateEdge) { + vector newNodesItVec( 1, nList ); + list newEdges; + sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps ); + } } } @@ -2201,16 +2796,22 @@ static void makeWalls (SMESHDS_Mesh* aMesh, TElemOfElemListMap::iterator itElem = newElemsMap.begin(); TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin(); - for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) - { + for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) { const SMDS_MeshElement* elem = itElem->first; vector& vecNewNodes = itElemNodes->second; - if ( elem->GetType() == SMDSAbs_Edge ) - { - // create a ceiling edge - aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), - vecNewNodes[ 1 ]->second.back() ); + if ( elem->GetType() == SMDSAbs_Edge ) { + if(!elem->IsQuadratic()) { + // create a ceiling edge + aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back() ); + } + else { + // create a ceiling edge + aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back(), + vecNewNodes[ 2 ]->second.back()); + } } if ( elem->GetType() != SMDSAbs_Face ) continue; @@ -2220,43 +2821,72 @@ static void makeWalls (SMESHDS_Mesh* aMesh, set avoidSet; avoidSet.insert( elem ); - // loop on a face nodes set aFaceLastNodes; int iNode, nbNodes = vecNewNodes.size(); - for ( iNode = 0; iNode < nbNodes; iNode++ ) - { - aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); - // look for free links of a face - int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; - const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; - const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; - // check if a link is free - if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) - { - hasFreeLinks = true; - // make an edge and a ceiling for a new edge - if ( !aMesh->FindEdge( n1, n2 )) - aMesh->AddEdge( n1, n2 ); - n1 = vecNewNodes[ iNode ]->second.back(); - n2 = vecNewNodes[ iNext ]->second.back(); - if ( !aMesh->FindEdge( n1, n2 )) - aMesh->AddEdge( n1, n2 ); + if(!elem->IsQuadratic()) { + // loop on a face nodes + for ( iNode = 0; iNode < nbNodes; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); + // look for free links of a face + int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; + const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; + const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; + // check if a link is free + if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) { + hasFreeLinks = true; + // make an edge and a ceiling for a new edge + if ( !aMesh->FindEdge( n1, n2 )) { + aMesh->AddEdge( n1, n2 ); + } + n1 = vecNewNodes[ iNode ]->second.back(); + n2 = vecNewNodes[ iNext ]->second.back(); + if ( !aMesh->FindEdge( n1, n2 )) { + aMesh->AddEdge( n1, n2 ); + } + } + } + } + else { // elem is quadratic face + int nbn = nbNodes/2; + for ( iNode = 0; iNode < nbn; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); + int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1; + const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; + const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; + // check if a link is free + if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) { + hasFreeLinks = true; + // make an edge and a ceiling for a new edge + // find medium node + const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; + if ( !aMesh->FindEdge( n1, n2, n3 )) { + aMesh->AddEdge( n1, n2, n3 ); + } + n1 = vecNewNodes[ iNode ]->second.back(); + n2 = vecNewNodes[ iNext ]->second.back(); + n3 = vecNewNodes[ iNode+nbn ]->second.back(); + if ( !aMesh->FindEdge( n1, n2, n3 )) { + aMesh->AddEdge( n1, n2, n3 ); + } + } + } + for ( iNode = nbn; iNode < 2*nbn; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); } } + // sweep free links into faces - if ( hasFreeLinks ) - { + if ( hasFreeLinks ) { list & newVolumes = itElem->second; - int iStep, nbSteps = vecNewNodes[0]->second.size(); + int iStep; //, nbSteps = vecNewNodes[0]->second.size(); int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps; set initNodeSet, faceNodeSet; for ( iNode = 0; iNode < nbNodes; iNode++ ) initNodeSet.insert( vecNewNodes[ iNode ]->first ); - for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) - { + for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) { list::iterator v = newVolumes.begin(); iVol = 0; while ( iVol++ < volNb ) v++; @@ -2264,36 +2894,50 @@ static void makeWalls (SMESHDS_Mesh* aMesh, list< int > fInd; SMDS_VolumeTool vTool( *v ); int iF, nbF = vTool.NbFaces(); - for ( iF = 0; iF < nbF; iF ++ ) + for ( iF = 0; iF < nbF; iF ++ ) { if (vTool.IsFreeFace( iF ) && vTool.GetFaceNodes( iF, faceNodeSet ) && initNodeSet != faceNodeSet) // except an initial face fInd.push_back( iF ); + } if ( fInd.empty() ) continue; // create faces for all steps - for ( iStep = 0; iStep < nbSteps; iStep++ ) - { + for ( iStep = 0; iStep < nbSteps; iStep++ ) { vTool.Set( *v ); vTool.SetExternalNormal(); list< int >::iterator ind = fInd.begin(); - for ( ; ind != fInd.end(); ind++ ) - { + for ( ; ind != fInd.end(); ind++ ) { const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind ); - switch ( vTool.NbFaceNodes( *ind ) ) { + int nbn = vTool.NbFaceNodes( *ind ); + //switch ( vTool.NbFaceNodes( *ind ) ) { + switch ( nbn ) { case 3: aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break; case 4: aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break; default: { - int nbPolygonNodes = vTool.NbFaceNodes( *ind ); - vector polygon_nodes (nbPolygonNodes); - for (int inode = 0; inode < nbPolygonNodes; inode++) { - polygon_nodes[inode] = nodes[inode]; + if( (*v)->IsQuadratic() ) { + if(nbn==6) { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]); break; + } + else { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]); + break; + } + } + else { + int nbPolygonNodes = vTool.NbFaceNodes( *ind ); + vector polygon_nodes (nbPolygonNodes); + for (int inode = 0; inode < nbPolygonNodes; inode++) { + polygon_nodes[inode] = nodes[inode]; + } + aMesh->AddPolygonalFace(polygon_nodes); } - aMesh->AddPolygonalFace(polygon_nodes); break; } } @@ -2308,12 +2952,13 @@ static void makeWalls (SMESHDS_Mesh* aMesh, // make a ceiling face with a normal external to a volume SMDS_VolumeTool lastVol( itElem->second.back() ); + int iF = lastVol.GetFaceIndex( aFaceLastNodes ); - if ( iF >= 0 ) - { + if ( iF >= 0 ) { lastVol.SetExternalNormal(); const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF ); - switch ( lastVol.NbFaceNodes( iF ) ) { + int nbn = lastVol.NbFaceNodes( iF ); + switch ( nbn ) { case 3: if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ])) @@ -2326,18 +2971,36 @@ static void makeWalls (SMESHDS_Mesh* aMesh, break; default: { - int nbPolygonNodes = lastVol.NbFaceNodes( iF ); - vector polygon_nodes (nbPolygonNodes); - for (int inode = 0; inode < nbPolygonNodes; inode++) { - polygon_nodes[inode] = nodes[inode]; + if(itElem->second.back()->IsQuadratic()) { + if(nbn==6) { + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]) ) { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]); break; + } + } + else { // nbn==8 + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]) ) + aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]); + } + } + else { + int nbPolygonNodes = lastVol.NbFaceNodes( iF ); + vector polygon_nodes (nbPolygonNodes); + for (int inode = 0; inode < nbPolygonNodes; inode++) { + polygon_nodes[inode] = nodes[inode]; + } + if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) + aMesh->AddPolygonalFace(polygon_nodes); } - if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) - aMesh->AddPolygonalFace(polygon_nodes); } break; } } - } // loop on swept elements } @@ -2355,6 +3018,8 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, MESSAGE( "RotationSweep()"); gp_Trsf aTrsf; aTrsf.SetRotation( theAxis, theAngle ); + gp_Trsf aTrsf2; + aTrsf2.SetRotation( theAxis, theAngle/2. ); gp_Lin aLine( theAxis ); double aSqTol = theTol * theTol; @@ -2367,8 +3032,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; @@ -2383,8 +3047,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeOfNodeListMapItr nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) - { + if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; list& listNewNodes = nIt->second; @@ -2396,19 +3059,53 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, const SMDS_MeshNode * newNode = node; for ( int i = 0; i < theNbSteps; i++ ) { if ( !isOnAxis ) { - aTrsf.Transforms( coord[0], coord[1], coord[2] ); + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create two nodes + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + //aTrsf.Transforms( coord[0], coord[1], coord[2] ); + newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + //aTrsf.Transforms( coord[0], coord[1], coord[2] ); + } + else { + aTrsf.Transforms( coord[0], coord[1], coord[2] ); + } newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); } - listNewNodes.push_back( newNode ); + listNewNodes.push_back( newNode ); + } + } + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==theNbSteps) { + listNewNodes.clear(); + // make new nodes + gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + double coord[3]; + aXYZ.Coord( coord[0], coord[1], coord[2] ); + const SMDS_MeshNode * newNode = node; + for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + } + } } } newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps ); } @@ -2493,19 +3190,23 @@ void SMESH_MeshEditor::ExtrusionSweep { SMESHDS_Mesh* aMesh = GetMeshDS(); + int nbsteps = theParams.mySteps->Length(); + TNodeOfNodeListMap mapNewNodes; + //TNodeOfNodeVecMap mapNewNodes; TElemOfVecOfNnlmiMap mapElemNewNodes; + //TElemOfVecOfMapNodesMap mapElemNewNodes; // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { // check element type const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; vector & newNodesItVec = mapElemNewNodes[ elem ]; + //vector & newNodesItVec = mapElemNewNodes[ elem ]; newNodesItVec.reserve( elem->NbNodes() ); // loop on elem nodes @@ -2516,15 +3217,33 @@ void SMESH_MeshEditor::ExtrusionSweep const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) - { + //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node ); + if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; + //nIt = mapNewNodes.insert( make_pair( node, vector() )).first; list& listNewNodes = nIt->second; + //vector& vecNewNodes = nIt->second; + //vecNewNodes.reserve(nbsteps); // make new nodes double coord[] = { node->X(), node->Y(), node->Z() }; - int nbsteps = theParams.mySteps->Length(); + //int nbsteps = theParams.mySteps->Length(); for ( int i = 0; i < nbsteps; i++ ) { + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create additional node + double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.; + double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.; + double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.; + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(x, y, z, + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + listNewNodes.push_back( newNode ); + } + } //aTrsf.Transforms( coord[0], coord[1], coord[2] ); coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); @@ -2533,20 +3252,59 @@ void SMESH_MeshEditor::ExtrusionSweep const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], theTolerance, theParams.myNodes); listNewNodes.push_back( newNode ); + //vecNewNodes[i]=newNode; } else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); listNewNodes.push_back( newNode ); + //vecNewNodes[i]=newNode; + } + } + } + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==nbsteps) { + listNewNodes.clear(); + double coord[] = { node->X(), node->Y(), node->Z() }; + for ( int i = 0; i < nbsteps; i++ ) { + double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); + double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); + double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(x, y, z, + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + listNewNodes.push_back( newNode ); + } + coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); + coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); + coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + } + } } } } newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps ); } if( theFlags & EXTRUSION_FLAG_BOUNDARY ) { - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps ); } } @@ -2855,6 +3613,14 @@ SMESH_MeshEditor::Extrusion_Error } // make new node + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create additional node + double x = ( aPN1.X() + aPN0.X() )/2.; + double y = ( aPN1.Y() + aPN0.Y() )/2.; + double z = ( aPN1.Z() + aPN0.Z() )/2.; + const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z); + listNewNodes.push_back( newNode ); + } aX = aPN1.X(); aY = aPN1.Y(); aZ = aPN1.Z(); @@ -2867,13 +3633,44 @@ SMESH_MeshEditor::Extrusion_Error aDT0x = aDT1x; } } + + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==aNbTP-1) { + vector aNodes(2*(aNbTP-1)); + gp_XYZ P(node->X(), node->Y(), node->Z()); + list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin(); + int i; + for(i=0; iX() + P.X() )/2.; + double y = ( N->Y() + P.Y() )/2.; + double z = ( N->Z() + P.Z() )/2.; + const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z); + aNodes[2*i] = newN; + aNodes[2*i+1] = N; + P = gp_XYZ(N->X(),N->Y(),N->Z()); + } + listNewNodes.clear(); + for(i=0; i<2*(aNbTP-1); i++) { + listNewNodes.push_back(aNodes[i]); + } + } + } + } + newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], + newNodesItVec[0]->second.size() ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements, + aNbTP-1 ); return EXTR_OK; } @@ -2908,8 +3705,7 @@ void SMESH_MeshEditor::Transform (set & theElems, // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; @@ -2979,8 +3775,7 @@ void SMESH_MeshEditor::Transform (set & theElems, { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD }; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem || elem->GetType() == SMDSAbs_Node ) continue; @@ -3071,12 +3866,46 @@ void SMESH_MeshEditor::Transform (set & theElems, else i = index[ nbNodes - 4 ]; + if(elem->IsQuadratic()) { + static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + i = anIds; + if(needReverse) { + if(nbNodes==3) { // quadratic edge + static int anIds[] = {1,0,2}; + i = anIds; + } + else if(nbNodes==6) { // quadratic triangle + static int anIds[] = {0,2,1,5,4,3}; + i = anIds; + } + else if(nbNodes==8) { // quadratic quadrangle + static int anIds[] = {0,3,2,1,7,6,5,4}; + i = anIds; + } + else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes + static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; + i = anIds; + } + else if(nbNodes==13) { // quadratic pyramid of 13 nodes + static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + i = anIds; + } + else if(nbNodes==15) { // quadratic pentahedron with 15 nodes + static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; + i = anIds; + } + else { // nbNodes==20 - quadratic hexahedron with 20 nodes + static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + i = anIds; + } + } + } + // find transformed nodes const SMDS_MeshNode* nodes[8]; int iNode = 0; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + while ( itN->more() ) { const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); @@ -3087,18 +3916,26 @@ void SMESH_MeshEditor::Transform (set & theElems, if ( iNode != nbNodes ) continue; // not all nodes transformed - if ( theCopy ) - { + if ( theCopy ) { // add a new element switch ( elemType ) { case SMDSAbs_Edge: - aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ); + if ( nbNodes == 2 ) + aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ); + else + aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break; case SMDSAbs_Face: if ( nbNodes == 3 ) aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); - else + else if(nbNodes==4) aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]); + else if(nbNodes==6) + aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); + else // nbNodes==8 + aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); break; case SMDSAbs_Volume: if ( nbNodes == 4 ) @@ -3112,6 +3949,22 @@ void SMESH_MeshEditor::Transform (set & theElems, else if ( nbNodes == 5 ) aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], nodes[ 4 ]); + else if(nbNodes==10) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]); + else if(nbNodes==13) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12]); + else if(nbNodes==15) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]); + else // nbNodes==20 + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14], + nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]); break; default:; } @@ -3275,13 +4128,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // Fill nodeNodeMap and elems TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin(); - for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) - { + for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) { list& nodes = *grIt; list::iterator nIt = nodes.begin(); const SMDS_MeshNode* nToKeep = *nIt; - for ( ; nIt != nodes.end(); nIt++ ) - { + for ( ; nIt != nodes.end(); nIt++ ) { const SMDS_MeshNode* nToRemove = *nIt; nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); if ( nToRemove != nToKeep ) { @@ -3290,15 +4141,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); - while ( invElemIt->more() ) - elems.insert( invElemIt->next() ); + while ( invElemIt->more() ) { + const SMDS_MeshElement* elem = invElemIt->next(); + elems.insert(elem); + } } } // Change element nodes or remove an element set::iterator eIt = elems.begin(); - for ( ; eIt != elems.end(); eIt++ ) - { + for ( ; eIt != elems.end(); eIt++ ) { const SMDS_MeshElement* elem = *eIt; int nbNodes = elem->NbNodes(); int aShapeId = FindShape( elem ); @@ -3309,8 +4161,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // get new seq of nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + while ( itN->more() ) { const SMDS_MeshNode* n = static_cast( itN->next() ); @@ -3330,8 +4181,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) bool isOk = true; int nbUniqueNodes = nodeSet.size(); - if ( nbNodes != nbUniqueNodes ) // some nodes stick - { + if ( nbNodes != nbUniqueNodes ) { // some nodes stick // Polygons and Polyhedral volumes if (elem->IsPoly()) { @@ -3360,15 +4210,18 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) aMesh->SetMeshElementOnShape(newElem, aShapeId); } aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); - } else { + } + else { rmElemIds.push_back(elem->GetID()); } - } else if (elem->GetType() == SMDSAbs_Volume) { + } + else if (elem->GetType() == SMDSAbs_Volume) { // Polyhedral volume if (nbUniqueNodes < 4) { rmElemIds.push_back(elem->GetID()); - } else { + } + else { // each face has to be analized in order to check volume validity const SMDS_PolyhedralVolumeOfNodes* aPolyedre = static_cast( elem ); @@ -3403,11 +4256,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) else rmElemIds.push_back(elem->GetID()); - } else { + } + else { rmElemIds.push_back(elem->GetID()); } } - } else { + } + else { } continue; @@ -3478,7 +4333,96 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) else isOk = false; break; - case 8: { //////////////////////////////////// HEXAHEDRON + case 8: { + if(elem->IsQuadratic()) { // Quadratic quadrangle + // 1 5 2 + // +---+---+ + // | | + // | | + // 4+ +6 + // | | + // | | + // +---+---+ + // 0 7 3 + isOk = false; + if(nbRepl==3) { + nbUniqueNodes = 6; + if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[5]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[6]; + isOk = true; + } + if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[1]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[5]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[0]; + isOk = true; + } + if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[1]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[2]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[3]; + isOk = true; + } + } + break; + } + //////////////////////////////////// HEXAHEDRON isOk = false; SMDS_VolumeTool hexa (elem); hexa.SetExternalNormal(); @@ -3682,11 +4626,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities ); } - } else { + } + else { // Change regular element or polygon aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes ); } - } else { + } + else { // Remove invalid regular element or invalid polygon rmElemIds.push_back( elem->GetID() ); } @@ -3779,14 +4725,52 @@ const SMDS_MeshElement* i1 = iNode - 1; } // find a n2 linked to n1 - for ( iNode = 0; iNode < 2; iNode++ ) { - if ( iNode ) // node before n1 - n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; - else // node after n1 - n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; - if ( n == n2 ) - return elem; + if(!elem->IsQuadratic()) { + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; + if ( n == n2 ) + return elem; + } } + else { // analysis for quadratic elements + bool IsFind = false; + // check using only corner nodes + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ]; + if ( n == n2 ) + IsFind = true; + } + if(IsFind) { + return elem; + } + else { + // check using all nodes + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while ( anIter->more() ) { + faceNodes[iNode] = static_cast(anIter->next()); + if ( faceNodes[ iNode++ ] == n1 ) + i1 = iNode - 1; + } + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; + if ( n == n2 ) { + return elem; + } + } + } + } // end analysis for quadratic elements } return 0; } @@ -3830,12 +4814,12 @@ static bool findFreeBorder (const SMDS_MeshNode* theFirstNode, theNodes.push_back( theFirstNode ); theNodes.push_back( theSecondNode ); - const SMDS_MeshNode* nodes [5], *nIgnore = theFirstNode, * nStart = theSecondNode; + //vector nodes; + const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode; set < const SMDS_MeshElement* > foundElems; bool needTheLast = ( theLastNode != 0 ); - while ( nStart != theLastNode ) - { + while ( nStart != theLastNode ) { if ( nStart == theFirstNode ) return !needTheLast; @@ -3846,13 +4830,24 @@ static bool findFreeBorder (const SMDS_MeshNode* theFirstNode, SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator(); while ( invElemIt->more() ) { const SMDS_MeshElement* e = invElemIt->next(); - if ( e == curElem || foundElems.insert( e ).second ) - { + if ( e == curElem || foundElems.insert( e ).second ) { // get nodes - SMDS_ElemIteratorPtr nIt = e->nodesIterator(); int iNode = 0, nbNodes = e->NbNodes(); - while ( nIt->more() ) - nodes[ iNode++ ] = static_cast( nIt->next() ); + const SMDS_MeshNode* nodes[nbNodes+1]; + if(e->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(e); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + nodes[ iNode++ ] = 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++ ) @@ -3987,8 +4982,7 @@ SMESH_MeshEditor::Sew_Error MESSAGE(" Free Border 1 not found " ); aResult = SEW_BORDER1_NOT_FOUND; } - if (theSideIsFreeBorder) - { + if (theSideIsFreeBorder) { // Free border 2 // -------------- if (!findFreeBorder(theSideFirstNode, theSideSecondNode, theSideThirdNode, @@ -4000,8 +4994,7 @@ SMESH_MeshEditor::Sew_Error if ( aResult != SEW_OK ) return aResult; - if (!theSideIsFreeBorder) - { + if (!theSideIsFreeBorder) { // Side 2 // -------------- @@ -4027,8 +5020,7 @@ SMESH_MeshEditor::Sew_Error gp_XYZ Ps2( theSideSecondNode->X(), theSideSecondNode->Y(), theSideSecondNode->Z() ); double tol2 = 1.e-8; gp_Vec Vbs1( Pb1 - Ps1 ),Vbs2( Pb2 - Ps2 ); - if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) - { + if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) { // Need node movement. // find X and Z axes to create trsf @@ -4057,8 +5049,7 @@ SMESH_MeshEditor::Sew_Error nBordXYZ.insert( TNodeXYZMap::value_type( n, xyz )); } } - else - { + else { // just insert nodes XYZ in the nBordXYZ map for ( nBordIt = bordNodes.begin(); nBordIt != bordNodes.end(); nBordIt++ ) { const SMDS_MeshNode* n = *nBordIt; @@ -4110,13 +5101,27 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes; if ( isVolume ) // --volume hasVolumes = true; - else if ( nbNodes > 2 ) { // --face + //else if ( nbNodes > 2 ) { // --face + else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode - SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); - while ( nIt->more() ) { - nodes[ iNode ] = static_cast( nIt->next() ); - if ( nodes[ iNode++ ] == prevSideNode ) - iPrevNode = iNode - 1; + if(elem->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + nodes[ iNode ] = anIter->next(); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } + } + else { + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + while ( nIt->more() ) { + nodes[ iNode ] = static_cast( nIt->next() ); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } } // there are 2 links to check nbNodes = 2; @@ -4129,7 +5134,8 @@ SMESH_MeshEditor::Sew_Error if ( isVolume ) { if ( !volume.IsLinked( n, prevSideNode )) continue; - } else { + } + else { if ( iNode ) // a node before prevSideNode n = nodes[ iPrevNode == 0 ? elem->NbNodes() - 1 : iPrevNode - 1 ]; else // a node after prevSideNode @@ -4408,18 +5414,39 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, int iNode = 0, il1, il2, i3, i4; il1 = il2 = i3 = i4 = -1; const SMDS_MeshNode* nodes[ theFace->NbNodes() ]; - SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - if ( n == theBetweenNode1 ) - il1 = iNode; - else if ( n == theBetweenNode2 ) - il2 = iNode; - else if ( i3 < 0 ) - i3 = iNode; - else - i4 = iNode; - nodes[ iNode++ ] = n; + + if(theFace->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(theFace); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + const SMDS_MeshNode* n = anIter->next(); + if ( n == theBetweenNode1 ) + il1 = iNode; + else if ( n == theBetweenNode2 ) + il2 = iNode; + else if ( i3 < 0 ) + i3 = iNode; + else + i4 = iNode; + nodes[ iNode++ ] = n; + } + } + else { + SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + if ( n == theBetweenNode1 ) + il1 = iNode; + else if ( n == theBetweenNode2 ) + il2 = iNode; + else if ( i3 < 0 ) + i3 = iNode; + else + i4 = iNode; + nodes[ iNode++ ] = n; + } } if ( il1 < 0 || il2 < 0 || i3 < 0 ) return ; @@ -4448,25 +5475,48 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // add nodes of face up to first node of link bool isFLN = false; - 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; + if(theFace->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(theFace); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() && !isFLN ) { + const SMDS_MeshNode* n = 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++] = 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; + } } // edit or replace the face @@ -4474,8 +5524,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, if (theFace->IsPoly()) { aMesh->ChangePolygonNodes(theFace, poly_nodes); - - } else { + } + else { int aShapeId = FindShape( theFace ); SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); @@ -4487,81 +5537,184 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, return; } - // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 - int nbLinkNodes = 2 + aNodesToInsert.size(); - const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; - linkNodes[ 0 ] = nodes[ il1 ]; - linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ]; - list::iterator nIt = aNodesToInsert.begin(); - for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { - linkNodes[ iNode++ ] = *nIt; - } - // decide how to split a quadrangle: compare possible variants - // and choose which of splits to be a quadrangle - int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad; - if ( nbFaceNodes == 3 ) - { - iBestQuad = nbSplits; - i4 = i3; - } - else if ( nbFaceNodes == 4 ) - { - SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio); - double aBestRate = DBL_MAX; - for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) { - i1 = 0; i2 = 1; - double aBadRate = 0; - // evaluate elements quality - for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) { - if ( iSplit == iQuad ) { - SMDS_FaceOfNodes quad (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ i3 ], - nodes[ i4 ]); - aBadRate += getBadRate( &quad, aCrit ); + if( !theFace->IsQuadratic() ) { + + // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 + int nbLinkNodes = 2 + aNodesToInsert.size(); + const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; + linkNodes[ 0 ] = nodes[ il1 ]; + linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ]; + list::iterator nIt = aNodesToInsert.begin(); + for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { + linkNodes[ iNode++ ] = *nIt; + } + // decide how to split a quadrangle: compare possible variants + // and choose which of splits to be a quadrangle + int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad; + if ( nbFaceNodes == 3 ) { + iBestQuad = nbSplits; + i4 = i3; + } + else if ( nbFaceNodes == 4 ) { + SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio); + double aBestRate = DBL_MAX; + for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) { + i1 = 0; i2 = 1; + double aBadRate = 0; + // evaluate elements quality + for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) { + if ( iSplit == iQuad ) { + SMDS_FaceOfNodes quad (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ i3 ], + nodes[ i4 ]); + aBadRate += getBadRate( &quad, aCrit ); + } + else { + SMDS_FaceOfNodes tria (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ iSplit < iQuad ? i4 : i3 ]); + aBadRate += getBadRate( &tria, aCrit ); + } } - else { - SMDS_FaceOfNodes tria (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ iSplit < iQuad ? i4 : i3 ]); - aBadRate += getBadRate( &tria, aCrit ); + // choice + if ( aBadRate < aBestRate ) { + iBestQuad = iQuad; + aBestRate = aBadRate; } } - // choice - if ( aBadRate < aBestRate ) { - iBestQuad = iQuad; - aBestRate = aBadRate; + } + + // create new elements + SMESHDS_Mesh *aMesh = GetMeshDS(); + int aShapeId = FindShape( theFace ); + + i1 = 0; i2 = 1; + for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) { + SMDS_MeshElement* newElem = 0; + if ( iSplit == iBestQuad ) + newElem = aMesh->AddFace (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ i3 ], + nodes[ i4 ]); + else + newElem = aMesh->AddFace (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ iSplit < iBestQuad ? i4 : i3 ]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + + // change nodes of theFace + const SMDS_MeshNode* newNodes[ 4 ]; + newNodes[ 0 ] = linkNodes[ i1 ]; + newNodes[ 1 ] = linkNodes[ i2 ]; + newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ]; + newNodes[ 3 ] = nodes[ i4 ]; + aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); + } // end if(!theFace->IsQuadratic()) + else { // theFace is quadratic + // we have to split theFace on simple triangles and one simple quadrangle + int tmp = il1/2; + int nbshift = tmp*2; + // shift nodes in nodes[] by nbshift + int i,j; + for(i=0; iAddFace (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ i3 ], - nodes[ i4 ]); - else - newElem = aMesh->AddFace (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ iSplit < iBestQuad ? i4 : i3 ]); - if ( aShapeId && newElem ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + int n1,n2,n3; + if(nbFaceNodes==6) { // quadratic triangle + SMDS_MeshElement* newElem = + aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + if(theFace->IsMediumNode(nodes[il1])) { + // create quadrangle + newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 1; + n2 = 2; + n3 = 3; + } + else { + // create quadrangle + newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 0; + n2 = 1; + n3 = 5; + } + } + else { // nbFaceNodes==8 - quadratic quadrangle + SMDS_MeshElement* newElem = + aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + if(theFace->IsMediumNode(nodes[il1])) { + // create quadrangle + newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 1; + n2 = 2; + n3 = 3; + } + else { + // create quadrangle + newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 0; + n2 = 1; + n3 = 7; + } + } + // create needed triangles using n1,n2,n3 and inserted nodes + int nbn = 2 + aNodesToInsert.size(); + const SMDS_MeshNode* aNodes[nbn]; + aNodes[0] = nodes[n1]; + aNodes[nbn-1] = nodes[n2]; + list::iterator nIt = aNodesToInsert.begin(); + for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { + aNodes[iNode++] = *nIt; + } + for(i=1; iAddFace(aNodes[i-1],aNodes[i],nodes[n3]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + // remove old quadratic face + aMesh->RemoveElement(theFace); } - - // change nodes of theFace - const SMDS_MeshNode* newNodes[ 4 ]; - newNodes[ 0 ] = linkNodes[ i1 ]; - newNodes[ 1 ] = linkNodes[ i2 ]; - newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ]; - newNodes[ 3 ] = nodes[ i4 ]; - aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); } //======================================================================= @@ -4607,7 +5760,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode poly_nodes.push_back(*nIt); } } - } else if (faceNodes[inode] == theBetweenNode2) { + } + else if (faceNodes[inode] == theBetweenNode2) { if (faceNodes[inode + 1] == theBetweenNode1) { nbInserted = theNodesToInsert.size(); @@ -4619,7 +5773,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode } poly_nodes.push_back(*nIt); } - } else { + } + else { } } } @@ -4632,7 +5787,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode if (elem->IsPoly()) { aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - } else { + } + else { int aShapeId = FindShape( elem ); SMDS_MeshElement* newElem = @@ -4709,11 +5865,24 @@ SMESH_MeshEditor::Sew_Error if ( elem->GetType() == SMDSAbs_Face ) { faceSet->insert( elem ); set faceNodeSet; - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - nodeSet->insert( n ); - faceNodeSet.insert( n ); + if(elem->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + const SMDS_MeshNode* n = anIter->next(); + nodeSet->insert( n ); + faceNodeSet.insert( n ); + } + } + else { + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + nodeSet->insert( n ); + faceNodeSet.insert( n ); + } } setOfFaceNodeSet.insert( faceNodeSet ); } @@ -4754,8 +5923,7 @@ SMESH_MeshEditor::Sew_Error // face does not exist // ------------------------------------------------------------------------- - if ( !volSet->empty() ) - { + if ( !volSet->empty() ) { //int nodeSetSize = nodeSet->size(); // loop on given volumes @@ -4778,9 +5946,11 @@ SMESH_MeshEditor::Sew_Error // no such a face is given but it still can exist, check it if ( nbNodes == 3 ) { aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] ); - } else if ( nbNodes == 4 ) { + } + else if ( nbNodes == 4 ) { aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); - } else { + } + else { vector poly_nodes (nbNodes); for (int inode = 0; inode < nbNodes; inode++) { poly_nodes[inode] = fNodes[inode]; @@ -4792,9 +5962,11 @@ SMESH_MeshEditor::Sew_Error // create a temporary face if ( nbNodes == 3 ) { aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); - } else if ( nbNodes == 4 ) { + } + else if ( nbNodes == 4 ) { aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); - } else { + } + else { vector poly_nodes (nbNodes); for (int inode = 0; inode < nbNodes; inode++) { poly_nodes[inode] = fNodes[inode]; @@ -4946,8 +6118,7 @@ SMESH_MeshEditor::Sew_Error // loop on links in linkList; find faces by links and append links // of the found faces to linkList list< TPairOfNodes >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ; - for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) - { + for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) { TPairOfNodes link[] = { *linkIt[0], *linkIt[1] }; long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second ); if ( linkIdSet.find( linkID ) == linkIdSet.end() ) @@ -4959,8 +6130,12 @@ SMESH_MeshEditor::Sew_Error // --------------------------------------------------------------- const SMDS_MeshElement* face[] = { 0, 0 }; - const SMDS_MeshNode* faceNodes[ 2 ][ 5 ]; - const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ; + //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ]; + vector fnodes1(9); + vector fnodes2(9); + //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ; + vector notLinkNodes1(6); + vector notLinkNodes2(6); int iLinkNode[2][2]; for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides const SMDS_MeshNode* n1 = link[iSide].first; @@ -4984,40 +6159,109 @@ SMESH_MeshEditor::Sew_Error faceSet->erase( f ); // get face nodes and find ones of a link iNode = 0; - SMDS_ElemIteratorPtr nIt = f->nodesIterator(); - while ( nIt->more() ) { - const SMDS_MeshNode* n = - static_cast( nIt->next() ); - if ( n == n1 ) - iLinkNode[ iSide ][ 0 ] = iNode; - else if ( n == n2 ) - iLinkNode[ iSide ][ 1 ] = iNode; - else if ( notLinkNodes[ iSide ][ 0 ] ) - notLinkNodes[ iSide ][ 1 ] = n; - else - notLinkNodes[ iSide ][ 0 ] = n; - faceNodes[ iSide ][ iNode++ ] = n; + int nbl = -1; + if(f->IsPoly()) { + if(iSide==0) { + fnodes1.resize(f->NbNodes()+1); + notLinkNodes1.resize(f->NbNodes()-2); + } + else { + fnodes2.resize(f->NbNodes()+1); + notLinkNodes2.resize(f->NbNodes()-2); + } + } + if(!f->IsQuadratic()) { + SMDS_ElemIteratorPtr nIt = f->nodesIterator(); + while ( nIt->more() ) { + const SMDS_MeshNode* n = + static_cast( nIt->next() ); + if ( n == n1 ) { + iLinkNode[ iSide ][ 0 ] = iNode; + } + else if ( n == n2 ) { + iLinkNode[ iSide ][ 1 ] = iNode; + } + //else if ( notLinkNodes[ iSide ][ 0 ] ) + // notLinkNodes[ iSide ][ 1 ] = n; + //else + // notLinkNodes[ iSide ][ 0 ] = n; + else { + nbl++; + if(iSide==0) + notLinkNodes1[nbl] = n; + //notLinkNodes1.push_back(n); + else + notLinkNodes2[nbl] = n; + //notLinkNodes2.push_back(n); + } + //faceNodes[ iSide ][ iNode++ ] = n; + if(iSide==0) { + fnodes1[iNode++] = n; + } + else { + fnodes2[iNode++] = n; + } + } + } + else { // f->IsQuadratic() + const SMDS_QuadraticFaceOfNodes* F = + static_cast(f); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while ( anIter->more() ) { + const SMDS_MeshNode* n = + static_cast( anIter->next() ); + if ( n == n1 ) { + iLinkNode[ iSide ][ 0 ] = iNode; + } + else if ( n == n2 ) { + iLinkNode[ iSide ][ 1 ] = iNode; + } + else { + nbl++; + if(iSide==0) { + notLinkNodes1[nbl] = n; + } + else { + notLinkNodes2[nbl] = n; + } + } + if(iSide==0) { + fnodes1[iNode++] = n; + } + else { + fnodes2[iNode++] = n; + } + } + } + //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ]; + if(iSide==0) { + fnodes1[iNode] = fnodes1[0]; + } + else { + fnodes2[iNode] = fnodes1[0]; } - faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ]; } } } } + // check similarity of elements of the sides if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) { MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); - if ( nReplaceMap.size() == 2 ) // faces on input nodes not found + if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); - else + } + else { aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } break; // do not return because it s necessary to remove tmp faces } // set nodes to merge // ------------------- - if ( face[0] && face[1] ) - { + if ( face[0] && face[1] ) { int nbNodes = face[0]->NbNodes(); if ( nbNodes != face[1]->NbNodes() ) { MESSAGE("Diff nb of face nodes"); @@ -5025,9 +6269,12 @@ SMESH_MeshEditor::Sew_Error break; // do not return because it s necessary to remove tmp faces } bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle - if ( nbNodes == 3 ) + if ( nbNodes == 3 ) { + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][0], notLinkNodes[1][0] )); nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][0], notLinkNodes[1][0] )); + ( notLinkNodes1[0], notLinkNodes2[0] )); + } else { for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides // analyse link orientation in faces @@ -5041,34 +6288,44 @@ SMESH_MeshEditor::Sew_Error reverse[ iSide ] = !reverse[ iSide ]; } if ( reverse[0] == reverse[1] ) { - nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][0], notLinkNodes[1][0] )); - nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][1], notLinkNodes[1][1] )); + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][0], notLinkNodes[1][0] )); + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][1], notLinkNodes[1][1] )); + for(int nn=0; nn::iterator, bool > iter_isnew = linkIdSet.insert( linkID ); if ( !iter_isnew.second ) { // already in a set: no need to process linkIdSet.erase( iter_isnew.first ); } else // new in set == encountered for the first time: add { - const SMDS_MeshNode* n1 = nodes[ iNode ]; - const SMDS_MeshNode* n2 = nodes[ iNode + 1]; + //const SMDS_MeshNode* n1 = nodes[ iNode ]; + //const SMDS_MeshNode* n2 = nodes[ iNode + 1]; + const SMDS_MeshNode* n1 = fnodes1[ iNode ]; + const SMDS_MeshNode* n2 = fnodes1[ iNode + 1]; linkList[0].push_back ( TPairOfNodes( n1, n2 )); linkList[1].push_back ( TPairOfNodes( nReplaceMap[n1], nReplaceMap[n2] )); } @@ -5100,8 +6357,7 @@ SMESH_MeshEditor::Sew_Error // loop on nodes replacement map TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt; for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ ) - if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) - { + if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) { const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first; nodeIDsToRemove.push_back( nToRemove->GetID() ); // loop on elements sharing nToRemove @@ -5128,7 +6384,7 @@ SMESH_MeshEditor::Sew_Error if ( nbReplaced ) aMesh->ChangeElementNodes( e, nodes, nbNodes ); } - } + } Remove( nodeIDsToRemove, true ); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index b3f104ae2..a2c73ac6d 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -433,7 +433,7 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) */ //============================================================================= -const TopoDS_Shape & SMESH_subMesh::GetSubShape() +const TopoDS_Shape & SMESH_subMesh::GetSubShape() const { //MESSAGE("SMESH_subMesh::GetSubShape"); return _subShape; @@ -540,7 +540,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( ! CanAddHypothesis( anHyp )) return SMESH_Hypothesis::HYP_BAD_DIM; - if ( GetSimilarAttached( _subShape, anHyp ) ) + if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) ) return SMESH_Hypothesis::HYP_ALREADY_EXIST; if ( !_meshDS->AddHypothesis(_subShape, anHyp)) @@ -549,9 +549,9 @@ SMESH_Hypothesis::Hypothesis_Status // Serve Propagation of 1D hypothesis if (event == ADD_HYP) { bool isPropagationOk = true; - string hypName = anHyp->GetName(); + bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 ); - if (hypName == "Propagation") { + if ( isPropagationHyp ) { TopExp_Explorer exp (_subShape, TopAbs_EDGE); TopTools_MapOfShape aMap; for (; exp.More(); exp.Next()) { @@ -579,7 +579,11 @@ SMESH_Hypothesis::Hypothesis_Status } else { } - if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + if ( isPropagationOk ) { + if ( isPropagationHyp ) + return ret; // nothing more to do for "Propagation" hypothesis + } + else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { ret = SMESH_Hypothesis::HYP_CONCURENT; } } // Serve Propagation of 1D hypothesis @@ -598,7 +602,9 @@ SMESH_Hypothesis::Hypothesis_Status { bool isPropagationOk = true; SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" )); - if ( propagFilter.IsOk( anHyp, _subShape )) + bool isPropagationHyp = propagFilter.IsOk( anHyp, _subShape ); + + if ( isPropagationHyp ) { TopExp_Explorer exp (_subShape, TopAbs_EDGE); TopTools_MapOfShape aMap; @@ -620,7 +626,11 @@ SMESH_Hypothesis::Hypothesis_Status isPropagationOk = _father->RebuildPropagationChains(); } - if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + if ( isPropagationOk ) { + if ( isPropagationHyp ) + return ret; // nothing more to do for "Propagation" hypothesis + } + else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { ret = SMESH_Hypothesis::HYP_CONCURENT; } } // Serve Propagation of 1D hypothesis @@ -698,7 +708,7 @@ SMESH_Hypothesis::Hypothesis_Status SetAlgoState(HYP_OK); if (SMESH_Hypothesis::IsStatusFatal( ret )) _meshDS->RemoveHypothesis(_subShape, anHyp); - else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + else if (!_father->IsUsedHypothesis( anHyp, this )) { _meshDS->RemoveHypothesis(_subShape, anHyp); ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; @@ -788,7 +798,7 @@ SMESH_Hypothesis::Hypothesis_Status // ret should be fatal: anHyp was not added ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; } - else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + else if (!_father->IsUsedHypothesis( anHyp, this )) ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; if (SMESH_Hypothesis::IsStatusFatal( ret )) @@ -852,7 +862,7 @@ SMESH_Hypothesis::Hypothesis_Status ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { - if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp + if (_father->IsUsedHypothesis( anHyp, this )) // new Hyp modifiedHyp = true; } else @@ -1607,8 +1617,9 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg if ( mainShape.IsSame( _subShape )) return _subShape; + const bool ignoreAuxiliaryHyps = false; list aUsedHyp = - theAlgo->GetUsedHypothesis( *_father, _subShape ); // copy + theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy // put in a compound all shapes with the same hypothesis assigned // and a good ComputState @@ -1626,7 +1637,7 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg if (subMesh->GetComputeState() == READY_TO_COMPUTE && anAlgo == theAlgo && - anAlgo->GetUsedHypothesis( *_father, S ) == aUsedHyp) + anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) { aBuilder.Add( aCompound, S ); } @@ -1637,26 +1648,31 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg //======================================================================= //function : GetSimilarAttached -//purpose : return nb of hypotheses attached to theShape. +//purpose : return a hypothesis attached to theShape. // If theHyp is provided, similar but not same hypotheses -// are countered; else only applicable ones having theHypType -// are countered +// is returned; else only applicable ones having theHypType +// is returned //======================================================================= const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType) { - SMESH_HypoFilter filter; - filter.Init( SMESH_HypoFilter::HasType( theHyp ? theHyp->GetType() : theHypType )); + SMESH_HypoFilter hypoKind; + hypoKind.Init( hypoKind.HasType( theHyp ? theHyp->GetType() : theHypType )); if ( theHyp ) { - filter.And( SMESH_HypoFilter::HasDim( theHyp->GetDim() )); - filter.AndNot( SMESH_HypoFilter::Is( theHyp )); + hypoKind.And ( hypoKind.HasDim( theHyp->GetDim() )); + hypoKind.AndNot( hypoKind.Is( theHyp )); + if ( theHyp->IsAuxiliary() ) + hypoKind.And( hypoKind.HasName( theHyp->GetName() )); + else + hypoKind.AndNot( hypoKind.IsAuxiliary()); + } + else { + hypoKind.And( hypoKind.IsApplicableTo( theShape )); } - else - filter.And( SMESH_HypoFilter::IsApplicableTo( theShape )); - return _father->GetHypothesis( theShape, filter, false ); + return _father->GetHypothesis( theShape, hypoKind, false ); } //======================================================================= diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index e2af61ac0..5c5b92ec6 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -70,7 +70,7 @@ class SMESH_subMesh const map < int, SMESH_subMesh * >&DependsOn(); //const map < int, SMESH_subMesh * >&Dependants(); - const TopoDS_Shape & GetSubShape(); + const TopoDS_Shape & GetSubShape() const; // bool _vertexSet; // only for vertex subMesh, set to false for dim > 0 @@ -103,17 +103,13 @@ class SMESH_subMesh SMESH_Hypothesis::Hypothesis_Status SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp); - int GetAlgoState() { return _algoState; } + int GetAlgoState() const { return _algoState; } + int GetComputeState() const { return _computeState; }; void DumpAlgoState(bool isMain); bool ComputeStateEngine(int event); - int GetComputeState() - { - return _computeState; - }; - bool IsConform(const SMESH_Algo* theAlgo); // check if a conform mesh will be produced by the Algo diff --git a/src/SMESHDS/SMESHDS_Command.cxx b/src/SMESHDS/SMESHDS_Command.cxx index d8b664e0e..7de0dc637 100644 --- a/src/SMESHDS/SMESHDS_Command.cxx +++ b/src/SMESHDS/SMESHDS_Command.cxx @@ -416,3 +416,199 @@ const list < double >&SMESHDS_Command::GetCoords() { return myReals; } + + +//******************************************************************** +//***** Methods for quadratic elements ****** +//******************************************************************** + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +void SMESHDS_Command::AddEdge(int NewEdgeID, int n1, int n2, int n12) +{ + if (!myType == SMESHDS_AddQuadEdge) { + MESSAGE("SMESHDS_Command::AddEdge : Bad Type"); + return; + } + myIntegers.push_back(NewEdgeID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n12); + myNumber++; +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Command::AddFace(int NewFaceID, + int n1, int n2, int n3, + int n12, int n23, int n31) +{ + if (!myType == SMESHDS_AddQuadTriangle) { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myNumber++; +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Command::AddFace(int NewFaceID, + int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41) +{ + if (!myType == SMESHDS_AddQuadQuadrangle) { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, + int n14, int n24, int n34) +{ + if (!myType == SMESHDS_AddQuadTetrahedron) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myIntegers.push_back(n14); + myIntegers.push_back(n24); + myIntegers.push_back(n34); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, + int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45) +{ + if (!myType == SMESHDS_AddQuadPyramid) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n5); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(n15); + myIntegers.push_back(n25); + myIntegers.push_back(n35); + myIntegers.push_back(n45); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, + int n3, int n4, int n5,int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36) +{ + if (!myType == SMESHDS_AddQuadPentahedron) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n5); + myIntegers.push_back(n6); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myIntegers.push_back(n45); + myIntegers.push_back(n56); + myIntegers.push_back(n64); + myIntegers.push_back(n14); + myIntegers.push_back(n25); + myIntegers.push_back(n36); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48) +{ + if (!myType == SMESHDS_AddQuadHexahedron) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n5); + myIntegers.push_back(n6); + myIntegers.push_back(n7); + myIntegers.push_back(n8); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(n56); + myIntegers.push_back(n67); + myIntegers.push_back(n78); + myIntegers.push_back(n85); + myIntegers.push_back(n15); + myIntegers.push_back(n26); + myIntegers.push_back(n37); + myIntegers.push_back(n48); + myNumber++; +} + diff --git a/src/SMESHDS/SMESHDS_Command.hxx b/src/SMESHDS/SMESHDS_Command.hxx index 3ecd762f3..7f1e3dbd3 100644 --- a/src/SMESHDS/SMESHDS_Command.hxx +++ b/src/SMESHDS/SMESHDS_Command.hxx @@ -54,6 +54,28 @@ class SMESHDS_Command void AddPolyhedralVolume (const int ElementID, std::vector nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); + void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index f2c505b1f..2f7455a58 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -30,22 +30,30 @@ //#include enum SMESHDS_CommandType { - SMESHDS_AddNode, - SMESHDS_AddEdge, - SMESHDS_AddTriangle, - SMESHDS_AddQuadrangle, - SMESHDS_AddPolygon, - SMESHDS_AddTetrahedron, - SMESHDS_AddPyramid, - SMESHDS_AddPrism, - SMESHDS_AddHexahedron, - SMESHDS_AddPolyhedron, - SMESHDS_RemoveNode, - SMESHDS_RemoveElement, - SMESHDS_MoveNode, - SMESHDS_ChangeElementNodes, - SMESHDS_ChangePolyhedronNodes, - SMESHDS_Renumber + SMESHDS_AddNode, + SMESHDS_AddEdge, + SMESHDS_AddTriangle, + SMESHDS_AddQuadrangle, + SMESHDS_AddPolygon, + SMESHDS_AddTetrahedron, + SMESHDS_AddPyramid, + SMESHDS_AddPrism, + SMESHDS_AddHexahedron, + SMESHDS_AddPolyhedron, + SMESHDS_RemoveNode, + SMESHDS_RemoveElement, + SMESHDS_MoveNode, + SMESHDS_ChangeElementNodes, + SMESHDS_ChangePolyhedronNodes, + SMESHDS_Renumber, + // special types for quadratic elements + SMESHDS_AddQuadEdge, + SMESHDS_AddQuadTriangle, + SMESHDS_AddQuadQuadrangle, + SMESHDS_AddQuadTetrahedron, + SMESHDS_AddQuadPyramid, + SMESHDS_AddQuadPentahedron, + SMESHDS_AddQuadHexahedron }; diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index d22746e32..30fb84c6c 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1184,3 +1184,460 @@ SMESHDS_Mesh::~SMESHDS_Mesh() { delete myScript; } + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID); + if(anElem) myScript->AddEdge(ID,n1,n2,n12); + return anElem; +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n12->GetID()); + return anElem; +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + return AddEdgeWithID(n1->GetID(), + n2->GetID(), + n12->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(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_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(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) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(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, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(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) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23, + n31,n14,n24,n34,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID(), ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(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) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5, + n12,n23,n34,n41, + n15,n25,n35,n45,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(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) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6, + n12,n23,n31, + n45,n56,n64, + n14,n25,n36,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron with 15 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(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) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + SMDS_MeshVolume *anElem = 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(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(), + ID); +} + + diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 88c531c9e..6a8f15e6d 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -93,6 +93,16 @@ public: virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -113,6 +123,44 @@ public: const SMDS_MeshNode * n3, const SMDS_MeshNode * n4); + // 2d order triangle of 6 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + // 2d order quadrangle + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID); + virtual SMDS_MeshFace* AddFaceWithID(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, + int ID); + virtual SMDS_MeshFace* AddFace(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 SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -171,6 +219,153 @@ public: const SMDS_MeshNode * n7, const SMDS_MeshNode * n8); + // 2d order tetrahedron of 10 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d order pyramid of 13 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d order Pentahedron with 15 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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); + + // 2d order Hexahedrons with 20 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(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, + int ID); + virtual SMDS_MeshVolume* AddVolume(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 SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, const int ID); diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index 16c606945..327a88161 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -257,3 +257,98 @@ const list& SMESHDS_Script::GetCommands() { return myCommands; } + + +//******************************************************************** +//***** Methods for quadratic elements ****** +//******************************************************************** + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +void SMESHDS_Script::AddEdge(int NewEdgeID, int n1, int n2, int n12) +{ + getCommand(SMESHDS_AddQuadEdge)->AddEdge(NewEdgeID, n1, n2, n12); +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31) +{ + getCommand(SMESHDS_AddQuadTriangle)->AddFace(NewFaceID, n1, n2, n3, + n12, n23, n31); +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41) +{ + getCommand(SMESHDS_AddQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4, + n12, n23, n34, n41); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, + int n14, int n24, int n34) +{ + getCommand(SMESHDS_AddQuadTetrahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n12, n23, n31, + n14, n24, n34); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45) +{ + getCommand(SMESHDS_AddQuadPyramid)->AddVolume(NewVolID, n1, n2, n3, n4, n5, + n12, n23, n34, n41, + n15, n25, n35, n45); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5,int n6, int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36) +{ + getCommand(SMESHDS_AddQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6, + n12, n23, n31, + n45, n56, n64, + n14, n25, n36); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48) +{ + getCommand(SMESHDS_AddQuadHexahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n5, n6, n7, n8, + n12, n23, n34, n41, + n56, n67, n78, n85, + n15, n26, n37, n48); +} + diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 366ac3bdc..95e5335ad 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -59,6 +59,27 @@ class SMESHDS_Script std::vector nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); diff --git a/src/SMESHGUI/Makefile.in b/src/SMESHGUI/Makefile.in index 0dbb8e0a0..fe8f66ecf 100644 --- a/src/SMESHGUI/Makefile.in +++ b/src/SMESHGUI/Makefile.in @@ -109,7 +109,8 @@ LIB_SRC = SMESHGUI.cxx \ SMESHGUI_MeshOp.cxx \ SMESHGUI_Displayer.cxx \ SMESHGUI_Hypotheses.cxx \ - SMESHGUI_ShapeByMeshDlg.cxx + SMESHGUI_ShapeByMeshDlg.cxx \ + SMESHGUI_AddQuadraticElementDlg.cxx LIB_MOC = \ SMESHGUI.h \ @@ -156,8 +157,8 @@ LIB_MOC = \ SMESHGUI_Dialog.h \ SMESHGUI_MeshDlg.h \ SMESHGUI_MeshOp.h \ - SMESHGUI_Hypotheses.h \ - SMESHGUI_ShapeByMeshDlg.h + SMESHGUI_ShapeByMeshDlg.h \ + SMESHGUI_AddQuadraticElementDlg.h LIB_CLIENT_IDL = SALOME_Exception.idl \ diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 91b86ec1f..f4df5d67d 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -40,6 +40,7 @@ #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI_MoveNodesDlg.h" #include "SMESHGUI_AddMeshElementDlg.h" +#include "SMESHGUI_AddQuadraticElementDlg.h" #include "SMESHGUI_EditHypothesesDlg.h" #include "SMESHGUI_CreateHypothesesDlg.h" #include "SMESHGUI_FilterDlg.h" @@ -1866,6 +1867,46 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; } + case 4034: // QUADRATIC EDGE + case 4035: // QUADRATIC TRIANGLE + case 4036: // QUADRATIC QUADRANGLE + case 4037: // QUADRATIC TETRAHEDRON + case 4038: // QUADRATIC PYRAMID + case 4039: // QUADRATIC PENTAHEDRON + case 4040: // QUADRATIC HEXAHEDRON + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + int type; + + switch (theCommandID) { + case 4034: + type = QUAD_EDGE; break; + case 4035: + type = QUAD_TRIANGLE; break; + case 4036: + type = QUAD_QUADRANGLE; break; + case 4037: + type = QUAD_TETRAHEDRON; break; + case 4038: + type = QUAD_PYRAMID; break; + case 4039: + type = QUAD_PENTAHEDRON; break; + case 4040: + type = QUAD_HEXAHEDRON; + break; + default:; + } + new SMESHGUI_AddQuadraticElementDlg( this, type ); + } + else { + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } case 4041: // REMOVES NODES { if(checkLock(aStudy)) break; @@ -2320,6 +2361,13 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 301, "DISPLAY" ); createSMESHAction( 302, "DISPLAY_ONLY" ); createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" ); + createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" ); + createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" ); + createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" ); + createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); + createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); + createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); + createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); // ----- create menu -------------- int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), @@ -2399,6 +2447,14 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4031, addId, -1 ); createMenu( 4032, addId, -1 ); createMenu( 4033, addId, -1 ); + createMenu( separator(), addId, -1 ); + createMenu( 4034, addId, -1 ); + createMenu( 4035, addId, -1 ); + createMenu( 4036, addId, -1 ); + createMenu( 4037, addId, -1 ); + createMenu( 4038, addId, -1 ); + createMenu( 4039, addId, -1 ); + createMenu( 4040, addId, -1 ); createMenu( 4041, removeId, -1 ); createMenu( 4042, removeId, -1 ); @@ -2475,6 +2531,14 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4032, addRemTb ); createTool( 4033, addRemTb ); createTool( separator(), addRemTb ); + createTool( 4034, addRemTb ); + createTool( 4035, addRemTb ); + createTool( 4036, addRemTb ); + createTool( 4037, addRemTb ); + createTool( 4038, addRemTb ); + createTool( 4039, addRemTb ); + createTool( 4040, addRemTb ); + createTool( separator(), addRemTb ); createTool( 4041, addRemTb ); createTool( 4042, addRemTb ); createTool( separator(), addRemTb ); diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx index caf4ffc45..06e6cf1b9 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 74ad155bd..7d1cb9808 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -388,6 +388,35 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() anActor = myActor; if (anActor != 0) { + // skl 07.02.2006 + SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + if( myFilterType == SMESHGUI_TriaFilter || + myFilterType == SMESHGUI_QuadFilter || + myFilterType == SMESHGUI_FaceFilter ) { + SMDS_FaceIteratorPtr it = aMesh->facesIterator(); + while(it->more()) { + const SMDS_MeshFace* f = it->next(); + if(myFilterType == SMESHGUI_FaceFilter) { + myIds.Add(f->GetID()); + } + else if( myFilterType==SMESHGUI_TriaFilter && + ( f->NbNodes()==3 || f->NbNodes()==6 ) ) { + myIds.Add(f->GetID()); + } + else if( myFilterType==SMESHGUI_QuadFilter && + ( f->NbNodes()==4 || f->NbNodes()==8 ) ) { + myIds.Add(f->GetID()); + } + } + } + else if(myFilterType == SMESHGUI_VolumeFilter) { + SMDS_VolumeIteratorPtr it = aMesh->volumesIterator(); + while(it->more()) { + const SMDS_MeshVolume* f = it->next(); + myIds.Add(f->GetID()); + } + } + /* commented by skl 07.02.2006 TVisualObjPtr aVisualObj = anActor->GetObject(); vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid(); if (aGrid != 0) { @@ -411,6 +440,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() } } } + */ } } diff --git a/src/SMESHGUI/SMESH_icons.po b/src/SMESHGUI/SMESH_icons.po index 60dff5a19..463f6f37a 100644 --- a/src/SMESHGUI/SMESH_icons.po +++ b/src/SMESHGUI/SMESH_icons.po @@ -155,7 +155,33 @@ msgstr "mesh_tetra.png" msgid "ICON_DLG_HEXAS" msgstr "mesh_hexa.png" +#Quadratic Edge +msgid "ICON_DLG_QUADRATIC_EDGE" +msgstr "mesh_quad_edge.png" +#Quadratic Triangle +msgid "ICON_DLG_QUADRATIC_TRIANGLE" +msgstr "mesh_quad_triangle.png" + +#Quadratic Quadrangle +msgid "ICON_DLG_QUADRATIC_QUADRANGLE" +msgstr "mesh_quad_quadrangle.png" + +#Quadratic Tetrahedron +msgid "ICON_DLG_QUADRATIC_TETRAHEDRON" +msgstr "mesh_quad_tetrahedron.png" + +#Quadratic Pyramid +msgid "ICON_DLG_QUADRATIC_PYRAMID" +msgstr "mesh_quad_pyramid.png" + +#Quadratic Pentahedron +msgid "ICON_DLG_QUADRATIC_PENTAHEDRON" +msgstr "mesh_quad_pentahedron.png" + +#Quadratic Hexahedron +msgid "ICON_DLG_QUADRATIC_HEXAHEDRON" +msgstr "mesh_quad_hexahedron.png" #----------------------------------------------------------- # ObjectBrowser #----------------------------------------------------------- diff --git a/src/SMESHGUI/SMESH_images.po b/src/SMESHGUI/SMESH_images.po index 2825f19a8..16737d44a 100644 --- a/src/SMESHGUI/SMESH_images.po +++ b/src/SMESHGUI/SMESH_images.po @@ -170,6 +170,35 @@ msgstr "mesh_hexa.png" #Polyhedre msgid "ICON_DLG_POLYHEDRON" msgstr "mesh_polyhedron.png" + +#Quadratic Edge +msgid "ICON_DLG_QUADRATIC_EDGE" +msgstr "mesh_quad_edge.png" + +#Quadratic Triangle +msgid "ICON_DLG_QUADRATIC_TRIANGLE" +msgstr "mesh_quad_triangle.png" + +#Quadratic Quadrangle +msgid "ICON_DLG_QUADRATIC_QUADRANGLE" +msgstr "mesh_quad_quadrangle.png" + +#Quadratic Tetrahedron +msgid "ICON_DLG_QUADRATIC_TETRAHEDRON" +msgstr "mesh_quad_tetrahedron.png" + +#Quadratic Pyramid +msgid "ICON_DLG_QUADRATIC_PYRAMID" +msgstr "mesh_quad_pyramid.png" + +#Quadratic Pentahedron +msgid "ICON_DLG_QUADRATIC_PENTAHEDRON" +msgstr "mesh_quad_pentahedron.png" + +#Quadratic Hexahedron +msgid "ICON_DLG_QUADRATIC_HEXAHEDRON" +msgstr "mesh_quad_hexahedron.png" + #----------------------------------------------------------- # ObjectBrowser #----------------------------------------------------------- diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index 75439de35..c043fc307 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -1814,6 +1814,80 @@ msgstr "Polygon" msgid "SMESH_ADD_POLYGON" msgstr "Add polygon" +msgid "SMESH_ADD_QUADRATIC_EDGE_TITLE" +msgstr "Add Quadratic Edge" + +msgid "SMESH_ADD_QUADRATIC_TRIANGLE_TITLE" +msgstr "Add Quadratic Triangle" + +msgid "SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE" +msgstr "Add Quadratic Quadrangle" + +msgid "SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE" +msgstr "Add Quadratic Tetrahedron" + +msgid "SMESH_ADD_QUADRATIC_PYRAMID_TITLE" +msgstr "Add Quadratic Pyramid" + +msgid "SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE" +msgstr "Add Quadratic Pentahedron" + +msgid "SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE" +msgstr "Add Quadratic Hexahedron" + +msgid "SMESH_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "SMESH_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "SMESH_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "SMESH_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "SMESH_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "SMESH_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "SMESH_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_CORNER_NODES" +msgstr "Corner Nodes:" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_EDGE" +msgstr "Add Quadratic Edge" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TRIANGLE" +msgstr "Add Quadratic Triangle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_QUADRANGLE" +msgstr "Add Quadratic Quadrangle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TETRAHEDRON" +msgstr "Add Quadratic Tetrahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PYRAMID" +msgstr "Add Quadratic PYRAMID" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PENTAHEDRON" +msgstr "Add Quadratic Pentahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_HEXAHEDRON" +msgstr "Add Quadratic Hexahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_FIRST" +msgstr "First" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_MIDDLE" +msgstr "Middle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_LAST" +msgstr "Last" #---------------------------------------------------- msgid "SMESHGUI_CreatePatternDlg::CAPTION" @@ -2028,6 +2102,27 @@ msgstr "Polygon" msgid "MEN_POLYHEDRON" msgstr "Polyhedron" +msgid "MEN_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "MEN_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "MEN_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "MEN_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "MEN_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "MEN_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "MEN_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "MEN_NODES" msgstr "Nodes" @@ -2357,6 +2452,27 @@ msgstr "Polygon" msgid "TOP_POLYHEDRON" msgstr "Polyhedron" +msgid "TOP_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "TOP_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "TOP_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "TOP_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "TOP_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "TOP_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "TOP_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "TOP_NODES" msgstr "Nodes" @@ -2637,6 +2753,27 @@ msgstr "Polygon" msgid "STB_POLYHEDRON" msgstr "Polyhedron" +msgid "STB_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "STB_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "STB_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "STB_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "STB_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "STB_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "STB_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "STB_NODES" msgstr "Nodes" diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 6d8150db8..5adfa1c73 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1,3 +1,31 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_2D_Algo_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + // File : SMESH_2smeshpy.cxx // Created : Fri Nov 18 13:20:10 2005 // Author : Edward AGAPOV (eap) @@ -407,6 +435,13 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd): _pyObject(theCreation */ //================================================================================ +//================================================================================ +/*! + * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh + * \param theCommand - Engine method called for this mesh + */ +//================================================================================ + void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) { // smesh.py wraps the following methods: @@ -663,6 +698,11 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->myCreationMethod = "Propagation"; hyp->myType = "Regular_1D"; } + else if ( hypType == "QuadraticMesh" ) { + hyp->myDim = 1; + hyp->myCreationMethod = "QuadraticMesh"; + hyp->myType = "Regular_1D"; + } else if ( hypType == "AutomaticLength" ) { hyp->myDim = 1; hyp->myCreationMethod = "AutomaticLength"; diff --git a/src/SMESH_I/SMESH_Hypothesis_i.cxx b/src/SMESH_I/SMESH_Hypothesis_i.cxx index d5cdce9fb..768c37ad8 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.cxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.cxx @@ -89,7 +89,7 @@ SMESH_Hypothesis_i::~SMESH_Hypothesis_i() char* SMESH_Hypothesis_i::GetName() { - MESSAGE( "SMESH_Hypothesis_i::GetName" ); + //MESSAGE( "SMESH_Hypothesis_i::GetName" ); return CORBA::string_dup( myBaseImpl->GetName() ); }; diff --git a/src/SMESH_I/SMESH_MEDMesh_i.cxx b/src/SMESH_I/SMESH_MEDMesh_i.cxx index 3f1c017d4..bbf959006 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.cxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.cxx @@ -1121,7 +1121,7 @@ void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception) if (_creeFamily == false) { _creeFamily = true; - SMESH_subMesh_i *subMeshServant; + //SMESH_subMesh_i *subMeshServant; map < int, SMESH_subMesh_i * >::iterator it; for (it = _mesh_i->_mapSubMesh_i.begin(); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 9aa35ea1e..d85258440 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -128,6 +128,17 @@ CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) TPythonDump() << "isDone = " << this << ".AddEdge([ " << index1 << ", " << index2 <<" ])"; } + if (NbNodes == 3) { + CORBA::Long n1 = IDsOfNodes[0]; + CORBA::Long n2 = IDsOfNodes[1]; + CORBA::Long n12 = IDsOfNodes[2]; + GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1), + GetMeshDS()->FindNode(n2), + GetMeshDS()->FindNode(n12)); + // Update Python script + TPythonDump() << "isDone = " << this << ".AddEdge([ " + <AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); } - else + else if (NbNodes == 6) { - GetMeshDS()->AddPolygonalFace(nodes); + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); + } + else if (NbNodes == 8) + { + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); } // Update Python script @@ -189,6 +206,30 @@ CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) return true; }; +//============================================================================= +/*! + * AddPolygonalFace + */ +//============================================================================= +CORBA::Boolean SMESH_MeshEditor_i::AddPolygonalFace + (const SMESH::long_array & IDsOfNodes) +{ + int NbNodes = IDsOfNodes.length(); + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + + GetMeshDS()->AddPolygonalFace(nodes); + + // Update Python script + TPythonDump() <<"isDone = "<FindNode(IDsOfNodes[i]); + SMDS_MeshElement* elem = 0; switch(NbNodes) { - case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break; - case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break; - case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break; - case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break; + case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break; + case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break; + case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break; + case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break; + case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5], + n[6],n[7],n[8],n[9]); + break; + case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6], + n[7],n[8],n[9],n[10],n[11],n[12]); + break; + case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8], + n[9],n[10],n[11],n[12],n[13],n[14]); + break; + case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17],n[18],n[19]); + break; } // Update Python script TPythonDump() << "isDone = " << this << ".AddVolume( " << IDsOfNodes << " )"; @@ -215,7 +270,7 @@ CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNode TPythonDump() << "print 'AddVolume: ', isDone"; #endif - return true; + return elem; }; //============================================================================= diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index aa28198c1..0632747a6 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -50,6 +50,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z); CORBA::Boolean AddEdge(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddFace(const SMESH::long_array & IDsOfNodes); + CORBA::Boolean AddPolygonalFace(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddVolume(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes, diff --git a/src/SMESH_SWIG/smesh.py b/src/SMESH_SWIG/smesh.py index 4242344af..ec24cadfa 100644 --- a/src/SMESH_SWIG/smesh.py +++ b/src/SMESH_SWIG/smesh.py @@ -250,6 +250,18 @@ class Mesh_Segment(Mesh_Algorithm): hyp.SetFineness( fineness ) return hyp + def QuadraticMesh(self): + """ + Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges. + If the 2D mesher sees that all boundary edges are quadratic ones, + it generates quadratic faces, else it generates linear faces using + medium nodes as if they were vertex ones. + The 3D mesher generates quadratic volumes only if all boundary faces + are quadratic ones, else it fails. + """ + hyp = self.Hypothesis("QuadraticMesh") + return hyp + # Public class: Mesh_Segment_Python # --------------------------------- diff --git a/src/StdMeshers/Makefile.in b/src/StdMeshers/Makefile.in index 592ff2b2b..d21007816 100644 --- a/src/StdMeshers/Makefile.in +++ b/src/StdMeshers/Makefile.in @@ -50,7 +50,9 @@ EXPORT_HEADERS = \ StdMeshers_Hexa_3D.hxx \ StdMeshers_AutomaticLength.hxx \ StdMeshers_Distribution.hxx \ - StdMeshers_QuadranglePreference.hxx + StdMeshers_QuadranglePreference.hxx \ + StdMeshers_Helper.hxx \ + StdMeshers_QuadraticMesh.hxx EXPORT_PYSCRIPTS = @@ -76,7 +78,9 @@ LIB_SRC = \ StdMeshers_Hexa_3D.cxx \ StdMeshers_AutomaticLength.cxx \ StdMeshers_Distribution.cxx \ - StdMeshers_QuadranglePreference.cxx + StdMeshers_QuadranglePreference.cxx \ + StdMeshers_Helper.cxx \ + StdMeshers_QuadraticMesh.cxx LIB_SERVER_IDL = diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index a3ed4f11a..a5ed09820 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -45,6 +45,7 @@ using namespace std; #include #include #include +#include #include #include @@ -70,15 +71,14 @@ static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aSha //============================================================================= StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, - SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) + SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); - _name = "Hexa_3D"; -// _shapeType = TopAbs_SOLID; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type -// MESSAGE("_shapeType octal " << oct << _shapeType); - for (int i = 0; i < 6; i++) - _quads[i] = 0; + MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); + _name = "Hexa_3D"; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type + for (int i = 0; i < 6; i++) + _quads[i] = 0; + myTool = 0; } //============================================================================= @@ -89,11 +89,29 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() { - MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); - for (int i = 0; i < 6; i++) - StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]); + MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); + ClearAndReturn(true); } +//================================================================================ +/*! + * \brief Clear fields and return the argument + * \param res - the value to return + * \retval bool - the argument value + */ +//================================================================================ + +bool StdMeshers_Hexa_3D::ClearAndReturn(const bool res) +{ + for (int i = 0; i < 6; i++) + StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]); + if ( myTool ) + delete myTool; + myTool = 0; + return res; +} + + //============================================================================= /*! * @@ -146,6 +164,7 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& return true; } + //============================================================================= /*! * Hexahedron mesh on hexaedron like form @@ -163,534 +182,507 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - MESSAGE("StdMeshers_Hexa_3D::Compute"); - //bool isOk = false; - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS(); - - // 0. - shape and face mesh verification - // 0.1 - shape must be a solid (or a shell) with 6 faces - //MESSAGE("---"); - - vector < SMESH_subMesh * >meshFaces; - for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) - { - SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT(aSubMesh); - meshFaces.push_back(aSubMesh); - } - if (meshFaces.size() != 6) - { - SCRUTE(meshFaces.size()); -// ASSERT(0); - return false; - } - - // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) - //MESSAGE("---"); - - for (int i = 0; i < 6; i++) - { - TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); - SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); - string algoName = algo->GetName(); - bool isAllQuad = false; - if (algoName == "Quadrangle_2D") { - SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); - if ( sm ) { - isAllQuad = true; - SMDS_ElemIteratorPtr eIt = sm->GetElements(); - while ( isAllQuad && eIt->more() ) - isAllQuad = ( eIt->next()->NbNodes() == 4 ); - } - } - if ( ! isAllQuad ) { - //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f - bool bIsOk; - // - bIsOk=ComputePentahedralMesh(aMesh, aShape); - if (bIsOk) { - return true; - } - //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t - SCRUTE(algoName); - // ASSERT(0); - return false; - } - StdMeshers_Quadrangle_2D *quadAlgo = - dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); - ASSERT(quadAlgo); - try - { - _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace); - // *** to delete after usage - } - catch(SALOME_Exception & S_ex) - { - // *** delete _quads - // *** throw exception - // ASSERT(0); - return false; - } - - // 0.2.1 - number of points on the opposite edges must be the same - if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || - _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) - { - MESSAGE("different number of points on the opposite edges of face " << i); - // ASSERT(0); - return false; - } - } - - // 1. - identify faces and vertices of the "cube" - // 1.1 - ancestor maps vertex->edges in the cube - //MESSAGE("---"); - - TopTools_IndexedDataMapOfShapeListOfShape MS; - TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); - - // 1.2 - first face is choosen as face Y=0 of the unit cube - //MESSAGE("---"); - - const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); - const TopoDS_Face & F = TopoDS::Face(aFace); - - // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 - //MESSAGE("---"); - - int i = 0; - TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube - double f, l; - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopoDS_Vertex VFirst, VLast; - TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l - bool isForward = - (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - - if (isForward) - { - _cube.V000 = VFirst; // will be (0,0,0) on the unit cube - _cube.V100 = VLast; // will be (1,0,0) on the unit cube - } - else - { - _cube.V000 = VLast; - _cube.V100 = VFirst; - } - - i = 1; - E = _quads[0]->edge[i]; - C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopExp::Vertices(E, VFirst, VLast); - isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - if (isForward) - _cube.V101 = VLast; // will be (1,0,1) on the unit cube - else - _cube.V101 = VFirst; - - i = 2; - E = _quads[0]->edge[i]; - C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopExp::Vertices(E, VFirst, VLast); - isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - if (isForward) - _cube.V001 = VLast; // will be (0,0,1) on the unit cube - else - _cube.V001 = VFirst; + MESSAGE("StdMeshers_Hexa_3D::Compute"); + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + + // 0. - shape and face mesh verification + // 0.1 - shape must be a solid (or a shell) with 6 faces + //MESSAGE("---"); + + vector < SMESH_subMesh * >meshFaces; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT(aSubMesh); + meshFaces.push_back(aSubMesh); + } + if (meshFaces.size() != 6) { + SCRUTE(meshFaces.size()); + return false; + } - // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) - // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) - // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) - // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) - //MESSAGE("---"); + // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) + //MESSAGE("---"); + + myTool = new StdMeshers_Helper(aMesh); + _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + + for (int i = 0; i < 6; i++) { + TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); + string algoName = algo->GetName(); + bool isAllQuad = false; + if (algoName == "Quadrangle_2D") { + SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); + if ( sm ) { + isAllQuad = true; + SMDS_ElemIteratorPtr eIt = sm->GetElements(); + while ( isAllQuad && eIt->more() ) { + const SMDS_MeshElement* elem = eIt->next(); + isAllQuad = ( elem->NbNodes()==4 ||(_quadraticMesh && elem->NbNodes()==8) ); + } + } + } + if ( ! isAllQuad ) { + //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f + bool bIsOk = ComputePentahedralMesh(aMesh, aShape); + return ClearAndReturn( bIsOk ); + } + StdMeshers_Quadrangle_2D *quadAlgo = + dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); + ASSERT(quadAlgo); + try { + _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh); + } + catch(SALOME_Exception & S_ex) { + return ClearAndReturn( false ); + } - TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS); - ASSERT(!E_0Y0.IsNull()); + // 0.2.1 - number of points on the opposite edges must be the same + if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || + _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) { + MESSAGE("different number of points on the opposite edges of face " << i); + // ASSERT(0); + return ClearAndReturn( false ); + } + } - TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS); - ASSERT(!E_1Y0.IsNull()); + // 1. - identify faces and vertices of the "cube" + // 1.1 - ancestor maps vertex->edges in the cube + //MESSAGE("---"); - TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS); - ASSERT(!E_1Y1.IsNull()); + TopTools_IndexedDataMapOfShapeListOfShape MS; + TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); - TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS); - ASSERT(!E_0Y1.IsNull()); + // 1.2 - first face is choosen as face Y=0 of the unit cube + //MESSAGE("---"); - // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 - //MESSAGE("---"); + const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); + const TopoDS_Face & F = TopoDS::Face(aFace); - TopExp::Vertices(E_0Y0, VFirst, VLast); - if (VFirst.IsSame(_cube.V000)) - _cube.V010 = VLast; - else - _cube.V010 = VFirst; + // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 + //MESSAGE("---"); - TopExp::Vertices(E_1Y0, VFirst, VLast); - if (VFirst.IsSame(_cube.V100)) - _cube.V110 = VLast; - else - _cube.V110 = VFirst; + int i = 0; + TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - TopExp::Vertices(E_1Y1, VFirst, VLast); - if (VFirst.IsSame(_cube.V101)) - _cube.V111 = VLast; - else - _cube.V111 = VFirst; + if (isForward) { + _cube.V000 = VFirst; // will be (0,0,0) on the unit cube + _cube.V100 = VLast; // will be (1,0,0) on the unit cube + } + else { + _cube.V000 = VLast; + _cube.V100 = VFirst; + } - TopExp::Vertices(E_0Y1, VFirst, VLast); - if (VFirst.IsSame(_cube.V001)) - _cube.V011 = VLast; - else - _cube.V011 = VFirst; - - // 1.6 - find remaining faces given 4 vertices - //MESSAGE("---"); - - _indY0 = 0; - _cube.quad_Y0 = _quads[_indY0]; - - _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V010, _cube.V011, _cube.V110, _cube.V111); - _cube.quad_Y1 = _quads[_indY1]; - - _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V000, _cube.V010, _cube.V100, _cube.V110); - _cube.quad_Z0 = _quads[_indZ0]; - - _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V001, _cube.V011, _cube.V101, _cube.V111); - _cube.quad_Z1 = _quads[_indZ1]; - - _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V000, _cube.V001, _cube.V010, _cube.V011); - _cube.quad_X0 = _quads[_indX0]; - - _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V100, _cube.V101, _cube.V110, _cube.V111); - _cube.quad_X1 = _quads[_indX1]; - - //MESSAGE("---"); - - // 1.7 - get convertion coefs from face 2D normalized to 3D normalized - - Conv2DStruct cx0; // for face X=0 - Conv2DStruct cx1; // for face X=1 - Conv2DStruct cy0; - Conv2DStruct cy1; - Conv2DStruct cz0; - Conv2DStruct cz1; - - GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(), - _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0); - GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(), - _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1); - GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(), - _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0); - GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(), - _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1); - GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), - _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0); - GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), - _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1); - - // 1.8 - create a 3D structure for normalized values - - //MESSAGE("---"); - int nbx = _cube.quad_Z0->nbPts[0]; - if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1]; + i = 1; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V101 = VLast; // will be (1,0,1) on the unit cube + else + _cube.V101 = VFirst; + + i = 2; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V001 = VLast; // will be (0,0,1) on the unit cube + else + _cube.V001 = VFirst; + + // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) + // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) + // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) + // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) + //MESSAGE("---"); + + TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS); + ASSERT(!E_0Y0.IsNull()); + + TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS); + ASSERT(!E_1Y0.IsNull()); + + TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS); + ASSERT(!E_1Y1.IsNull()); + + TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS); + ASSERT(!E_0Y1.IsNull()); + + // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 + //MESSAGE("---"); + + TopExp::Vertices(E_0Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V000)) + _cube.V010 = VLast; + else + _cube.V010 = VFirst; + + TopExp::Vertices(E_1Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V100)) + _cube.V110 = VLast; + else + _cube.V110 = VFirst; + + TopExp::Vertices(E_1Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V101)) + _cube.V111 = VLast; + else + _cube.V111 = VFirst; + + TopExp::Vertices(E_0Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V001)) + _cube.V011 = VLast; + else + _cube.V011 = VFirst; + + // 1.6 - find remaining faces given 4 vertices + //MESSAGE("---"); + + _indY0 = 0; + _cube.quad_Y0 = _quads[_indY0]; + + _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V010, _cube.V011, _cube.V110, _cube.V111); + _cube.quad_Y1 = _quads[_indY1]; + + _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V010, _cube.V100, _cube.V110); + _cube.quad_Z0 = _quads[_indZ0]; + + _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V001, _cube.V011, _cube.V101, _cube.V111); + _cube.quad_Z1 = _quads[_indZ1]; + + _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V001, _cube.V010, _cube.V011); + _cube.quad_X0 = _quads[_indX0]; + + _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V100, _cube.V101, _cube.V110, _cube.V111); + _cube.quad_X1 = _quads[_indX1]; + + //MESSAGE("---"); + + // 1.7 - get convertion coefs from face 2D normalized to 3D normalized + + Conv2DStruct cx0; // for face X=0 + Conv2DStruct cx1; // for face X=1 + Conv2DStruct cy0; + Conv2DStruct cy1; + Conv2DStruct cz0; + Conv2DStruct cz1; + + GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(), + _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0); + GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(), + _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1); + GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0); + GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(), + _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1); + GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0); + GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), + _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1); + + // 1.8 - create a 3D structure for normalized values + + //MESSAGE("---"); + int nbx = _cube.quad_Z0->nbPts[0]; + if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1]; - int nby = _cube.quad_X0->nbPts[0]; - if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1]; + int nby = _cube.quad_X0->nbPts[0]; + if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1]; - int nbz = _cube.quad_Y0->nbPts[0]; - if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1]; + int nbz = _cube.quad_Y0->nbPts[0]; + if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1]; - int i1, j1, nbxyz = nbx * nby * nbz; - Point3DStruct *np = new Point3DStruct[nbxyz]; + int i1, j1, nbxyz = nbx * nby * nbz; + Point3DStruct *np = new Point3DStruct[nbxyz]; - // 1.9 - store node indexes of faces + // 1.9 - store node indexes of faces - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); - - faceQuadStruct *quad = _cube.quad_X0; - int i = 0; // j = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); + faceQuadStruct *quad = _cube.quad_X0; + int i = 0; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } - - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face - int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face + int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_X1; - int i = nbx - 1; // j = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = _cube.quad_X1; + int i = nbx - 1; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face - int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face + int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Y0; - int j = 0; // i = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = _cube.quad_Y0; + int j = 0; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face - int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face + int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Y1; - int j = nby - 1; // i = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = _cube.quad_Y1; + int j = nby - 1; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face - int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face + int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Z0; - int k = 0; // i = x/face , j = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = _cube.quad_Z0; + int k = 0; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face - int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } - - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - faceQuadStruct *quad = _cube.quad_Z1; - int k = nbz - 1; // i = x/face , j = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face + int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Z1; + int k = nbz - 1; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(myTool->IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face - int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face + int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - // 2.0 - for each node of the cube: - // - get the 8 points 3D = 8 vertices of the cube - // - get the 12 points 3D on the 12 edges of the cube - // - get the 6 points 3D on the 6 faces with their ID - // - compute the point 3D - // - store the point 3D in SMESHDS, store its ID in 3D structure - - int shapeID = meshDS->ShapeToIndex( aShape ); - - Pt3 p000, p001, p010, p011, p100, p101, p110, p111; - Pt3 px00, px01, px10, px11; - Pt3 p0y0, p0y1, p1y0, p1y1; - Pt3 p00z, p01z, p10z, p11z; - Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; - - GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - for (int i = 1; i < nbx - 1; i++) - { - for (int j = 1; j < nby - 1; j++) - { - for (int k = 1; k < nbz - 1; k++) - { - // *** seulement maillage regulier - // 12 points on edges - GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); - - // 12 points on faces - GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); - GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); - - int ijk = k * nbx * nby + j * nbx + i; - double x = double (i) / double (nbx - 1); // *** seulement - double y = double (j) / double (nby - 1); // *** maillage - double z = double (k) / double (nbz - 1); // *** regulier - - Pt3 X; - for (int i = 0; i < 3; i++) - { - X[i] = - (1 - x) * p0yz[i] + x * p1yz[i] - + (1 - y) * px0z[i] + y * px1z[i] - + (1 - z) * pxy0[i] + z * pxy1[i] - - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) - - x * ((1 - y) * p10z[i] + y * p11z[i]) - - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) - - y * ((1 - z) * px10[i] + z * px11[i]) - - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) - - z * ((1 - x) * p0y1[i] + x * p1y1[i]) - + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) - + y * ((1 - z) * p010[i] + z * p011[i])) - + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) - + y * ((1 - z) * p110[i] + z * p111[i])); - } - - SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); - np[ijk].node = node; - meshDS->SetNodeInVolume(node, shapeID); - } - } - } + // 2.0 - for each node of the cube: + // - get the 8 points 3D = 8 vertices of the cube + // - get the 12 points 3D on the 12 edges of the cube + // - get the 6 points 3D on the 6 faces with their ID + // - compute the point 3D + // - store the point 3D in SMESHDS, store its ID in 3D structure + + int shapeID = meshDS->ShapeToIndex( aShape ); + + Pt3 p000, p001, p010, p011, p100, p101, p110, p111; + Pt3 px00, px01, px10, px11; + Pt3 p0y0, p0y1, p1y0, p1y1; + Pt3 p00z, p01z, p10z, p11z; + Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; + + GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + for (int i = 1; i < nbx - 1; i++) { + for (int j = 1; j < nby - 1; j++) { + for (int k = 1; k < nbz - 1; k++) { + // *** seulement maillage regulier + // 12 points on edges + GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); + + // 12 points on faces + GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); + GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); + + int ijk = k * nbx * nby + j * nbx + i; + double x = double (i) / double (nbx - 1); // *** seulement + double y = double (j) / double (nby - 1); // *** maillage + double z = double (k) / double (nbz - 1); // *** regulier + + Pt3 X; + for (int i = 0; i < 3; i++) { + X[i] = (1 - x) * p0yz[i] + x * p1yz[i] + + (1 - y) * px0z[i] + y * px1z[i] + + (1 - z) * pxy0[i] + z * pxy1[i] + - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) + - x * ((1 - y) * p10z[i] + y * p11z[i]) + - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) + - y * ((1 - z) * px10[i] + z * px11[i]) + - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) + - z * ((1 - x) * p0y1[i] + x * p1y1[i]) + + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) + + y * ((1 - z) * p010[i] + z * p011[i])) + + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) + + y * ((1 - z) * p110[i] + z * p111[i])); + } + + SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); + np[ijk].node = node; + meshDS->SetNodeInVolume(node, shapeID); + } + } + } // find orientation of furute volumes according to MED convention vector< bool > forward( nbx * nby ); SMDS_VolumeTool vTool; - for (int i = 0; i < nbx - 1; i++) - for (int j = 0; j < nby - 1; j++) - { + for (int i = 0; i < nbx - 1; i++) { + for (int j = 0; j < nby - 1; j++) { int n1 = j * nbx + i; int n2 = j * nbx + i + 1; int n3 = (j + 1) * nbx + i + 1; @@ -705,51 +697,53 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, vTool.Set( &tmpVol ); forward[ n1 ] = vTool.IsForward(); } + } - //2.1 - for each node of the cube (less 3 *1 Faces): - // - store hexahedron in SMESHDS - MESSAGE("Storing hexahedron into the DS"); - for (int i = 0; i < nbx - 1; i++) - for (int j = 0; j < nby - 1; j++) - { - bool isForw = forward.at( j * nbx + i ); - for (int k = 0; k < nbz - 1; k++) - { - int n1 = k * nbx * nby + j * nbx + i; - int n2 = k * nbx * nby + j * nbx + i + 1; - int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; - int n4 = k * nbx * nby + (j + 1) * nbx + i; - int n5 = (k + 1) * nbx * nby + j * nbx + i; - int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; - int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; - int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; - - SMDS_MeshVolume * elt; - if ( isForw ) - elt = meshDS->AddVolume(np[n1].node, - np[n2].node, - np[n3].node, - np[n4].node, - np[n5].node, - np[n6].node, - np[n7].node, - np[n8].node); - else - elt = meshDS->AddVolume(np[n1].node, - np[n4].node, - np[n3].node, - np[n2].node, - np[n5].node, - np[n8].node, - np[n7].node, - np[n6].node); - - meshDS->SetMeshElementOnShape(elt, shapeID); - } - } + //2.1 - for each node of the cube (less 3 *1 Faces): + // - store hexahedron in SMESHDS + MESSAGE("Storing hexahedron into the DS"); + for (int i = 0; i < nbx - 1; i++) { + for (int j = 0; j < nby - 1; j++) { + bool isForw = forward.at( j * nbx + i ); + for (int k = 0; k < nbz - 1; k++) { + int n1 = k * nbx * nby + j * nbx + i; + int n2 = k * nbx * nby + j * nbx + i + 1; + int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; + int n4 = k * nbx * nby + (j + 1) * nbx + i; + int n5 = (k + 1) * nbx * nby + j * nbx + i; + int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; + int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; + int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; + + SMDS_MeshVolume * elt; + if ( isForw ) { + //elt = meshDS->AddVolume(np[n1].node, np[n2].node, + // np[n3].node, np[n4].node, + // np[n5].node, np[n6].node, + // np[n7].node, np[n8].node); + elt = myTool->AddVolume(np[n1].node, np[n2].node, + np[n3].node, np[n4].node, + np[n5].node, np[n6].node, + np[n7].node, np[n8].node); + } + else { + //elt = meshDS->AddVolume(np[n1].node, np[n4].node, + // np[n3].node, np[n2].node, + // np[n5].node, np[n8].node, + // np[n7].node, np[n6].node); + elt = myTool->AddVolume(np[n1].node, np[n4].node, + np[n3].node, np[n2].node, + np[n5].node, np[n8].node, + np[n7].node, np[n6].node); + } + + meshDS->SetMeshElementOnShape(elt, shapeID); + } + } + } if ( np ) delete [] np; - //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); - return true; + //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); + return ClearAndReturn( true ); } //============================================================================= @@ -1066,3 +1060,4 @@ bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) return bOK; } + diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index a9e20459c..273de6369 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -35,6 +35,8 @@ #include "StdMeshers_Quadrangle_2D.hxx" #include "Utils_SALOME_Exception.hxx" +#include "StdMeshers_Helper.hxx" + typedef struct point3Dstruct { const SMDS_MeshNode * node; @@ -127,6 +129,8 @@ protected: Point3DStruct *np, const SMESHDS_Mesh* meshDS); + bool ClearAndReturn(const bool res); + CubeStruct _cube; FaceQuadStruct* _quads[6]; int _indX0; @@ -135,6 +139,9 @@ protected: int _indY1; int _indZ0; int _indZ1; + + bool myCreateQuadratic; + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 4852ce4fe..8102e0a03 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -62,9 +62,6 @@ using namespace std; #include #include -#include -//#include - //============================================================================= /*! * @@ -72,19 +69,19 @@ using namespace std; //============================================================================= StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, - SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) + SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); - _name = "MEFISTO_2D"; -// _shapeType = TopAbs_FACE; - _shapeType = (1 << TopAbs_FACE); - _compatibleHypothesis.push_back("MaxElementArea"); - _compatibleHypothesis.push_back("LengthFromEdges"); - - _edgeLength = 0; - _maxElementArea = 0; - _hypMaxElementArea = NULL; - _hypLengthFromEdges = NULL; + MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); + _name = "MEFISTO_2D"; + _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("MaxElementArea"); + _compatibleHypothesis.push_back("LengthFromEdges"); + + _edgeLength = 0; + _maxElementArea = 0; + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; + myTool = 0; } //============================================================================= @@ -95,7 +92,7 @@ StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() { - MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); + MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); } //============================================================================= @@ -184,112 +181,121 @@ bool StdMeshers_MEFISTO_2D::CheckHypothesis bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) { - MESSAGE("StdMeshers_MEFISTO_2D::Compute"); + MESSAGE("StdMeshers_MEFISTO_2D::Compute"); - if (_hypLengthFromEdges) - _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + if (_hypLengthFromEdges) + _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + + bool isOk = false; + //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - bool isOk = false; - //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - - const TopoDS_Face & FF = TopoDS::Face(aShape); - bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); - TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); - - Z nblf; //nombre de lignes fermees (enveloppe en tete) - Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee - R2 *uvslf = NULL; - Z nbpti = 0; //nombre points internes futurs sommets de la triangulation - R2 *uvpti = NULL; - - Z nbst; - R2 *uvst = NULL; - Z nbt; - Z *nust = NULL; - Z ierr = 0; - - Z nutysu = 1; // 1: il existe un fonction areteideale_() - // Z nutysu=0; // 0: on utilise aretmx - R aretmx = _edgeLength; // longueur max aretes future triangulation - - nblf = NumberOfWires(F); - - nudslf = new Z[1 + nblf]; - nudslf[0] = 0; - int iw = 1; - int nbpnt = 0; - - myOuterWire = BRepTools::OuterWire(F); - nbpnt += NumberOfPoints(aMesh, myOuterWire); - if ( nbpnt < 3 ) // ex: a circle with 2 segments - return false; - nudslf[iw++] = nbpnt; - - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - if (!myOuterWire.IsSame(W)) - { - nbpnt += NumberOfPoints(aMesh, W); - nudslf[iw++] = nbpnt; - } - } + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + Z nblf; //nombre de lignes fermees (enveloppe en tete) + Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee + R2 *uvslf = NULL; + Z nbpti = 0; //nombre points internes futurs sommets de la triangulation + R2 *uvpti = NULL; + + Z nbst; + R2 *uvst = NULL; + Z nbt; + Z *nust = NULL; + Z ierr = 0; + + Z nutysu = 1; // 1: il existe un fonction areteideale_() + // Z nutysu=0; // 0: on utilise aretmx + R aretmx = _edgeLength; // longueur max aretes future triangulation + + nblf = NumberOfWires(F); + + nudslf = new Z[1 + nblf]; + nudslf[0] = 0; + int iw = 1; + int nbpnt = 0; + + myTool = new StdMeshers_Helper(aMesh); + _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + + myOuterWire = BRepTools::OuterWire(F); + nbpnt += NumberOfPoints(aMesh, myOuterWire); + if ( nbpnt < 3 ) { // ex: a circle with 2 segments + delete myTool; myTool = 0; + return false; + } + nudslf[iw++] = nbpnt; - // avoid passing same uv points for a vertex common to 2 wires - TopTools_IndexedDataMapOfShapeListOfShape VWMap; - if ( iw - 1 > 1 ) // nbofWires > 1 - TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap ); + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) { + nbpnt += NumberOfPoints(aMesh, W); + nudslf[iw++] = nbpnt; + } + } - uvslf = new R2[nudslf[nblf]]; - int m = 0; + // avoid passing same uv points for a vertex common to 2 wires + TopTools_IndexedDataMapOfShapeListOfShape VWMap; + if ( iw - 1 > 1 ) // nbofWires > 1 + TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap ); - double scalex, scaley; - ComputeScaleOnFace(aMesh, F, scalex, scaley); + uvslf = new R2[nudslf[nblf]]; + int m = 0; - map mefistoToDS; // correspondence mefisto index--> points IDNodes - if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m, - mefistoToDS, scalex, scaley, VWMap)) - return false; + double scalex, scaley; + ComputeScaleOnFace(aMesh, F, scalex, scaley); - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - if (!myOuterWire.IsSame(W)) - { - if (! LoadPoints(aMesh, F, W, uvslf, m, - mefistoToDS, scalex, scaley, VWMap )) - return false; - } - } + map mefistoToDS; // correspondence mefisto index--> points IDNodes + if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m, + mefistoToDS, scalex, scaley, VWMap) ) { + delete myTool; myTool = 0; + return false; + } - uvst = NULL; - nust = NULL; - aptrte(nutysu, aretmx, - nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr); - - if (ierr == 0) - { - MESSAGE("... End Triangulation Generated Triangle Number " << nbt); - MESSAGE(" Node Number " << nbst); - StoreResult(aMesh, nbst, uvst, nbt, nust, F, - faceIsForward, mefistoToDS, scalex, scaley); - isOk = true; - } - else - { - MESSAGE("Error in Triangulation"); - isOk = false; - } - if (nudslf != NULL) - delete[]nudslf; - if (uvslf != NULL) - delete[]uvslf; - if (uvst != NULL) - delete[]uvst; - if (nust != NULL) - delete[]nust; - return isOk; + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) + { + if (! LoadPoints(aMesh, F, W, uvslf, m, + mefistoToDS, scalex, scaley, VWMap )) { + delete myTool; myTool = 0; + return false; + } + } + } + + uvst = NULL; + nust = NULL; + aptrte(nutysu, aretmx, + nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr); + + if (ierr == 0) + { + MESSAGE("... End Triangulation Generated Triangle Number " << nbt); + MESSAGE(" Node Number " << nbst); + StoreResult(aMesh, nbst, uvst, nbt, nust, F, + faceIsForward, mefistoToDS, scalex, scaley); + isOk = true; + } + else + { + MESSAGE("Error in Triangulation"); + isOk = false; + } + if (nudslf != NULL) + delete[]nudslf; + if (uvslf != NULL) + delete[]uvslf; + if (uvst != NULL) + delete[]uvst; + if (nust != NULL) + delete[]nust; + delete myTool; myTool = 0; + + return isOk; } //======================================================================= @@ -354,7 +360,8 @@ static bool fixCommonVertexUV (gp_Pnt2d & theUV, const TopoDS_Wire& theOW, const TopoDS_Face& theF, const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap, - SMESH_Mesh & theMesh) + SMESH_Mesh & theMesh, + bool CreateQuadratic) { if( theW.IsSame( theOW ) || !theVWMap.Contains( theV )) return false; @@ -417,10 +424,12 @@ static bool fixCommonVertexUV (gp_Pnt2d & theUV, umin = l; umax = f; } - else - { + else { while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); + // check if node is medium + if ( CreateQuadratic && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = static_cast(node->GetPosition().get()); double u = epos->GetUParameter(); @@ -515,9 +524,13 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, while ( nodeIt->more() ) { node = nodeIt->next(); + if ( _quadraticMesh && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = static_cast(node->GetPosition().get()); - params[ epos->GetUParameter() ] = node; + double param = epos->GetUParameter(); + if ( !isForward ) param = -param; + params.insert( make_pair( param, node )); } int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); if ( nbPoints != params.size()) @@ -535,7 +548,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, // vertex node gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale ); - if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh )) + if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh )) myNodesOnCommonV.push_back( idFirst ); mOnVertex.push_back( m ); uvslf[m].x = p.X(); @@ -547,22 +560,13 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, // internal nodes map::iterator u_n = params.begin(); - map::reverse_iterator u_n_rev = params.rbegin(); - for ( int i = 0; i < nbPoints; ++i ) + for ( int i = 0; u_n != params.end(); ++u_n, ++i ) { - if ( isForward ) { - u = u_n->first; - node = u_n->second; - ++u_n; - } else { - u = u_n_rev->first; - node = u_n_rev->second; - ++u_n_rev; - } + u = isForward ? u_n->first : - u_n->first; gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale ); uvslf[m].x = p.X(); uvslf[m].y = p.Y(); - mefistoToDS[m + 1] = node; + mefistoToDS[m + 1] = u_n->second; //MESSAGE(" "<AddFace(n1, n2, n3); + //elt = meshDS->AddFace(n1, n2, n3); + elt = myTool->AddFace(n1, n2, n3); else - elt = meshDS->AddFace(n1, n3, n2); + //elt = meshDS->AddFace(n1, n3, n2); + elt = myTool->AddFace(n1, n3, n2); meshDS->SetMeshElementOnShape(elt, faceID); m++; } - // remove bad elements build on vertices shared by wires + // remove bad elements built on vertices shared by wires list::iterator itN = myNodesOnCommonV.begin(); for ( ; itN != myNodesOnCommonV.end(); itN++ ) @@ -779,17 +777,14 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength"); // **** a mettre dans SMESH_2D_Algo ? - const TopoDS_Face & FF = TopoDS::Face(aShape); + //const TopoDS_Face & FF = TopoDS::Face(aShape); //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); - TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); double meanElementLength = 100; double wireLength = 0; int wireElementsNumber = 0; - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next()) + for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next()) { const TopoDS_Edge & E = TopoDS::Edge(expe.Current()); int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); @@ -797,7 +792,6 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, wireLength += length; wireElementsNumber += nb; } - } if (wireElementsNumber) meanElementLength = wireLength / wireElementsNumber; //SCRUTE(meanElementLength); diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx index fac85f07d..180ceb760 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx @@ -33,6 +33,8 @@ #include "SMESH_2D_Algo.hxx" #include +#include "StdMeshers_Helper.hxx" + class SMDS_MeshNode; class TopTools_IndexedDataMapOfShapeListOfShape; class TopoDS_Face; @@ -95,6 +97,8 @@ protected: TopoDS_Wire myOuterWire; std::list myNodesOnCommonV; + + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index ad6ebc831..efa96e08c 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -51,6 +51,9 @@ #include #include #include +#include +#include +#include #include #include @@ -70,7 +73,20 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D() myTol3D=0.1; myWallNodesMaps.resize( SMESH_Block::NbFaces() ); myShapeXYZ.resize( SMESH_Block::NbSubShapes() ); + myTool = 0; } + +//======================================================================= +//function : ~StdMeshers_Penta_3D +//purpose : +//======================================================================= + +StdMeshers_Penta_3D::~StdMeshers_Penta_3D() +{ + if ( myTool ) + delete myTool; +} + //======================================================================= //function : Compute //purpose : @@ -91,33 +107,43 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, if (myErrorStatus){ return bOK; } + + myTool = new StdMeshers_Helper(aMesh); + myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape); + // MakeBlock(); - if (myErrorStatus){ + if (myErrorStatus){ + delete myTool; myTool = 0; + return bOK; + } + // + ClearMeshOnFxy1(); + if (myErrorStatus) { + delete myTool; myTool = 0; return bOK; } // MakeNodes(); if (myErrorStatus){ + delete myTool; myTool = 0; return bOK; } // MakeConnectingMap(); // - ClearMeshOnFxy1(); - if (myErrorStatus) { - return bOK; - } - // MakeMeshOnFxy1(); if (myErrorStatus) { + delete myTool; myTool = 0; return bOK; } // MakeVolumeMesh(); // + delete myTool; myTool = 0; return !bOK; } + //======================================================================= //function : MakeNodes //purpose : @@ -144,12 +170,24 @@ void StdMeshers_Penta_3D::MakeNodes() // 1.1 Horizontal size myJSize=0; for (i=0; iGetSubMeshContaining(aS); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - iNbN=aSM->NbNodes(); - myJSize+=iNbN; + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + if(!myCreateQuadratic) { + iNbN = aSM->NbNodes(); + } + else { + iNbN = 0; + SMDS_NodeIteratorPtr itn = aSM->GetNodes(); + while(itn->more()) { + const SMDS_MeshNode* aNode = itn->next(); + if(myTool->IsMedium(aNode)) + continue; + iNbN++; + } + } + myJSize += iNbN; } //printf("*** Horizontal: number of nodes summary=%d\n", myJSize); // @@ -159,9 +197,21 @@ void StdMeshers_Penta_3D::MakeNodes() const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z); SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - iNbN=aSM->NbNodes(); - myISize+=iNbN; + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + if(!myCreateQuadratic) { + iNbN = aSM->NbNodes(); + } + else { + iNbN = 0; + SMDS_NodeIteratorPtr itn = aSM->GetNodes(); + while(itn->more()) { + const SMDS_MeshNode* aNode = itn->next(); + if(myTool->IsMedium(aNode)) + continue; + iNbN++; + } + } + myISize += iNbN; } //printf("*** Vertical: number of nodes on edges and vertices=%d\n", myISize); // @@ -177,18 +227,19 @@ void StdMeshers_Penta_3D::MakeNodes() // vertices for (k=0; kGetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + const TopoDS_Shape& aS = myBlock.Shape(aSID); + SMDS_NodeIteratorPtr ite = pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); while(ite->more()) { const SMDS_MeshNode* aNode = ite->next(); + if(myTool->IsMedium(aNode)) + continue; aNodeID=aNode->GetID(); // aTNode.SetNode(aNode); aTNode.SetShapeSupportID(aSID); aTNode.SetBaseNodeID(aNodeID); // - if ( SMESH_Block::IsEdgeID (aSID)) - { + if ( SMESH_Block::IsEdgeID (aSID)) { const SMDS_EdgePosition* epos = static_cast(aNode->GetPosition().get()); myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); @@ -200,7 +251,7 @@ void StdMeshers_Penta_3D::MakeNodes() aP3D.SetCoord(aX, aY, aZ); myBlock.ComputeParameters(aP3D, aS, aCoords); } - iErr=myBlock.ErrorStatus(); + iErr = myBlock.ErrorStatus(); if (iErr) { MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << "SMESHBlock: ComputeParameters operation failed"); @@ -325,8 +376,7 @@ void StdMeshers_Penta_3D::MakeNodes() // 3.3 set XYZ of vertices, and initialize of the rest SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS(); - for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) - { + for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) { if ( SMESH_Block::IsVertexID( id )) { TopoDS_Shape V = myBlock.Shape( id ); SMESHDS_SubMesh* sm = aMesh->MeshElements( V ); @@ -344,23 +394,46 @@ void StdMeshers_Penta_3D::MakeNodes() SMESH_Block::TShapeID aSSID, aBNSSID; StdMeshers_TNode aTN; // - for (j=0; jGetMeshDS(); + int topfaceID = meshDS->ShapeToIndex(TopFace); + const TopoDS_Vertex& v001 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V001)); + SMDS_NodeIteratorPtr itn = pMesh->GetSubMeshContaining(v001)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* N = itn->next(); + gp_XY UV001 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v101 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V101)); + itn = pMesh->GetSubMeshContaining(v101)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV101 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v011 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V011)); + itn = pMesh->GetSubMeshContaining(v011)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV011 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v111 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V111)); + itn = pMesh->GetSubMeshContaining(v111)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV111 = myTool->GetNodeUV(TopFace,N); + + for (j=0; j* nColumns[8]; double ratio[4]; // base node position between columns [0.-1.] - if ( createNode ) - for ( k = 0; k < 4; ++k ) + if ( createNode ) { + for ( k = 0; k < 4; ++k ) { ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ], nColumns[k*2], nColumns[k*2+1]); + } + } // // XYZ on the bottom and top faces const SMDS_MeshNode* n = aBN.Node(); @@ -368,8 +441,9 @@ void StdMeshers_Penta_3D::MakeNodes() myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. ); // // first create or find a top node, then the rest ones in a column - for (i=myISize-1; i>0; --i) - { + for (i=myISize-1; i>0; --i) { + bIsUpperLayer = (i==(myISize-1)); + gp_XY UV_Ex01, UV_Ex11, UV_E0y1, UV_E1y1; if ( createNode ) { // set XYZ on vertical edges and faces for ( k = 0; k < 4; ++k ) { @@ -377,11 +451,28 @@ void StdMeshers_Penta_3D::MakeNodes() myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() ); // n = (*nColumns[k*2]) [ i ]; + gp_XY tmp1; + if( i==myISize-1 ) { + tmp1 = myTool->GetNodeUV(TopFace,n); + tmp1 = ( 1. - ratio[ k ]) * tmp1; + } gp_XYZ xyz( n->X(), n->Y(), n->Z() ); myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz; n = (*nColumns[k*2+1]) [ i ]; xyz.SetCoord( n->X(), n->Y(), n->Z() ); myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz; + if( i==myISize-1 ) { + gp_XY tmp2 = myTool->GetNodeUV(TopFace,n); + tmp1 += ratio[ k ] * tmp2; + if( k==0 ) + UV_Ex01 = tmp1; + else if( k==1 ) + UV_Ex11 = tmp1; + else if( k==2 ) + UV_E0y1 = tmp1; + else + UV_E1y1 = tmp1; + } } } // fill current node info @@ -395,7 +486,6 @@ void StdMeshers_Penta_3D::MakeNodes() aCoords.SetCoord(aX, aY, aZ); // // suporting shape ID - bIsUpperLayer=(i==(myISize-1)); ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); @@ -418,6 +508,30 @@ void StdMeshers_Penta_3D::MakeNodes() if ( bIsUpperLayer ) { const SMDS_MeshNode* n = aTN.Node(); myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() ); + // set node on top face: + // find UV parameter for this node + // UV_Ex11 + // UV011+-----+----------+UV111 + // | | + // | | + // UV_E0y1+ +node +UV_E1y1 + // | | + // | | + // | | + // UV001+-----+----------+UV101 + // UV_Ex01 + gp_Pnt2d aP; + double u = aCoords.X(), v = aCoords.Y(); + double u1 = ( 1. - u ), v1 = ( 1. - v ); + aP.ChangeCoord() = UV_Ex01 * v1; + aP.ChangeCoord() += UV_Ex11 * v; + aP.ChangeCoord() += UV_E0y1 * u1; + aP.ChangeCoord() += UV_E1y1 * u; + aP.ChangeCoord() -= UV001 * u1 * v1; + aP.ChangeCoord() -= UV101 * u * v1; + aP.ChangeCoord() -= UV011 * u1 * v; + aP.ChangeCoord() -= UV111 * u * v; + meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y()); } } if (myErrorStatus) { @@ -456,10 +570,13 @@ void StdMeshers_Penta_3D::MakeNodes() */ //DEB t } + + //======================================================================= //function : FindNodeOnShape //purpose : //======================================================================= + void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, const gp_XYZ& aParams, const int z, @@ -470,14 +587,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, double aX, aY, aZ, aD, aTol2, minD; gp_Pnt aP1, aP2; // - SMESH_Mesh* pMesh=GetMesh(); - aTol2=myTol3D*myTol3D; + SMESH_Mesh* pMesh = GetMesh(); + aTol2 = myTol3D*myTol3D; minD = 1.e100; - SMDS_MeshNode* pNode=NULL; + SMDS_MeshNode* pNode = NULL; // if ( aS.ShapeType() == TopAbs_FACE || - aS.ShapeType() == TopAbs_EDGE ) - { + aS.ShapeType() == TopAbs_EDGE ) { // find a face ID to which aTN belongs to int faceID; if ( aS.ShapeType() == TopAbs_FACE ) @@ -492,13 +608,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, } ASSERT( SMESH_Block::IsFaceID( faceID )); int fIndex = SMESH_Block::ShapeIndex( faceID ); - StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ]; + StdMeshers_IJNodeMap & ijNodes = myWallNodesMaps[ fIndex ]; // look for a base node in ijNodes const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() ); StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin(); for ( ; par_nVec != ijNodes.end(); par_nVec++ ) if ( par_nVec->second[ 0 ] == baseNode ) { - pNode=(SMDS_MeshNode*)par_nVec->second.at( z ); + pNode = (SMDS_MeshNode*)par_nVec->second.at( z ); aTN.SetNode(pNode); return; } @@ -510,6 +626,8 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); while(ite->more()) { const SMDS_MeshNode* aNode = ite->next(); + if(myTool->IsMedium(aNode)) + continue; aX=aNode->X(); aY=aNode->Y(); aZ=aNode->Z(); @@ -532,6 +650,7 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, //myErrorStatus=11; // can not find the node; } + //======================================================================= //function : SetHorizEdgeXYZ //purpose : @@ -583,6 +702,7 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ& aBase return r; } + //======================================================================= //function : MakeVolumeMesh //purpose : @@ -593,20 +713,20 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() // int i, j, ij, ik, i1, i2, aSSID; // - SMESH_Mesh* pMesh =GetMesh(); - SMESHDS_Mesh* meshDS=pMesh->GetMeshDS(); + SMESH_Mesh* pMesh = GetMesh(); + SMESHDS_Mesh* meshDS = pMesh->GetMeshDS(); // int shapeID = meshDS->ShapeToIndex( myShape ); // // 1. Set Node In Volume - ik=myISize-1; + ik = myISize-1; for (i=1; iSetNodeInVolume(aNode, shapeID); } } @@ -621,22 +741,28 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() const TopoDS_Face& aFxy0= TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); - SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS(); // - itf=aSM0->GetElements(); + itf = aSM0->GetElements(); while(itf->more()) { - const SMDS_MeshElement* pE0=itf->next(); + const SMDS_MeshElement* pE0 = itf->next(); // int nbFaceNodes = pE0->NbNodes(); + if(myCreateQuadratic) + nbFaceNodes = nbFaceNodes/2; if ( aN.size() < nbFaceNodes * 2 ) aN.resize( nbFaceNodes * 2 ); // k=0; aItNodes=pE0->nodesIterator(); while (aItNodes->more()) { - const SMDS_MeshElement* pNode=aItNodes->next(); - aID0=pNode->GetID(); - aJ[k]=GetIndexOnLayer(aID0); + //const SMDS_MeshElement* pNode = aItNodes->next(); + const SMDS_MeshNode* pNode = + static_cast (aItNodes->next()); + if(myTool->IsMedium(pNode)) + continue; + aID0 = pNode->GetID(); + aJ[k] = GetIndexOnLayer(aID0); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); return; @@ -646,19 +772,19 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() } // bool forward = true; - for (i=0; iAddVolume(aN[0], aN[1], aN[2], - aN[3], aN[4], aN[5]); - else - aV = meshDS->AddVolume(aN[0], aN[2], aN[1], - aN[3], aN[5], aN[4]); + if ( forward ) { + //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], + // aN[3], aN[4], aN[5]); + aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5]); + } + else { + //aV = meshDS->AddVolume(aN[0], aN[2], aN[1], + // aN[3], aN[5], aN[4]); + aV = myTool->AddVolume(aN[0], aN[2], aN[1], aN[3], aN[5], aN[4]); + } break; case 4: - if ( forward ) - aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + if ( forward ) { + //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + // aN[4], aN[5], aN[6], aN[7]); + aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5], aN[6], aN[7]); - else - aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1], + } + else { + //aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1], + // aN[4], aN[7], aN[6], aN[5]); + aV = myTool->AddVolume(aN[0], aN[3], aN[2], aN[1], aN[4], aN[7], aN[6], aN[5]); + } break; default: continue; @@ -727,74 +863,68 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() const TopoDS_Face& aFxy1= TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1)); // - SMESH_Mesh* pMesh=GetMesh(); + SMESH_Mesh* pMesh = GetMesh(); SMESHDS_Mesh * meshDS = pMesh->GetMeshDS(); // SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); - SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS(); // // set nodes on aFxy1 - aLevel=myISize-1; - itn=aSM0->GetNodes(); - aNbNodes=aSM0->NbNodes(); + aLevel = myISize-1; + itn = aSM0->GetNodes(); + aNbNodes = aSM0->NbNodes(); //printf("** aNbNodes=%d\n", aNbNodes); - while(itn->more()) { - const SMDS_MeshNode* aN0=itn->next(); - aID0=aN0->GetID(); - aJ=GetIndexOnLayer(aID0); - if (myErrorStatus) { - MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); - return; - } - // - ij=aLevel*myJSize+aJ; - const StdMeshers_TNode& aTN1=myTNodes[ij]; - SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node(); - // - meshDS->SetNodeOnFace(aN1, aFxy1); - } + // // set elements on aFxy1 vector aNodes1; // - itf=aSM0->GetElements(); + itf = aSM0->GetElements(); while(itf->more()) { - const SMDS_MeshElement * pE0=itf->next(); - aElementType=pE0->GetType(); + const SMDS_MeshElement* pE0 = itf->next(); + aElementType = pE0->GetType(); if (!aElementType==SMDSAbs_Face) { continue; } - aNbNodes=pE0->NbNodes(); + aNbNodes = pE0->NbNodes(); + if(myCreateQuadratic) + aNbNodes = aNbNodes/2; // if (aNbNodes!=3) { // continue; // } if ( aNodes1.size() < aNbNodes ) aNodes1.resize( aNbNodes ); // - k=aNbNodes-1; // reverse a face - aItNodes=pE0->nodesIterator(); + k = aNbNodes-1; // reverse a face + aItNodes = pE0->nodesIterator(); while (aItNodes->more()) { - const SMDS_MeshElement* pNode=aItNodes->next(); - aID0=pNode->GetID(); - aJ=GetIndexOnLayer(aID0); + //const SMDS_MeshElement* pNode = aItNodes->next(); + const SMDS_MeshNode* pNode = + static_cast (aItNodes->next()); + if(myTool->IsMedium(pNode)) + continue; + aID0 = pNode->GetID(); + aJ = GetIndexOnLayer(aID0); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); return; } // - ij=aLevel*myJSize+aJ; - const StdMeshers_TNode& aTN1=myTNodes[ij]; - const SMDS_MeshNode* aN1=aTN1.Node(); - aNodes1[k]=aN1; + ij = aLevel*myJSize + aJ; + const StdMeshers_TNode& aTN1 = myTNodes[ij]; + const SMDS_MeshNode* aN1 = aTN1.Node(); + aNodes1[k] = aN1; --k; } SMDS_MeshFace * face = 0; switch ( aNbNodes ) { case 3: - face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); break; case 4: - face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); break; default: continue; @@ -802,6 +932,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() meshDS->SetMeshElementOnShape(face, aFxy1); } } + //======================================================================= //function : ClearMeshOnFxy1 //purpose : @@ -838,6 +969,7 @@ int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID) j=(*aMapIt).second; return j; } + //======================================================================= //function : MakeConnectingMap //purpose : @@ -852,6 +984,7 @@ void StdMeshers_Penta_3D::MakeConnectingMap() myConnectingMap[aBNID]=j; } } + //======================================================================= //function : CreateNode //purpose : @@ -879,8 +1012,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, // // point inside solid // myBlock.Point(aParams, aP); // } - if (bIsUpperLayer) - { + if (bIsUpperLayer) { double u = aParams.X(), v = aParams.Y(); double u1 = ( 1. - u ), v1 = ( 1. - v ); aP.ChangeCoord() = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1; @@ -893,8 +1025,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v; aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u * v; } - else - { + else { SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() ); } // @@ -906,12 +1037,14 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, // aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); // - SMESH_Mesh* pMesh=GetMesh(); - SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS(); + SMESH_Mesh* pMesh = GetMesh(); + SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS(); // pNode = pMeshDS->AddNode(aX, aY, aZ); + aTN.SetNode(pNode); } + //======================================================================= //function : ShapeSupportID //purpose : @@ -980,21 +1113,21 @@ void StdMeshers_Penta_3D::MakeBlock() SMDSAbs_ElementType aElementType; SMESH_Mesh* pMesh=GetMesh(); // - iCnt=0; - iNbF=aM.Extent(); + iCnt = 0; + iNbF = aM.Extent(); for (i=1; i<=iNbF; ++i) { - const TopoDS_Shape& aF=aM(i); + const TopoDS_Shape& aF = aM(i); SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - SMDS_ElemIteratorPtr itf=aSM->GetElements(); + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + SMDS_ElemIteratorPtr itf = aSM->GetElements(); while(itf->more()) { - const SMDS_MeshElement * pElement=itf->next(); - aElementType=pElement->GetType(); + const SMDS_MeshElement * pElement = itf->next(); + aElementType = pElement->GetType(); if (aElementType==SMDSAbs_Face) { - iNbNodes=pElement->NbNodes(); - if (iNbNodes==3) { - aFTr=aF; + iNbNodes = pElement->NbNodes(); + if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) { + aFTr = aF; ++iCnt; if (iCnt>1) { MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); @@ -1013,7 +1146,7 @@ void StdMeshers_Penta_3D::MakeBlock() TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES); // // 1.1 Base vertex V000 - iNbE=aME.Extent(); + iNbE = aME.Extent(); if (iNbE!=4){ MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); myErrorStatus=7; // too few edges are in base face aFTr @@ -1080,7 +1213,7 @@ void StdMeshers_Penta_3D::MakeBlock() // 2. Load Block const TopoDS_Shell& aShell=TopoDS::Shell(aME(1)); myBlock.Load(aShell, aV000, aV001); - iErr=myBlock.ErrorStatus(); + iErr = myBlock.ErrorStatus(); if (iErr) { MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); myErrorStatus=100; // SMESHBlock: Load operation failed @@ -1154,10 +1287,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, bool rev1, CumOri = false; TopExp_Explorer exp( theFace, TopAbs_EDGE ); int nbEdges = 0; - for ( ; exp.More(); exp.Next() ) - { - if ( ++nbEdges > 4 ) + for ( ; exp.More(); exp.Next() ) { + if ( ++nbEdges > 4 ) { return false; // more than 4 edges in theFace + } TopoDS_Edge e = TopoDS::Edge( exp.Current() ); if ( theBaseEdge.IsSame( e )) continue; @@ -1174,8 +1307,9 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, else e2 = e; } - if ( nbEdges < 4 ) - return false; // lass than 4 edges in theFace + if ( nbEdges < 4 ) { + return false; // less than 4 edges in theFace + } // submeshes corresponding to shapes SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace ); @@ -1200,13 +1334,32 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, return false; } if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) { - MESSAGE( "Wrong nb face nodes: " << - sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); - return false; + // check quadratic case + if ( myCreateQuadratic ) { + int n1 = sm1->NbNodes()/2; + int n2 = smb->NbNodes()/2; + int n3 = sm1->NbNodes() - n1; + int n4 = smb->NbNodes() - n2; + int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4; + if( nf != smFace->NbNodes() ) { + MESSAGE( "Wrong nb face nodes: " << + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + return false; + } + } + else { + MESSAGE( "Wrong nb face nodes: " << + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + return false; + } } // IJ size int vsize = sm1->NbNodes() + 2; int hsize = smb->NbNodes() + 2; + if(myCreateQuadratic) { + vsize = vsize - sm1->NbNodes()/2 -1; + hsize = hsize - smb->NbNodes()/2 -1; + } // load nodes from theBaseEdge @@ -1226,12 +1379,15 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, double range = l - f; SMDS_NodeIteratorPtr nIt = smb->GetNodes(); const SMDS_MeshNode* node; - while ( nIt->more() ) - { + while ( nIt->more() ) { node = nIt->next(); + if(myTool->IsMedium(node)) + continue; const SMDS_EdgePosition* pos = dynamic_cast( node->GetPosition().get() ); - if ( !pos ) return false; + if ( !pos ) { + return false; + } double u = ( pos->GetUParameter() - f ) / range; vector & nVec = theIJNodes[ u ]; nVec.resize( vsize, nullNode ); @@ -1246,19 +1402,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge nIt = sm1->GetNodes(); - while ( nIt->more() ) - { + while ( nIt->more() ) { node = nIt->next(); + if(myTool->IsMedium(node)) + continue; const SMDS_EdgePosition* pos = dynamic_cast( node->GetPosition().get() ); - if ( !pos ) return false; + if ( !pos ) { + return false; + } sortedNodes.insert( make_pair( pos->GetUParameter(), node )); } loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() ); map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin(); int row = rev1 ? vsize - 1 : 0; - for ( ; u_n != sortedNodes.end(); u_n++ ) - { + for ( ; u_n != sortedNodes.end(); u_n++ ) { if ( rev1 ) row--; else row++; loadedNodes.insert( nVecf[ row ] = u_n->second ); @@ -1285,8 +1443,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1; // loop on columns int col = 0; - for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) - { + for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) { col++; row = 0; const SMDS_MeshNode* n1 = par_nVec_1->second[ row ]; @@ -1295,10 +1452,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, do { // look for a face by 2 nodes face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces ); - if ( face ) - { + if ( face ) { int nbFaceNodes = face->NbNodes(); - if ( nbFaceNodes > 4 ) { + if ( (!myCreateQuadratic && nbFaceNodes>4) || + (myCreateQuadratic && nbFaceNodes>8) ) { MESSAGE(" Too many nodes in a face: " << nbFaceNodes ); return false; } @@ -1308,6 +1465,8 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, eIt = face->nodesIterator() ; while ( !found && eIt->more() ) { node = static_cast( eIt->next() ); + if(myTool->IsMedium(node)) + continue; found = loadedNodes.insert( node ).second; if ( !found && node != n1 && node != n2 ) n3 = node; @@ -1320,18 +1479,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, par_nVec_2->second[ row ] = node; foundFaces.insert( face ); n2 = node; - if ( nbFaceNodes == 4 ) + if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) { n1 = par_nVec_1->second[ row ]; + } } - else if (nbFaceNodes == 3 && - n3 == par_nVec_1->second[ row ] ) + else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) ) && + n3 == par_nVec_1->second[ row ] ) { n1 = n3; + } else { MESSAGE( "Not quad mesh, column "<< col ); return false; } } - } while ( face && n1 && n2 ); + } + while ( face && n1 && n2 ); if ( row < vsize - 1 ) { MESSAGE( "Too few nodes in column "<< col <<": "<< row+1); @@ -1390,17 +1552,18 @@ int StdMeshers_SMESHBlock::ErrorStatus() const { return myErrorStatus; } + //======================================================================= //function : Load //purpose : //======================================================================= void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell) { - TopoDS_Vertex aV000, aV001; // Load(theShell, aV000, aV001); } + //======================================================================= //function : Load //purpose : @@ -1416,12 +1579,13 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, bool bOk; // myShapeIDMap.Clear(); - bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); + bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); if (!bOk) { myErrorStatus=2; return; } } + //======================================================================= //function : ComputeParameters //purpose : @@ -1431,24 +1595,25 @@ void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, { ComputeParameters(thePnt, myShell, theXYZ); } + //======================================================================= //function : ComputeParameters //purpose : //======================================================================= void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, const TopoDS_Shape& theShape, - gp_XYZ& theXYZ) + gp_XYZ& theXYZ) { myErrorStatus=0; // int aID; bool bOk; // - aID=ShapeID(theShape); + aID = ShapeID(theShape); if (myErrorStatus) { return; } - bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID); + bOk = myTBlock.ComputeParameters(thePnt, theXYZ, aID); if (!bOk) { myErrorStatus=4; // problems with computation Parameters return; @@ -1469,12 +1634,12 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, int aID; bool bOk=false; // - aID=ShapeID(theShape); + aID = ShapeID(theShape); if (myErrorStatus) { return; } if ( SMESH_Block::IsEdgeID( aID )) - bOk=myTBlock.EdgeParameters( aID, theU, theXYZ ); + bOk = myTBlock.EdgeParameters( aID, theU, theXYZ ); if (!bOk) { myErrorStatus=4; // problems with computation Parameters return; @@ -1492,6 +1657,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, // Point(theParams, aS, aP3D); } + //======================================================================= //function : Point //purpose : @@ -1500,15 +1666,15 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, const TopoDS_Shape& theShape, gp_Pnt& aP3D) { - myErrorStatus=0; + myErrorStatus = 0; // int aID; - bool bOk=false; + bool bOk = false; gp_XYZ aXYZ(99.,99.,99.); aP3D.SetXYZ(aXYZ); // if (theShape.IsNull()) { - bOk=myTBlock.ShellPoint(theParams, aXYZ); + bOk = myTBlock.ShellPoint(theParams, aXYZ); } // else { @@ -1518,14 +1684,14 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, } // if (SMESH_Block::IsVertexID(aID)) { - bOk=myTBlock.VertexPoint(aID, aXYZ); + bOk = myTBlock.VertexPoint(aID, aXYZ); } else if (SMESH_Block::IsEdgeID(aID)) { - bOk=myTBlock.EdgePoint(aID, theParams, aXYZ); + bOk = myTBlock.EdgePoint(aID, theParams, aXYZ); } // else if (SMESH_Block::IsFaceID(aID)) { - bOk=myTBlock.FacePoint(aID, theParams, aXYZ); + bOk = myTBlock.FacePoint(aID, theParams, aXYZ); } } if (!bOk) { @@ -1534,6 +1700,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, } aP3D.SetXYZ(aXYZ); } + //======================================================================= //function : ShapeID //purpose : @@ -1561,6 +1728,7 @@ int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape) myErrorStatus=2; // unknown shape; return aID; } + //======================================================================= //function : Shape //purpose : @@ -1580,3 +1748,5 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID) const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID); return aS; } + + diff --git a/src/StdMeshers/StdMeshers_Penta_3D.hxx b/src/StdMeshers/StdMeshers_Penta_3D.hxx index dc8ba72cf..ae5b03c54 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.hxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.hxx @@ -39,9 +39,12 @@ #include #include #include +#include #include "SMESH_Block.hxx" +#include "StdMeshers_Helper.hxx" + typedef std::map< double, std::vector > StdMeshers_IJNodeMap; class StdMeshers_SMESHBlock { @@ -165,7 +168,7 @@ class StdMeshers_Penta_3D { public: // methods StdMeshers_Penta_3D(); - //~StdMeshers_Penta_3D(); + ~StdMeshers_Penta_3D(); bool Compute(SMESH_Mesh& , const TopoDS_Shape& ); @@ -181,10 +184,10 @@ class StdMeshers_Penta_3D { return myTol3D; } - static bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, - const TopoDS_Face& theFace, - const TopoDS_Edge& theBaseEdge, - SMESHDS_Mesh* theMesh); + bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, + const TopoDS_Face& theFace, + const TopoDS_Edge& theBaseEdge, + SMESHDS_Mesh* theMesh); // Load nodes bound to theFace into column (vectors) and rows // of theIJNodes. // The value of theIJNodes map is a vector of ordered nodes so @@ -251,6 +254,9 @@ class StdMeshers_Penta_3D { // vector myWallNodesMaps; // nodes on a face vector myShapeXYZ; // point on each sub-shape + + bool myCreateQuadratic; + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index 6672e2565..f2d982bd1 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -40,7 +40,7 @@ StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, : SMESH_Hypothesis(hypId, studyId, gen) { _name = GetName(); - _param_algo_dim = -2; + _param_algo_dim = -1; // 1D auxiliary } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 9ffa37d1f..da30b6783 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -47,6 +47,7 @@ using namespace std; #include #include #include +#include #include #include @@ -80,6 +81,7 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); _compatibleHypothesis.push_back("QuadranglePreference"); + myTool = 0; } //============================================================================= @@ -91,6 +93,8 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D() { MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D"); + if ( myTool ) + delete myTool; } //============================================================================= @@ -128,11 +132,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); + if ( !myTool ) + myTool = new StdMeshers_Helper(aMesh); + _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape); FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape); - if (!quad) + if (!quad) { + delete myTool; myTool = 0; return false; + } if(myQuadranglePreference) { int n1 = quad->nbPts[0]; @@ -144,14 +154,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, ntmp = ntmp*2; if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { // special path for using only quandrangle faces - return ComputeQuadPref(aMesh, aShape, quad); + bool ok = ComputeQuadPref(aMesh, aShape, quad); + delete myTool; myTool = 0; + return ok; } } // set normalized grid on unit square in parametric domain SetNormalizedGrid(aMesh, aShape, quad); - if (!quad) + if (!quad) { + delete myTool; myTool = 0; return false; + } // --- compute 3D values on points, store points & quadrangles @@ -180,7 +194,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, quad->uv_grid[ij].node = node; } } - + // mesh faces // [2] @@ -194,16 +208,16 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, // 0 > > > > > > > > nbhoriz // i // [0] - + i = 0; int ilow = 0; int iup = nbhoriz - 1; if (quad->isEdgeOut[3]) { ilow++; } else { if (quad->isEdgeOut[1]) iup--; } - + int jlow = 0; int jup = nbvertic - 1; if (quad->isEdgeOut[0]) { jlow++; } else { if (quad->isEdgeOut[2]) jup--; } - + // regular quadrangles for (i = ilow; i < iup; i++) { for (j = jlow; j < jup; j++) { @@ -212,11 +226,12 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, b = quad->uv_grid[j * nbhoriz + i + 1].node; c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i].node; - SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } - + UVPtStruct *uv_e0 = quad->uv_edges[0]; UVPtStruct *uv_e1 = quad->uv_edges[1]; UVPtStruct *uv_e2 = quad->uv_edges[2]; @@ -225,7 +240,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, double eps = Precision::Confusion(); // Boundary quadrangles - + if (quad->isEdgeOut[0]) { // Down edge is out // @@ -237,14 +252,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, // . . . . . . . . . __ down edge nodes // // >->->->->->->->->->->->-> -- direction of processing - + int g = 0; // number of last processed node in the regular grid - + // number of last node of the down edge to be processed int stop = nbdown - 1; // if right edge is out, we will stop at a node, previous to the last one if (quad->isEdgeOut[1]) stop--; - + // for each node of the down edge find nearest node // in the first row of the regular grid and link them for (i = 0; i < stop; i++) { @@ -252,18 +267,19 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, a = uv_e0[i].node; b = uv_e0[i + 1].node; gp_Pnt pb (b->X(), b->Y(), b->Z()); - + // find node c in the regular grid, which will be linked with node b int near = g; if (i == stop - 1) { // right bound reached, link with the rightmost node near = iup; c = quad->uv_grid[nbhoriz + iup].node; - } else { + } + else { // find in the grid node c, nearest to the b double mind = RealLast(); for (int k = g; k <= iup; k++) { - + const SMDS_MeshNode *nk; if (k < ilow) // this can be, if left edge is out nk = uv_e3[1].node; // get node from the left edge @@ -283,14 +299,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near - 1 < ilow) d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + near - 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); // if node d is not at position g - make additional triangles @@ -301,7 +320,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + k - 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -363,14 +383,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near + 1 > iup) d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near + 1 < g) { // if d not is at g - make additional triangles @@ -380,7 +403,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -428,14 +452,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near - 1 < jlow) d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*near - 2].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near - 1 > g) { // if d not is at g - make additional triangles @@ -445,7 +472,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*k - 2].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -490,14 +518,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near + 1 > jup) d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(near + 1) + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near + 1 < g) { // if d not is at g - make additional triangles @@ -507,7 +538,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -518,6 +550,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } QuadDelete(quad); + delete myTool; myTool = 0; + bool isOk = true; return isOk; } @@ -557,7 +591,13 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); if (nbEdges < 4) { quad->edge[nbEdges] = E; - quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema + if(!_quadraticMesh) { + quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema + } + else { + int tmp = nb/2; + quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema + } } nbEdges++; } @@ -571,18 +611,21 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, return quad; } - //============================================================================= /*! - * + * CheckAnd2Dcompute */ //============================================================================= FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute - (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception) + (SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool CreateQuadratic) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); + _quadraticMesh = CreateQuadratic; + FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); if(!quad) return 0; @@ -1185,13 +1228,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), + myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1252,13 +1295,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), + myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1335,13 +1378,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), + myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1389,16 +1432,47 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh, map params; SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - while(ite->more()) { - const SMDS_MeshNode* node = ite->next(); - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - double param = epos->GetUParameter(); - params[param] = node; + if(!_quadraticMesh) { + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + } + else { + vector nodes(nbPoints+2); + nodes[0] = idFirst; + nodes[nbPoints+1] = idLast; + nbPoints = nbPoints/2; + int nn = 1; + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + nodes[nn++] = node; + // check if node is medium + bool IsMedium = false; + SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator(); + while (itn->more()) { + const SMDS_MeshElement* elem = itn->next(); + if ( elem->GetType() != SMDSAbs_Edge ) + continue; + if(elem->IsMediumNode(node)) { + IsMedium = true; + break; + } + } + if(IsMedium) + continue; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } } - int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); if (nbPoints != params.size()) { MESSAGE( "BAD NODE ON EDGE POSITIONS" ); return 0; @@ -1523,21 +1597,60 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh, // --- edge internal IDNodes (relies on good order storage, not checked) +// if(_quadraticMesh) { + // fill myNLinkNodeMap +// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements(); +// while(iter->more()) { +// const SMDS_MeshElement* elem = iter->next(); +// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); +// const SMDS_MeshNode* n1 = static_cast( nodeIt->next() ); +// const SMDS_MeshNode* n2 = static_cast( nodeIt->next() ); +// const SMDS_MeshNode* n3 = static_cast( nodeIt->next() ); +// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 )); +// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3)); +// myNLinkNodeMap[link] = n3; +// } +// } + map params; SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - while(ite->more()) - { - const SMDS_MeshNode* node = ite->next(); - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - double param = epos->GetUParameter(); - params[param] = node; + if(!_quadraticMesh) { + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + } + else { + nbPoints = nbPoints/2; + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + // check if node is medium + bool IsMedium = false; + SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator(); + while (itn->more()) { + const SMDS_MeshElement* elem = itn->next(); + if ( elem->GetType() != SMDSAbs_Edge ) + continue; + if(elem->IsMediumNode(node)) { + IsMedium = true; + break; + } + } + if(IsMedium) + continue; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } } - int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - if (nbPoints != params.size()) - { + if (nbPoints != params.size()) { MESSAGE( "BAD NODE ON EDGE POSITIONS" ); return 0; } diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index afb3498cb..9abff008c 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -34,7 +34,11 @@ #include "SMESH_Mesh.hxx" #include "Utils_SALOME_Exception.hxx" -class SMDS_MeshNode; +#include "gp_XY.hxx" + +#include "StdMeshers_Helper.hxx" + +//class SMDS_MeshNode; typedef struct uvPtStruct { @@ -75,11 +79,17 @@ public: throw (SALOME_Exception); FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) + const TopoDS_Shape& aShape, + const bool CreateQuadratic) throw (SALOME_Exception); static void QuadDelete(FaceQuadStruct* quad); + /** + * Returns NLinkNodeMap from myTool + */ + const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); } + ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp); @@ -120,6 +130,8 @@ protected: // construction of quadrangles if the number of nodes on opposite edges // is not the same in the case where the global number of nodes on edges is even bool myQuadranglePreference; + + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.cxx b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx index 013bde786..5ac5bd582 100644 --- a/src/StdMeshers/StdMeshers_QuadraticMesh.cxx +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx @@ -98,3 +98,14 @@ istream & operator >>(istream & load, StdMeshers_QuadraticMesh & hyp) { return hyp.LoadFrom( load ); } +//================================================================================ +/*! + * \brief Initialize my parameter values by the mesh built on the geometry + * \retval bool - false as this hypothesis does not have parameters values + */ +//================================================================================ + +bool StdMeshers_QuadraticMesh::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&) +{ + return false; +} diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.hxx b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx index 6f2cc7e83..8b88c93db 100644 --- a/src/StdMeshers/StdMeshers_QuadraticMesh.hxx +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx @@ -49,6 +49,17 @@ class StdMeshers_QuadraticMesh:public SMESH_Hypothesis virtual std::istream & LoadFrom(std::istream & load); friend std::ostream & operator <<(std::ostream & save, StdMeshers_QuadraticMesh & hyp); friend std::istream & operator >>(std::istream & load, StdMeshers_QuadraticMesh & hyp); + + /*! + * \brief Initialize my parameter values by the mesh built on the geometry + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + * + * Just return false as this hypothesis does not have parameters values + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + }; #endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 0c6144988..dc1ec9bb4 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -33,6 +33,8 @@ using namespace std; #include "StdMeshers_Distribution.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_subMesh.hxx" #include "StdMeshers_LocalLength.hxx" #include "StdMeshers_NumberOfSegments.hxx" @@ -44,7 +46,6 @@ using namespace std; #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMESH_subMesh.hxx" #include "Utils_SALOME_Exception.hxx" #include "utilities.h" @@ -90,6 +91,8 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, _compatibleHypothesis.push_back("Deflection1D"); _compatibleHypothesis.push_back("Arithmetic1D"); _compatibleHypothesis.push_back("AutomaticLength"); + + _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! } //============================================================================= @@ -109,22 +112,37 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D() //============================================================================= bool StdMeshers_Regular_1D::CheckHypothesis - (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus) { _hypType = NONE; + _quadraticMesh = false; + + const bool ignoreAuxiliaryHyps = false; + const list & hyps = + GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps); + + // find non-auxiliary hypothesis + const SMESHDS_Hypothesis *theHyp = 0; + list ::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) { + if ( static_cast(*h)->IsAuxiliary() ) { + if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 ) + _quadraticMesh = true; + } + else { + if ( !theHyp ) + theHyp = *h; // use only the first non-auxiliary hypothesis + } + } - const list &hyps = GetUsedHypothesis(aMesh, aShape); - if (hyps.size() == 0) + if ( !theHyp ) { aStatus = SMESH_Hypothesis::HYP_MISSING; return false; // can't work without a hypothesis } - // use only the first hypothesis - const SMESHDS_Hypothesis *theHyp = hyps.front(); - string hypName = theHyp->GetName(); if (hypName == "LocalLength") @@ -538,15 +556,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh ASSERT(!VLast.IsNull()); lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); - if (!lid->more()) - { + if (!lid->more()) { MESSAGE (" NO NODE BUILT ON VERTEX "); return false; } const SMDS_MeshNode * idLast = lid->next(); - if (!Curve.IsNull()) - { + if (!Curve.IsNull()) { list< double > params; bool reversed = false; if ( !_mainEdge.IsNull() ) @@ -566,9 +582,14 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh // only internal nodes receive an edge position with param on curve const SMDS_MeshNode * idPrev = idFirst; + double parPrev = f; + double parLast = l; +// if(reversed) { +// parPrev = l; +// parLast = f; +// } - for (list::iterator itU = params.begin(); itU != params.end(); itU++) - { + for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -576,17 +597,39 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnEdge(node, shapeID, param); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, shapeID); + if(_quadraticMesh) { + // create medium node + double prm = ( parPrev + param )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + idPrev = node; + parPrev = param; + } + if(_quadraticMesh) { + double prm = ( parPrev + parLast )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); } - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, shapeID); } - else - { + else { // Edge is a degenerated Edge : We put n = 5 points on the edge. - int NbPoints = 5; + const int NbPoints = 5; BRep_Tool::Range(E, f, l); double du = (l - f) / (NbPoints - 1); //MESSAGE("************* Degenerated edge! *****************"); @@ -596,18 +639,38 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh gp_Pnt P = BRep_Tool::Pnt(V1); const SMDS_MeshNode * idPrev = idFirst; - for (int i = 2; i < NbPoints; i++) - { + for (int i = 2; i < NbPoints; i++) { double param = f + (i - 1) * du; SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + if(_quadraticMesh) { + // create medium node + double prm = param - du/2.; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } meshDS->SetNodeOnEdge(node, shapeID, param); - - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, shapeID); idPrev = node; } - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, shapeID); + if(_quadraticMesh) { + // create medium node + double prm = l - du/2.; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } } return true; } @@ -618,40 +681,47 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh */ //============================================================================= -const list & StdMeshers_Regular_1D::GetUsedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _usedHypList.clear(); - _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy - int nbHyp = _usedHypList.size(); _mainEdge.Nullify(); + + SMESH_HypoFilter auxiliaryFilter, compatibleFilter; + auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() ); + const bool ignoreAux = true; + InitCompatibleHypoFilter( compatibleFilter, ignoreAux ); + + // get non-auxiliary assigned to aShape + int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); + if (nbHyp == 0) { // Check, if propagated from some other edge if (aShape.ShapeType() == TopAbs_EDGE && aMesh.IsPropagatedHypothesis(aShape, _mainEdge)) { - // Propagation of 1D hypothesis from on this edge - //_usedHypList = GetAppliedHypothesis(aMesh, _mainEdge); // copy - // use a general method in order not to nullify _mainEdge - _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, _mainEdge); // copy - nbHyp = _usedHypList.size(); + // Propagation of 1D hypothesis from on this edge; + // get non-auxiliary assigned to _mainEdge + nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, false ); } } - if (nbHyp == 0) + + if (nbHyp == 0) // nothing propagated nor assigned to aShape { - TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape )); - for (; ancIt.More(); ancIt.Next()) - { - const TopoDS_Shape& ancestor = ancIt.Value(); - _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy - nbHyp = _usedHypList.size(); - if (nbHyp == 1) - break; - } + SMESH_Algo::GetUsedHypothesis( aMesh, aShape, ignoreAuxiliary ); + nbHyp = _usedHypList.size(); } - if (nbHyp > 1) - _usedHypList.clear(); //only one compatible hypothesis allowed + else + { + // get auxiliary hyps from aShape + aMesh.GetHypotheses( aShape, auxiliaryFilter, _usedHypList, true ); + } + if ( nbHyp > 1 && ignoreAuxiliary ) + _usedHypList.clear(); //only one compatible non-auxiliary hypothesis allowed + return _usedHypList; } diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index 4ab58e9ce..e2695901b 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -49,7 +49,7 @@ public: const TopoDS_Shape& aShape); virtual const std::list & - GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true); ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); diff --git a/src/StdMeshersGUI/StdMeshers_images.po b/src/StdMeshersGUI/StdMeshers_images.po index c5978633b..64828da63 100644 --- a/src/StdMeshersGUI/StdMeshers_images.po +++ b/src/StdMeshersGUI/StdMeshers_images.po @@ -80,10 +80,14 @@ msgstr "mesh_tree_algo_quad.png" msgid "ICON_SMESH_TREE_HYPO_MaxElementArea" msgstr "mesh_tree_hypo_area.png" -#mesh_tree_hypo_area +#mesh_tree_hypo_quadranglepreference msgid "ICON_SMESH_TREE_HYPO_QuadranglePreference" msgstr "mesh_tree_algo_quad.png" +#mesh_tree_hypo_quadraticmesh +msgid "ICON_SMESH_TREE_HYPO_QuadraticMesh" +msgstr "mesh_tree_hypo_length.png" + #mesh_tree_hypo_length msgid "ICON_SMESH_TREE_HYPO_LocalLength" msgstr "mesh_tree_hypo_length.png" diff --git a/src/StdMeshers_I/Makefile.in b/src/StdMeshers_I/Makefile.in index cb445cb85..0f5cbcd18 100644 --- a/src/StdMeshers_I/Makefile.in +++ b/src/StdMeshers_I/Makefile.in @@ -52,7 +52,8 @@ EXPORT_HEADERS = \ StdMeshers_MEFISTO_2D_i.hxx \ StdMeshers_Hexa_3D_i.hxx \ StdMeshers_AutomaticLength_i.hxx \ - StdMeshers_QuadranglePreference_i.hxx + StdMeshers_QuadranglePreference_i.hxx \ + StdMeshers_QuadraticMesh_i.hxx # Libraries targets @@ -75,7 +76,8 @@ LIB_SRC = \ StdMeshers_MEFISTO_2D_i.cxx \ StdMeshers_Hexa_3D_i.cxx \ StdMeshers_AutomaticLength_i.cxx \ - StdMeshers_QuadranglePreference_i.cxx + StdMeshers_QuadranglePreference_i.cxx \ + StdMeshers_QuadraticMesh_i.cxx LIB_SERVER_IDL = SMESH_BasicHypothesis.idl diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index 768d2c4fb..a379e81ac 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -39,6 +39,7 @@ using namespace std; #include "StdMeshers_Propagation_i.hxx" #include "StdMeshers_LengthFromEdges_i.hxx" #include "StdMeshers_QuadranglePreference_i.hxx" +#include "StdMeshers_QuadraticMesh_i.hxx" #include "StdMeshers_MaxElementArea_i.hxx" #include "StdMeshers_MaxElementVolume_i.hxx" #include "StdMeshers_NotConformAllowed_i.hxx" @@ -87,6 +88,8 @@ extern "C" aCreator = new HypothesisCreator_i; else if (strcmp(aHypName, "QuadranglePreference") == 0) aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "QuadraticMesh") == 0) + aCreator = new HypothesisCreator_i; // Algorithms else if (strcmp(aHypName, "Regular_1D") == 0) -- 2.39.2