diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx index 8baf9846a..7c949c527 100644 --- a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx @@ -36,6 +36,7 @@ #include "SMESH_HypoFilter.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_Comment.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -58,6 +59,8 @@ #include #include +typedef SMESH_Comment TComm; + using namespace std; @@ -164,7 +167,7 @@ namespace { const int eventType, SMESH_subMesh* subMesh, EventListenerData* data, - SMESH_Hypothesis* /*hyp*/) + const SMESH_Hypothesis* /*hyp*/) { bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT && subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ); @@ -175,32 +178,35 @@ namespace { { if ( SMESH_subMesh* sm = *smIt ) { sm->SetIsAlwaysComputed( false ); - if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX ) - sm->GetFather()->GetGen()->Compute( *sm ); - else // edge - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } } } // at study restoration: // check if edge submesh must have _alwaysComputed flag - else if ( eventType == SMESH_subMesh::COMPUTE_EVENT && - event == SMESH_subMesh::SUBMESH_RESTORED ) + else if ( event == SMESH_subMesh::SUBMESH_RESTORED && + eventType == SMESH_subMesh::COMPUTE_EVENT ) { if ( !subMesh->GetEventListenerData( this )) { // not yet checked SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS(); - TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() ); - TopoDS_Vertex V1, V2; - TopExp::Vertices( edge, V1, V2 ); - bool noVertexNode1 = ( !SMESH_Algo::VertexNode( V1, meshDS )); - bool noVertexNode2 = ( !SMESH_Algo::VertexNode( V2, meshDS )); - if ( noVertexNode1 || noVertexNode2 ) { - TopoDS_Face face; - auto_ptr< StdMeshers_FaceSide > side - ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(), - edge, face, false )); - if ( side->NbSegments() ) - careOfSubMeshes( *side, this ); + if ( meshDS->NbNodes() > 0 ) { + // check if there are nodes on all vertices + bool hasNodesOnVerext = true; + SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); + while ( hasNodesOnVerext && smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + hasNodesOnVerext = ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbNodes() ); + } + if ( !hasNodesOnVerext ) { + // check if an edge is a part of a complex side + TopoDS_Face face; + TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() ); + auto_ptr< StdMeshers_FaceSide > side + ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(), + edge, face, false )); + if ( side->NbEdges() > 1 && side->NbSegments() ) + careOfSubMeshes( *side, this ); + } } } } @@ -343,15 +349,14 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh & aMesh, // Create mesh const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); - if (!nFirst) { - MESSAGE (" NO NODE BUILT ON VERTEX "); - return false; - } - const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if (!nLast) { - MESSAGE (" NO NODE BUILT ON VERTEX "); - return false; - } + const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); + if (!nFirst) + return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ") + <ShapeToIndex(VFirst)); + if (!nLast) + return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ") + <ShapeToIndex(VLast)); + vector nodes( nbNodes, (const SMDS_MeshNode*)0 ); nodes.front() = nFirst; nodes.back() = nLast; @@ -397,9 +402,9 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh & aMesh, } // remove nodes on internal vertices - for ( int iE = 0; iE < side->NbEdges()-1; ++iE ) + for ( int iE = 1; iE < side->NbEdges(); ++iE ) { - TopoDS_Vertex V = side->LastVertex( iE ); + TopoDS_Vertex V = side->FirstVertex( iE ); while ( const SMDS_MeshNode * n = SMESH_Algo::VertexNode( V, meshDS )) meshDS->RemoveNode( n ); } diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index 21490011b..80cd6caeb 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -36,6 +36,7 @@ #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" +#include "SMESH_Comment.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -47,23 +48,20 @@ #include #include #include -//#include #include #include #include -// #include -// #include -// #include -// #include #include #include "utilities.h" #include "Utils_ExceptHandlers.hxx" +typedef SMESH_Comment TComm; + using namespace std; -static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); +static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &); //============================================================================= /*! @@ -71,8 +69,8 @@ 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) +StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_3D_Algo(hypId, studyId, gen) { MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); _name = "Hexa_3D"; @@ -175,8 +173,8 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& */ //============================================================================= -bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, - const TopoDS_Shape & aShape)throw(SALOME_Exception) +bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); MESSAGE("StdMeshers_Hexa_3D::Compute"); @@ -184,7 +182,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, // 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()) { @@ -192,13 +189,10 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, ASSERT(aSubMesh); meshFaces.push_back(aSubMesh); } - if (meshFaces.size() != 6) { - SCRUTE(meshFaces.size()); - return false; - } + if (meshFaces.size() != 6) + return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in block"); // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) - //MESSAGE("---"); // tool for working with quadratic elements SMESH_MesherHelper aTool (aMesh); @@ -231,7 +225,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, for (int i = 0; i < 6; i++) aQuads[i] = 0; - for (int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) + { TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); string algoName = algo->GetName(); @@ -248,9 +243,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, } } if ( ! isAllQuad ) { - //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f - bool bIsOk = ComputePentahedralMesh(aMesh, aShape); - return ClearAndReturn( aQuads, bIsOk ); + SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape); + return ClearAndReturn( aQuads, error(err)); } StdMeshers_Quadrangle_2D *quadAlgo = dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); @@ -259,7 +253,9 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh); } catch(SALOME_Exception & S_ex) { - return ClearAndReturn( aQuads, false ); + return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) << + " Raised by StdMeshers_Quadrangle_2D " + " on face #" << meshDS->ShapeToIndex( aFace ))); } // 0.2.1 - number of points on the opposite edges must be the same @@ -270,58 +266,30 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, aQuads[i]->side[2]->NbEdges() != 1 || aQuads[i]->side[3]->NbEdges() != 1*/) { MESSAGE("different number of points on the opposite edges of face " << i); - // ASSERT(0); - // \begin{E.A.} // Try to go into penta algorithm 'cause it has been improved. - // return ClearAndReturn( aQuads, false ); - bool bIsOk = ComputePentahedralMesh(aMesh, aShape); - return ClearAndReturn( aQuads, bIsOk ); - // \end{E.A.} + SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape); + return ClearAndReturn( aQuads, error(err)); } } // 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("---"); aCube.V000 = aQuads[0]->side[0]->FirstVertex(); // will be (0,0,0) on the unit cube aCube.V100 = aQuads[0]->side[0]->LastVertex(); // will be (1,0,0) on the unit cube aCube.V001 = aQuads[0]->side[2]->FirstVertex(); // will be (0,0,1) on the unit cube aCube.V101 = aQuads[0]->side[2]->LastVertex(); // will be (1,0,1) on the unit cube - // 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, aCube.V000, MS); -// ASSERT(!E_0Y0.IsNull()); - -// TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V100, MS); -// ASSERT(!E_1Y0.IsNull()); - -// TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V101, MS); -// ASSERT(!E_1Y1.IsNull()); - -// TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V001, MS); -// ASSERT(!E_0Y1.IsNull()); - - // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 - //MESSAGE("---"); - TopTools_IndexedMapOfShape MV0; TopExp::MapShapes(F, TopAbs_VERTEX, MV0); @@ -330,33 +298,7 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, aCube.V011 = OppositeVertex( aCube.V001, MV0, aQuads); aCube.V111 = OppositeVertex( aCube.V101, MV0, aQuads); -// TopoDS_Vertex VFirst, VLast; -// TopExp::Vertices(E_0Y0, VFirst, VLast); -// if (VFirst.IsSame(aCube.V000)) -// aCube.V010 = VLast; -// else -// aCube.V010 = VFirst; - -// TopExp::Vertices(E_1Y0, VFirst, VLast); -// if (VFirst.IsSame(aCube.V100)) -// aCube.V110 = VLast; -// else -// aCube.V110 = VFirst; - -// TopExp::Vertices(E_1Y1, VFirst, VLast); -// if (VFirst.IsSame(aCube.V101)) -// aCube.V111 = VLast; -// else -// aCube.V111 = VFirst; - -// TopExp::Vertices(E_0Y1, VFirst, VLast); -// if (VFirst.IsSame(aCube.V001)) -// aCube.V011 = VLast; -// else -// aCube.V011 = VFirst; - // 1.6 - find remaining faces given 4 vertices - //MESSAGE("---"); int _indY0 = 0; aCube.quad_Y0 = aQuads[_indY0]; @@ -381,8 +323,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, aCube.V100, aCube.V101, aCube.V110, aCube.V111); aCube.quad_X1 = aQuads[_indX1]; - //MESSAGE("---"); - // 1.7 - get convertion coefs from face 2D normalized to 3D normalized Conv2DStruct cx0; // for face X=0 @@ -407,7 +347,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, // 1.8 - create a 3D structure for normalized values - //MESSAGE("---"); int nbx = aCube.quad_Z0->side[0]->NbPoints(); if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints(); @@ -734,20 +673,12 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, 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 = aTool.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 = aTool.AddVolume(np[n1].node, np[n4].node, np[n3].node, np[n2].node, np[n5].node, np[n8].node, @@ -759,7 +690,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, } } if ( np ) delete [] np; - //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); return ClearAndReturn( aQuads, true ); } @@ -769,8 +699,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, */ //============================================================================= -void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, - int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS) +void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, int nbz, + Point3DStruct * np, const SMESHDS_Mesh * meshDS) { int ijk = k * nbx * nby + j * nbx + i; const SMDS_MeshNode * node = np[ijk].node; @@ -1050,16 +980,21 @@ TopoDS_Vertex StdMeshers_Hexa_3D::OppositeVertex(const TopoDS_Vertex& aVertex, //function : ComputePentahedralMesh //purpose : //======================================================================= -bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) + +SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) { //printf(" ComputePentahedralMesh HERE\n"); // bool bOK; + SMESH_ComputeErrorPtr err = SMESH_ComputeError::New(); //int iErr; StdMeshers_Penta_3D anAlgo; // bOK=anAlgo.Compute(aMesh, aShape); // + err = anAlgo.GetComputeError(); + // if ( !bOK && anAlgo.ErrorStatus() == 5 ) { static StdMeshers_Prism_3D * aPrism3D = 0; @@ -1068,10 +1003,12 @@ bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen ); } SMESH_Hypothesis::Hypothesis_Status aStatus; - if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) + if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) { bOK = aPrism3D->Compute( aMesh, aShape ); + err = aPrism3D->GetComputeError(); + } } - return bOK; + return err; } diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index b08d352f2..cb4e61fc1 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -34,6 +34,7 @@ #include "SMESH_subMesh.hxx" #include "SMESH_Block.hxx" #include "SMESH_MesherHelper.hxx" +#include "SMESH_Comment.hxx" #include "StdMeshers_FaceSide.hxx" #include "StdMeshers_MaxElementArea.hxx" @@ -180,8 +181,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD)); // helper builds quadratic mesh if necessary - myTool = new SMESH_MesherHelper(aMesh); - auto_ptr helperDeleter( myTool ); + SMESH_MesherHelper helper(aMesh); + myTool = &helper; _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); const bool ignoreMediumNodes = _quadraticMesh; @@ -209,10 +210,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh { wireEdges.splice(wireEdges.end(), wireEdges, wireEdges.begin(), ++wireEdges.begin()); - if ( from->IsSame( wireEdges.front() )) { - MESSAGE( "No nodes on vertices on wire " << iW+1); - return false; - } + if ( from->IsSame( wireEdges.front() )) + return error(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"); } StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh, true, ignoreMediumNodes); @@ -222,7 +221,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh from = to; } if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments - return false; + return error(COMPERR_BAD_INPUT_MESH, + SMESH_Comment("Too few segments")<NbSegments()); if (_hypLengthFromEdges && _edgeLength < DBL_MIN ) _edgeLength = 100; @@ -283,7 +283,7 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh } else { - MESSAGE("Error in Triangulation"); + error(ierr,"Error in Triangulation (aptrte())"); } } if (nudslf != NULL) delete[]nudslf; @@ -512,12 +512,12 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, { const vector& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue); if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) { - MESSAGE("Wrong nb UVPtStruct: "<::const_iterator uvPt = uvPtVec.begin(); diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index 51b33214f..6359f2905 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -38,6 +38,7 @@ #include "SMESH_MeshEditor.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_Comment.hxx" #include #include @@ -71,7 +72,7 @@ enum { NB_WALL_FACES = 4 }; //purpose : //======================================================================= StdMeshers_Penta_3D::StdMeshers_Penta_3D() -: myErrorStatus(1) +: myErrorStatus(SMESH_ComputeError::New()) { myTol3D=0.1; myWallNodesMaps.resize( SMESH_Block::NbFaces() ); @@ -86,8 +87,6 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D() StdMeshers_Penta_3D::~StdMeshers_Penta_3D() { - if ( myTool ) - delete myTool; } //======================================================================= @@ -99,51 +98,45 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, { MESSAGE("StdMeshers_Penta_3D::Compute()"); // - myErrorStatus=0; - // bool bOK=false; // myShape=aShape; SetMesh(aMesh); // CheckData(); - if (myErrorStatus){ + if (!myErrorStatus->IsOK()) { return bOK; } - myTool = new SMESH_MesherHelper(aMesh); + SMESH_MesherHelper helper(aMesh); + myTool = &helper; myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape); // MakeBlock(); - if (myErrorStatus){ - delete myTool; myTool = 0; + if (!myErrorStatus->IsOK()) { return bOK; } // ClearMeshOnFxy1(); - if (myErrorStatus) { - delete myTool; myTool = 0; + if (!myErrorStatus->IsOK()) { return bOK; } // MakeNodes(); - if (myErrorStatus){ - delete myTool; myTool = 0; + if (!myErrorStatus->IsOK()) { return bOK; } // MakeConnectingMap(); // MakeMeshOnFxy1(); - if (myErrorStatus) { - delete myTool; myTool = 0; + if (!myErrorStatus->IsOK()) { return bOK; } // MakeVolumeMesh(); // - delete myTool; myTool = 0; return !bOK; } @@ -153,8 +146,6 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, //======================================================================= void StdMeshers_Penta_3D::MakeNodes() { - myErrorStatus=0; - // const int aNbSIDs=9; int i, j, k, ij, iNbN, aNodeID, aSize, iErr; double aX, aY, aZ; @@ -258,7 +249,7 @@ void StdMeshers_Penta_3D::MakeNodes() if (iErr) { MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << "SMESHBlock: ComputeParameters operation failed"); - myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed + myErrorStatus=myBlock.GetError(); return; } aTNode.SetNormCoord(aCoords); @@ -284,8 +275,10 @@ void StdMeshers_Penta_3D::MakeNodes() TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )), pMesh->GetMeshDS()); if ( !ok ) { - myErrorStatus = i + 1; - MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus ); + myErrorStatus->myName = COMPERR_BAD_INPUT_MESH; + myErrorStatus->myComment = SMESH_Comment() << + "Can't find regular quadrangle mesh on a side face #" << + pMesh->GetMeshDS()->ShapeToIndex( myBlock.Shape( wallFaceID[ i ])); return; } } @@ -430,7 +423,7 @@ void StdMeshers_Penta_3D::MakeNodes() // // suporting shape ID ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID); - if (myErrorStatus) { + if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); return; } @@ -477,7 +470,7 @@ void StdMeshers_Penta_3D::MakeNodes() meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y()); } } - if (myErrorStatus) { + if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); return; } @@ -525,8 +518,6 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, const int z, StdMeshers_TNode& aTN) { - myErrorStatus=0; - // double aX, aY, aZ, aD, aTol2, minD; gp_Pnt aP1, aP2; // @@ -670,8 +661,6 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ& aBase //======================================================================= void StdMeshers_Penta_3D::MakeVolumeMesh() { - myErrorStatus=0; - // int i, j, ij, ik, i1, i2, aSSID; // SMESH_Mesh* pMesh = GetMesh(); @@ -724,7 +713,7 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() continue; aID0 = pNode->GetID(); aJ[k] = GetIndexOnLayer(aID0); - if (myErrorStatus) { + if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); return; } @@ -811,8 +800,6 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() //======================================================================= void StdMeshers_Penta_3D::MakeMeshOnFxy1() { - myErrorStatus=0; - // int aID0, aJ, aLevel, ij, aNbNodes, k; // SMDS_NodeIteratorPtr itn; @@ -859,14 +846,13 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() k = aNbNodes-1; // reverse a face aItNodes = pE0->nodesIterator(); while (aItNodes->more()) { - //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) { + if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); return; } @@ -908,8 +894,6 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() //======================================================================= void StdMeshers_Penta_3D::ClearMeshOnFxy1() { - myErrorStatus=0; - // SMESH_subMesh* aSubMesh; SMESH_Mesh* pMesh=GetMesh(); // @@ -925,14 +909,13 @@ void StdMeshers_Penta_3D::ClearMeshOnFxy1() //======================================================================= int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID) { - myErrorStatus=0; - // int j=-1; StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt; // aMapIt=myConnectingMap.find(aID); if (aMapIt==myConnectingMap.end()) { - myErrorStatus=200; + myErrorStatus->myName = 200; + myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D"; return j; } j=(*aMapIt).second; @@ -962,9 +945,6 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, const gp_XYZ& aParams, StdMeshers_TNode& aTN) { - myErrorStatus=0; - // - // int iErr; double aX, aY, aZ; // gp_Pnt aP; @@ -1022,8 +1002,6 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, const SMESH_Block::TShapeID aBNSSID, SMESH_Block::TShapeID& aSSID) { - myErrorStatus=0; - // switch (aBNSSID) { case SMESH_Block::ID_V000: aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z; @@ -1054,7 +1032,8 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, break; default: aSSID=SMESH_Block::ID_NONE; - myErrorStatus=10; // Can not find supporting shape ID + myErrorStatus->myName=10; // Can not find supporting shape ID + myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D"; break; } return; @@ -1065,8 +1044,6 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, //======================================================================= void StdMeshers_Penta_3D::MakeBlock() { - myErrorStatus=0; - // bool bFound; int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF; // @@ -1263,7 +1240,8 @@ void StdMeshers_Penta_3D::MakeBlock() } } if (!isOK) { - myErrorStatus=5; // more than one face has triangulation + myErrorStatus->myName=5; // more than one face has triangulation + myErrorStatus->myComment="Incorrect input mesh"; return; } } @@ -1278,7 +1256,9 @@ void StdMeshers_Penta_3D::MakeBlock() iNbE = aME.Extent(); if (iNbE!= NB_WALL_FACES ){ MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); - myErrorStatus=7; // too few edges are in base face aFTr + myErrorStatus->myName=7; // too few edges are in base face aFTr + myErrorStatus->myComment=SMESH_Comment("Not a quadrilateral face #") + <GetMeshDS()->ShapeToIndex( aFTr )<<": "<myName=7; // too few edges meet in base vertex + myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #") + <GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<myName=8; // can not find reper V001 + myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #") + <GetMeshDS()->ShapeToIndex( aV000 ); return; } //DEB @@ -1335,7 +1319,8 @@ void StdMeshers_Penta_3D::MakeBlock() iNbE=aME.Extent(); if (iNbE!=1) { MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); - myErrorStatus=9; // number of shells in source shape !=1 + myErrorStatus->myName=9; // number of shells in source shape !=1 + myErrorStatus->myComment=SMESH_Comment("Unexpected nb of shells ")<myName=2; // null shape + myErrorStatus->myComment="Null shape"; return; } // aST=myShape.ShapeType(); if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) { MESSAGE("StdMeshers_Penta_3D::CheckData() "); - myErrorStatus=3; // not compatible type of shape + myErrorStatus->myName=3; // not compatible type of shape + myErrorStatus->myComment=SMESH_Comment("Wrong shape type (TopAbs_ShapeEnum) ")<myName=4; // number of subshape is not compatible + myErrorStatus->myComment="Wrong number of subshapes of a block"; return; } } @@ -1682,6 +1668,28 @@ int StdMeshers_SMESHBlock::ErrorStatus() const return myErrorStatus; } +//================================================================================ +/*! + * \brief Return problem description + */ +//================================================================================ + +SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const +{ + SMESH_ComputeErrorPtr err = SMESH_ComputeError::New(); + string & text = err->myComment; + switch ( myErrorStatus ) { + case 2: + case 3: text = "Internal error of StdMeshers_Penta_3D"; break; + case 4: text = "Can't compute normalized parameters of a point inside a block"; break; + case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break; + case 6: text = "Can't detect block subshapes. Not a block?"; break; + } + if (!text.empty()) + err->myName = myErrorStatus; + return err; +} + //======================================================================= //function : Load //purpose : @@ -1710,7 +1718,7 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, myShapeIDMap.Clear(); bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); if (!bOk) { - myErrorStatus=2; + myErrorStatus=6; return; } } @@ -1824,7 +1832,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, } } if (!bOk) { - myErrorStatus=4; // problems with point computation + myErrorStatus=5; // problems with point computation return; } aP3D.SetXYZ(aXYZ); diff --git a/src/StdMeshers/StdMeshers_Penta_3D.hxx b/src/StdMeshers/StdMeshers_Penta_3D.hxx index a635a3828..667b50096 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.hxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.hxx @@ -42,7 +42,7 @@ #include #include "SMESH_Block.hxx" - +#include "SMESH_ComputeError.hxx" #include "SMESH_MesherHelper.hxx" typedef std::map< double, std::vector > StdMeshers_IJNodeMap; @@ -87,6 +87,8 @@ public: int ErrorStatus() const; + SMESH_ComputeErrorPtr GetError() const; + protected: TopoDS_Shell myShell; @@ -173,6 +175,12 @@ class StdMeshers_Penta_3D { bool Compute(SMESH_Mesh& , const TopoDS_Shape& ); int ErrorStatus() const { + if (myErrorStatus->IsOK()) + return 0; + return myErrorStatus->myName; + } + + SMESH_ComputeErrorPtr GetComputeError() const { return myErrorStatus; } @@ -244,7 +252,7 @@ class StdMeshers_Penta_3D { TopoDS_Shape myShape; StdMeshers_SMESHBlock myBlock; void * myMesh; - int myErrorStatus; + SMESH_ComputeErrorPtr myErrorStatus; // vector myTNodes; int myISize; diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index dd2c271d5..8d87d043f 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -34,6 +34,7 @@ #include "SMDS_VolumeTool.hxx" #include "SMDS_VolumeOfNodes.hxx" #include "SMDS_EdgePosition.hxx" +#include "SMESH_Comment.hxx" #include "utilities.h" @@ -55,6 +56,7 @@ using namespace std; // } typedef StdMeshers_ProjectionUtils TAssocTool; +typedef SMESH_Comment TCom; enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0, ID_TOP_FACE = SMESH_Block::ID_Fxy1, @@ -227,15 +229,14 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh& a bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape) { - myHelper = new SMESH_MesherHelper( theMesh ); - // to delete helper at exit from Compute() - std::auto_ptr helperDeleter( myHelper ); + SMESH_MesherHelper helper( theMesh ); + myHelper = &helper; myHelper->IsQuadraticSubMesh( theShape ); // Analyse mesh and geomerty to find block subshapes and submeshes if ( !myBlock.Init( myHelper, theShape )) - return false; + return error( myBlock.GetError()); SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); @@ -282,7 +283,9 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() ); gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE )) - RETURN_BAD_RESULT("ComputeParameters() on the top face failed"); + return error(dfltErr(),TCom("Can't compute normalized parameters ") + << "for node " << column.back()->GetID() + << " on the face #"<< column.back()->GetPosition()->GetShapeId() ); // vertical loop TNodeColumn::iterator columnNodes = column.begin(); @@ -308,7 +311,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh // compute coords for a new node gp_XYZ coords; if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords )) - RETURN_BAD_RESULT("SMESH_Block::ShellPoint() failed"); + return error(dfltErr(),"Can't compute coordinates by normalized parameters"); // create a node node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); @@ -320,7 +323,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh // Create volumes SMESHDS_SubMesh* smDS = myBlock.SubMeshDS( ID_BOT_FACE ); - if ( !smDS ) RETURN_BAD_RESULT("Null submesh"); + if ( !smDS ) return error(COMPERR_BAD_INPUT_MESH, "Null submesh"); // loop on bottom mesh faces SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); @@ -341,13 +344,13 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) - RETURN_BAD_RESULT(" node column for a node not found"); + return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() ); columns[ i ] = & bot_column->second; } else { columns[ i ] = myBlock.GetNodeColumn( n ); if ( !columns[ i ] ) - RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() ); + return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() ); } } // create prisms @@ -459,7 +462,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS(); if ( !botSMDS || botSMDS->NbElements() == 0 ) - RETURN_BAD_RESULT("Empty horiz submesh"); + return error(dfltErr(),TCom("No elememts on face #") << botSM->GetId()); bool needProject = false; if ( !topSMDS || @@ -467,12 +470,15 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() botSMDS->NbNodes() != topSMDS->NbNodes()) { if ( myBlock.HasNotQuadElemOnTop() ) - RETURN_BAD_RESULT("Different triangles on 2 sides"); + return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); needProject = true; } if ( 0/*needProject && !myProjectTriangles*/ ) - RETURN_BAD_RESULT("Need to project but not allowed"); + return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); + ///RETURN_BAD_RESULT("Need to project but not allowed"); if ( needProject ) { @@ -486,14 +492,16 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(), topFace, myBlock.Mesh(), shape2ShapeMap) ) - RETURN_BAD_RESULT("FindSubShapeAssociation failed"); + return error(dfltErr(),TCom("Topology of faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); // Find matching nodes of top and bottom faces TNodeNodeMap n2nMap; if ( ! TAssocTool::FindMatchingNodesOnFaces( botFace, myBlock.Mesh(), topFace, myBlock.Mesh(), shape2ShapeMap, n2nMap )) - RETURN_BAD_RESULT("Different mesh on top and bottom faces"); + return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); // Fill myBotToColumnMap @@ -508,7 +516,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() // compute bottom node params TNode bN( botNode ); if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE )) - RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed"); + return error(dfltErr(),TCom("Can't compute normalized parameters ") + << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() ); // create node column TNode2ColumnMap::iterator bN_col = myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first; @@ -555,12 +564,14 @@ bool StdMeshers_Prism_3D::projectBottomToTop() // compute bottom node params TNode bN( botNode ); if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE )) - RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed"); + return error(dfltErr(),TCom("Can't compute normalized parameters ") + << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() ); // compute top node coords gp_XYZ topXYZ; gp_XY topUV; if ( !myBlock.FacePoint( ID_TOP_FACE, bN.GetParams(), topXYZ ) || !myBlock.FaceUV ( ID_TOP_FACE, bN.GetParams(), topUV )) - RETURN_BAD_RESULT("SMESH_Block::FacePoint() on the top face failed"); + return error(dfltErr(),TCom("Can't compute coordinates ") + << "by normalized parameters on the face #"<< topSM->GetId() ); SMDS_MeshNode * topNode = meshDS->AddNode( topXYZ.X(),topXYZ.Y(),topXYZ.Z() ); meshDS->SetNodeOnFace( topNode, topFaceID, topUV.X(), topUV.Y() ); // create node column @@ -593,13 +604,13 @@ bool StdMeshers_Prism_3D::projectBottomToTop() if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) - RETURN_BAD_RESULT(" node column for a node not found"); + return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() ); nodes[ i ] = bot_column->second.back(); } else { const TNodeColumn* column = myBlock.GetNodeColumn( n ); if ( !column ) - RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() ); + return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() ); nodes[ i ] = column->back(); } } @@ -711,6 +722,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, SMESH_Block::ID_Fx1z, SMESH_Block::ID_F0yz }; + myError = SMESH_ComputeError::New(); + // ------------------------------------------------------------- // Look for top and bottom faces: not quadrangle ones or meshed // with not quadrangle elements @@ -721,14 +734,13 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, int nbFaces = 0; // SMESH_subMesh* mainSubMesh = myHelper->GetMesh()->GetSubMeshContaining( shape3D ); - if ( !mainSubMesh ) RETURN_BAD_RESULT("Null submesh of shape3D"); + if ( !mainSubMesh ) return error(COMPERR_BAD_INPUT_MESH,"Null submesh of shape3D"); // analyse face submeshes - const map< int, SMESH_subMesh * >& subSM = mainSubMesh->DependsOn(); - map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin(); - for ( ; i_subSM != subSM.end(); ++i_subSM ) + SMESH_subMeshIteratorPtr smIt = mainSubMesh->getDependsOnIterator(false,false); + while ( smIt->more() ) { - SMESH_subMesh* sm = i_subSM->second; + SMESH_subMesh* sm = smIt->next(); const TopoDS_Shape& face = sm->GetSubShape(); if ( face.ShapeType() != TopAbs_FACE ) continue; @@ -760,7 +772,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, notQuadElemSubMesh.push_back( sm ); } else { - RETURN_BAD_RESULT("not meshed face"); + return error(COMPERR_BAD_INPUT_MESH,TCom("Not meshed face #")<GetId()); } // check if a quadrangle face is meshed with a quadranglar grid if ( notQuadGeomSubMesh.back() != sm && @@ -800,9 +812,13 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // detect bad cases if ( nbNotQuad > 0 && nbNotQuad != 2 ) - RETURN_BAD_RESULT("Wrong shape geometry"); + return error(COMPERR_BAD_SHAPE, + TCom("More than 2 not quadrilateral faces") + < 2 ) - RETURN_BAD_RESULT("More then 2 faces meshed with not quadrangle elements"); + return error(COMPERR_BAD_INPUT_MESH, + TCom("More then 2 faces meshed with not quadrangle elements") + < 1 ); - + // ---------------------------------------------------------- if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ? @@ -873,7 +889,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // Load geometry in SMESH_Block if ( !SMESH_Block::FindBlockShapes( shell, Vbot, Vtop, myShapeIDMap )) { if ( !hasNotQuad ) - RETURN_BAD_RESULT("Can not detect top and bottom"); + return error(COMPERR_BAD_SHAPE, "Can't detect top and bottom of a prism"); } else { if ( !botSM ) botSM = Mesh()->GetSubMeshContaining( myShapeIDMap( ID_BOT_FACE )); @@ -927,7 +943,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // Get Wall faces corresponding to the ordered bottom edges list< TopoDS_Face > wallFaces; if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces)) - RETURN_BAD_RESULT("GetWallFaces() failed"); + return error(COMPERR_BAD_SHAPE, "Can't find side faces"); // Find columns of wall nodes and calculate edges' lengths // -------------------------------------------------------- @@ -945,7 +961,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, { TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ]; if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS )) - RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed"); + return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ") + << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt )); SHOWYXZ("\np1 F "<second.front() )); SHOWYXZ("p2 F "<second.front() )); @@ -957,7 +974,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, { SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edgeIt); if ( !smDS ) - RETURN_BAD_RESULT("Null submesh on a bottom edge"); + return error(COMPERR_BAD_INPUT_MESH, TCom("Null submesh on the edge #") + << MeshDS()->ShapeToIndex( *edgeIt )); // assure length uniqueness edgeLength[ iE ] *= smDS->NbNodes() + edgeLength[ iE ] / ( 1000 + iE ); len2edgeMap[ edgeLength[ iE ]] = iE; @@ -970,7 +988,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, { TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ]; if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS )) - RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed"); + return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ") + << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt )); // edge columns int id = MeshDS()->ShapeToIndex( *edgeIt ); bool isForward = true; // meaningless for intenal wires diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index e4e12eb83..55a249570 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -35,6 +35,7 @@ #include "SMESHDS_Mesh.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_MesherHelper.hxx" +#include "SMESH_Comment.hxx" #include #include @@ -114,6 +115,11 @@ public: */ bool Init(SMESH_MesherHelper* helper, const TopoDS_Shape& shape3D); + /*! + * \brief Return problem description + */ + SMESH_ComputeErrorPtr GetError() const { return myError; } + /*! * \brief Return number of nodes on every vertical edge * \retval int - number of nodes including end nodes @@ -342,7 +348,14 @@ private: // to find a column for a node by edge SMESHDS Index map< int, pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap; - + SMESH_ComputeErrorPtr myError; + /*! + * \brief store error and comment and then return ( error == COMPERR_OK ) + */ + bool error(int error, const SMESH_Comment& comment = "") { + myError = SMESH_ComputeError::New(error,comment); + return myError->IsOK(); + } //vector< SMESH_subMesh* > mySubMeshesVec; // submesh by in-block id }; diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index d9c58e9d7..c276b3afa 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1238,7 +1238,7 @@ namespace { HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, - EventListenerData*, SMESH_Hypothesis*) + EventListenerData*, const SMESH_Hypothesis*) { if ( event == SMESH_subMesh::MODIF_HYP && eventType == SMESH_subMesh::ALGO_EVENT) diff --git a/src/StdMeshers/StdMeshers_Projection_1D.cxx b/src/StdMeshers/StdMeshers_Projection_1D.cxx index 571d3990a..1bfdc41c5 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_1D.cxx @@ -41,6 +41,7 @@ #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_Comment.hxx" #include #include @@ -190,7 +191,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh, shape2ShapeMap) ) - RETURN_BAD_RESULT("FindSubShapeAssociation failed"); + return error(dfltErr(),SMESH_Comment("Vertices association failed" )); // ---------------------------------------------- // Assure that mesh on a source edge is computed @@ -201,11 +202,11 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& if ( tgtMesh == srcMesh ) { if ( !TAssocTool::MakeComputed( srcSubMesh )) - RETURN_BAD_RESULT("Impossible to compute the source mesh"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } else { if ( !srcSubMesh->IsMeshComputed() ) - RETURN_BAD_RESULT("Source mesh is not computed"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } // ----------------------------------------------- // Find out nodes distribution on the source edge @@ -216,7 +217,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& vector< double > params; // sorted parameters of nodes on the source edge if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params )) - RETURN_BAD_RESULT("Bad node params on the source edge"); + return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge"); int i, nbNodes = params.size(); @@ -248,20 +249,10 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& vector< const SMDS_MeshNode* > nodes ( nbNodes ); // Get the first and last nodes - // ----------------------------- - - SMESHDS_SubMesh* smV0 = meshDS->MeshElements( tgtV[0] ); - SMESHDS_SubMesh* smV1 = meshDS->MeshElements( tgtV[1] ); - if ( !smV0 || !smV1 ) - RETURN_BAD_RESULT("No submeshes on vertices"); - - SMDS_NodeIteratorPtr nItV0 = smV0->GetNodes(); - SMDS_NodeIteratorPtr nItV1 = smV1->GetNodes(); - if ( !nItV0->more() || !nItV1->more() ) - RETURN_BAD_RESULT("No nodes on vertices"); - - nodes.front() = nItV0->next(); - nodes.back() = nItV1->next(); + nodes.front() = VertexNode( tgtV[0], meshDS ); + nodes.back() = VertexNode( tgtV[1], meshDS ); + if ( !nodes.front() || !nodes.back() ) + return error(COMPERR_BAD_INPUT_MESH,"No node on vertex"); // Compute parameters on the target edge and make internal nodes // -------------------------------------------------------------- @@ -284,7 +275,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // from the point at given parameter. GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] ); if ( !Discret.IsDone() ) - RETURN_BAD_RESULT(" GCPnts_AbscissaPoint failed"); + return error(dfltErr(),"GCPnts_AbscissaPoint failed"); tgtParams[ i ] = Discret.Parameter(); } // make internal nodes @@ -324,7 +315,8 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } // enough nodes to make all edges quadratic? if ( quadratic && ( nbNodes < 3 || ( nbNodes % 2 != 1 ))) - RETURN_BAD_RESULT("Wrong nb nodes to make quadratic mesh"); + return error(COMPERR_BAD_INPUT_MESH, + SMESH_Comment("Wrong number of nodes to make quadratic mesh: ")<& subSM = sm->DependsOn(); - map< int, SMESH_subMesh * >::const_iterator i_sm = subSM.begin(); - for ( ; i_sm != subSM.end(); ++i_sm ) - Clean( i_sm->second ); + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false); + while ( smIt->more() ) + Clean( smIt->next() ); } } }; @@ -386,7 +386,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcFace, srcMesh, shape2ShapeMap) ) - RETURN_BAD_RESULT("FindSubShapeAssociation failed"); + return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" ); // ---------------------------------------------- // Assure that mesh on a source Face is computed @@ -397,11 +397,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& if ( tgtMesh == srcMesh ) { if ( !TAssocTool::MakeComputed( srcSubMesh )) - RETURN_BAD_RESULT("Impossible to compute the source mesh"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } else { if ( !srcSubMesh->IsMeshComputed() ) - RETURN_BAD_RESULT("Source mesh is not computed"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } // -------------------- @@ -412,7 +412,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& SMESH_Pattern mapper; mapper.Load( srcMesh, srcFace ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - RETURN_BAD_RESULT("SMESH_Pattern::Load() failed"); + return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face"); // Find the first target vertex corresponding to first vertex of the // and flag needed to call mapper.Apply() @@ -463,14 +463,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& mapper.Apply( tgtFace, tgtV1, reverse ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - RETURN_BAD_RESULT("SMESH_Pattern::Apply() failed"); + return error(dfltErr(),"Can't apply source mesh pattern to the face"); // Create the mesh const bool toCreatePolygons = false, toCreatePolyedrs = false; mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - RETURN_BAD_RESULT("SMESH_Pattern::MakeMesh() failed"); + return error(dfltErr(),"Can't make mesh by source mesh pattern"); // it will remove mesh built by pattern mapper on edges and vertices // in failure case @@ -487,11 +487,10 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // Make groups of nodes to merge // loop on edge and vertex submeshes of a target face - const map< int, SMESH_subMesh * >& subSM = tgtSubMesh->DependsOn(); - map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin(); - for ( ; i_subSM != subSM.end(); ++i_subSM ) + SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false); + while ( smIt->more() ) { - SMESH_subMesh* sm = i_subSM->second; + SMESH_subMesh* sm = smIt->next(); SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); // Sort new and old nodes of a submesh separately diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index 1d8bce6d8..68eda5d65 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -42,6 +42,7 @@ #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" #include "SMESH_MesherHelper.hxx" +#include "SMESH_Comment.hxx" #include "SMDS_VolumeTool.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" @@ -204,13 +205,15 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) srcShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) - RETURN_BAD_RESULT("There must be 1 shell in the source shape"); + return error(COMPERR_BAD_SHAPE, + SMESH_Comment("Shape must have 1 shell but not") << nbShell); exp.Init( aShape, TopAbs_SHELL ); for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) tgtShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) - RETURN_BAD_RESULT("There must be 1 shell in the target shape"); + return error(COMPERR_BAD_SHAPE, + SMESH_Comment("Shape must have 1 shell but not") << nbShell); // Assure that mesh on a source shape is computed @@ -219,11 +222,11 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) { if ( !TAssocTool::MakeComputed( srcSubMesh )) - RETURN_BAD_RESULT("Impossible to compute the source mesh"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } else { if ( !srcSubMesh->IsMeshComputed() ) - RETURN_BAD_RESULT("Source mesh is not computed"); + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } // Find 2 pairs of corresponding vertices @@ -242,18 +245,18 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS { if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh, shape2ShapeMap) ) - RETURN_BAD_RESULT("FindSubShapeAssociation() failed"); + return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" ); exp.Init( tgtShell, TopAbs_EDGE ); TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 ); if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 )) - RETURN_BAD_RESULT("Shape associating not done"); + return error(dfltErr(),"Association of subshapes failed" ); srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 )); srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 )); if ( !TAssocTool::IsSubShape( srcV000, srcShell ) || !TAssocTool::IsSubShape( srcV100, srcShell )) - RETURN_BAD_RESULT("Wrong target vertices"); + return error(dfltErr(),"Incorrect association of subshapes" ); } // Load 2 SMESH_Block's with src and tgt shells @@ -261,10 +264,10 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS SMESH_Block srcBlock, tgtBlock; TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes; if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes )) - RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(tgtShell) failed"); + return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?"); if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes )) - RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(srcShell) failed"); + return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?"); // Find matching nodes of src and tgt shells @@ -293,9 +296,9 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS TNodeNodeMap faceMatchingNodes; if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, shape2ShapeMap, faceMatchingNodes )) - RETURN_BAD_RESULT("Different mesh on corresponding src and tgt faces: " - << srcMeshDS->ShapeToIndex( srcFace ) << " and " - << tgtMeshDS->ShapeToIndex( tgtFace )); + return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #") + << srcMeshDS->ShapeToIndex( srcFace ) << " and " + << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" ); // put found matching nodes of 2 faces to the global map src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() ); @@ -339,11 +342,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS gp_Pnt srcCoord = gpXYZ( srcNode ); gp_XYZ srcParam; if ( !srcBlock.ComputeParameters( srcCoord, srcParam )) - RETURN_BAD_RESULT("srcBlock.ComputeParameters() failed"); + return error(dfltErr(),SMESH_Comment("Can't compute normalized parameters ") + << "for source node " << srcNode->GetID()); // compute coordinates of target node by srcParam gp_XYZ tgtXYZ; if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ )) - RETURN_BAD_RESULT("tgtBlock.ShellPoint() failed"); + return error(dfltErr(),"Can't compute coordinates by normalized parameters"); // add node SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() ); tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() ); @@ -356,20 +360,21 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS // Create a new volume SMDS_MeshVolume * tgtVol = 0; + int id = 0, force3d = false; switch ( volType ) { case SMDS_VolumeTool::TETRA : case SMDS_VolumeTool::QUAD_TETRA: tgtVol = helper.AddVolume( nodes[0], nodes[1], nodes[2], - nodes[3]); break; + nodes[3], id, force3d); break; case SMDS_VolumeTool::PYRAM : case SMDS_VolumeTool::QUAD_PYRAM: tgtVol = helper.AddVolume( nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4]); break; + nodes[4], id, force3d); break; case SMDS_VolumeTool::PENTA : case SMDS_VolumeTool::QUAD_PENTA: tgtVol = helper.AddVolume( nodes[0], @@ -377,7 +382,7 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS nodes[2], nodes[3], nodes[4], - nodes[5]); break; + nodes[5], id, force3d); break; case SMDS_VolumeTool::HEXA : case SMDS_VolumeTool::QUAD_HEXA : tgtVol = helper.AddVolume( nodes[0], @@ -387,16 +392,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS nodes[4], nodes[5], nodes[6], - nodes[7]); break; + nodes[7], id, force3d); break; default: // polyhedron const SMDS_PolyhedralVolumeOfNodes * poly = dynamic_cast( srcVol ); if ( !poly ) RETURN_BAD_RESULT("Unexpected volume type"); - vector quantities( poly->NbFaces(), 0 ); - for ( int i = 0; i < quantities.size(); ++i ) - quantities[ i ] = poly->NbFaceNodes( i + 1 ); - tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, quantities ); + tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() ); } if ( tgtVol ) { tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() ); diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index 2591d309d..2b701a07a 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -28,93 +28,415 @@ #include "utilities.h" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMDS_SetIterator.hxx" + using namespace std; +namespace { + + // ======================================================================= + /*! + * \brief Listener managing propagation of 1D hypotheses + */ + // ======================================================================= + + class PropagationMgr: public SMESH_subMeshEventListener + { + public: + static PropagationMgr* GetListener(); + /*! + * \brief Set listener on edge submesh + */ + static void Set(SMESH_subMesh * submesh); + /*! + * \brief Return an edge from which hypotheses are propagated from + */ + static TopoDS_Edge GetSource(SMESH_subMesh * submesh); + /*! + * \brief Does it's main job + */ + void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMesh, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp = 0); + private: + PropagationMgr(); + }; +} + //============================================================================= /*! - * + * StdMeshers_Propagation Implementation */ //============================================================================= -StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, - SMESH_Gen * gen) - : SMESH_Hypothesis(hypId, studyId, gen) + +StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen) { _name = GetName(); _param_algo_dim = -1; // 1D auxiliary } - -//============================================================================= +StdMeshers_Propagation::~StdMeshers_Propagation() {} +string StdMeshers_Propagation::GetName () { return "Propagation"; } +ostream & StdMeshers_Propagation::SaveTo (ostream & save) { return save; } +istream & StdMeshers_Propagation::LoadFrom (istream & load) { return load; } +ostream & operator << (ostream & save, StdMeshers_Propagation & hyp) { return hyp.SaveTo(save); } +istream & operator >> (istream & load, StdMeshers_Propagation & hyp) { return hyp.LoadFrom(load); } +bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*, + const TopoDS_Shape& ) { return false; } +void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); } /*! - * + * \brief Return an edge from which hypotheses are propagated from */ -//============================================================================= -StdMeshers_Propagation::~StdMeshers_Propagation() +TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh, + const TopoDS_Shape& theEdge) { + return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge )); } //============================================================================= -/*! - * - */ +//============================================================================= +// PROPAGATION MANAGEMENT +//============================================================================= //============================================================================= -ostream & StdMeshers_Propagation::SaveTo (ostream & save) -{ - return save; -} +namespace { -//============================================================================= -/*! - * - */ -//============================================================================= -istream & StdMeshers_Propagation::LoadFrom (istream & load) -{ - return load; -} + enum SubMeshState { WAIT_PROPAG_HYP, // no propagation hyp in chain + HAS_PROPAG_HYP, // propag hyp on this submesh + IN_CHAIN, // submesh is in propagation chain + LAST_IN_CHAIN, // submesh with local 1D hyp breaking a chain + MEANINGLESS_LAST }; // meaningless -//============================================================================= -/*! - * - */ -//============================================================================= -ostream & operator << (ostream & save, StdMeshers_Propagation & hyp) -{ - return hyp.SaveTo(save); -} + struct PropagationMgrData : public EventListenerData + { + bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge + PropagationMgrData( SubMeshState state ): EventListenerData(true) { + myType = state; + } + SubMeshState State() const { + return (SubMeshState) myType; + } + void SetSource(SMESH_subMesh* sm ) { + mySubMeshes.clear(); if ( sm ) mySubMeshes.push_back( sm ); + } + void SetChain(list< SMESH_subMesh* >& chain ) { + mySubMeshes.clear(); mySubMeshes.splice( mySubMeshes.end(), chain ); + } + SMESH_subMeshIteratorPtr GetChain() const; + SMESH_subMesh* GetSource() const; + }; -//============================================================================= -/*! - * - */ -//============================================================================= -istream & operator >> (istream & load, StdMeshers_Propagation & hyp) -{ - return hyp.LoadFrom(load); -} + //============================================================================= + /*! + * \brief return filter to find Propagation hypothesis + */ + SMESH_HypoFilter & propagHypFilter() + { + static SMESH_HypoFilter propagHypFilter + ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())); + return propagHypFilter; + } + //============================================================================= + /*! + * \brief return static PropagationMgr + */ + PropagationMgr* PropagationMgr::GetListener() + { + static PropagationMgr theListener; + return &theListener; + } + PropagationMgr* getListener() + { + return PropagationMgr::GetListener(); + } + //============================================================================= + /*! + * \brief return PropagationMgrData + */ + PropagationMgrData* getData(SMESH_subMesh* sm) + { + if ( sm ) + return static_cast< PropagationMgrData* >( sm->GetEventListenerData( getListener() )); + return 0; + } + //============================================================================= + /*! + * \brief return PropagationMgrData + */ + PropagationMgrData* getData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge) + { + if ( theEdge.ShapeType() == TopAbs_EDGE ) + return getData( theMesh.GetSubMeshContaining( theEdge ) ); + return 0; + } + //================================================================================ + /*! + * \brief Return an iterator on a chain + */ + SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const + { + typedef SMESH_subMesh* TsubMesh; + typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator; + switch ( State() ) { + case HAS_PROPAG_HYP: + return SMESH_subMeshIteratorPtr + ( new TIterator( mySubMeshes.begin(), mySubMeshes.end() )); + case IN_CHAIN: + case LAST_IN_CHAIN: + if ( mySubMeshes.empty() ) break; + return getData( mySubMeshes.front() )->GetChain(); + default:; + } + return SMESH_subMeshIteratorPtr + ( new TIterator( mySubMeshes.end(), mySubMeshes.end() )); + } + //================================================================================ + /*! + * \brief Return a propagation source submesh + */ + SMESH_subMesh* PropagationMgrData::GetSource() const + { + if ( myType == IN_CHAIN || myType == LAST_IN_CHAIN ) + if ( !mySubMeshes.empty() ) + return mySubMeshes.front(); + return 0; + } + //============================================================================= + /*! + * \brief Returns a local 1D hypothesis used for theEdge + */ + const SMESH_Hypothesis* isLocal1DHypothesis (SMESH_Mesh& theMesh, + const TopoDS_Shape& theEdge) + { + static SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 )); + hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() )); -//============================================================================= -/*! - * GetName - */ -//============================================================================= -std::string StdMeshers_Propagation::GetName () -{ - return "Propagation"; -} -//================================================================================ -/*! - * \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 - */ -//================================================================================ + return theMesh.GetHypothesis( theEdge, hypo, true ); + } + //================================================================================ + /*! + * \brief Build propagation chain + * \param theMainSubMesh - the submesh with Propagation hypothesis + */ + bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh ) + { + // const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape(); +// if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; -bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/, - const TopoDS_Shape& /*theShape*/) -{ - return false; -} +// SMESH_Mesh* mesh = theMainSubMesh->GetFather(); + +// EventListenerData* chainData = new PropagationMgrData(HAS_PROPAG_HYP); +// theMainSubMesh->SetEventListener( getListener(), chainData, theMainSubMesh ); + +// // Edges submeshes, on which the 1D hypothesis will be propagated from +// list & chain = chainData->mySubMeshes; + +// // List of edges, added to chain on the previous cycle pass +// TopTools_ListOfShape listPrevEdges; +// listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD )); + +// // 4____3____2____3____4____5 +// // | | | | | | Number in the each knot of +// // | | | | | | grid indicates cycle pass, +// // 3____2____1____2____3____4 on which corresponding edge +// // | | | | | | (perpendicular to the plane +// // | | | | | | of view) will be found. +// // 2____1____0____1____2____3 +// // | | | | | | +// // | | | | | | +// // 3____2____1____2____3____4 + +// // Collect all edges pass by pass +// while (listPrevEdges.Extent() > 0) { +// // List of edges, added to chain on this cycle pass +// TopTools_ListOfShape listCurEdges; + +// // Find the next portion of edges +// TopTools_ListIteratorOfListOfShape itE (listPrevEdges); +// for (; itE.More(); itE.Next()) { +// TopoDS_Shape anE = itE.Value(); + +// // Iterate on faces, having edge +// TopTools_ListIteratorOfListOfShape itA (mesh->GetAncestors(anE)); +// for (; itA.More(); itA.Next()) { +// TopoDS_Shape aW = itA.Value(); + +// // There are objects of different type among the ancestors of edge +// if (aW.ShapeType() == TopAbs_WIRE) { +// TopoDS_Shape anOppE; + +// BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); +// Standard_Integer nb = 1, found = 0; +// TopTools_Array1OfShape anEdges (1,4); +// for (; aWE.More(); aWE.Next(), nb++) { +// if (nb > 4) { +// found = 0; +// break; +// } +// anEdges(nb) = aWE.Current(); +// if (!_mapAncestors.Contains(anEdges(nb))) { +// MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!"); +// break; +// } +// if (anEdges(nb).IsSame(anE)) found = nb; +// } + +// if (nb == 5 && found > 0) { +// // Quadrangle face found, get an opposite edge +// Standard_Integer opp = ( found + 2 ) % 4; +// anOppE = anEdges(opp); + +// // add anOppE to aChain if ... +// PropagationMgrData* data = getData( *mesh, anOppE ); +// if ( !data || data->State() == WAIT_PROPAG_HYP ) { // ... anOppE is not in any chain +// if ( !isLocal1DHypothesis( *mesh, anOppE )) { // ... no other 1d hyp on anOppE +// // Add found edge to the chain oriented so that to +// // have it co-directed with a forward MainEdge +// TopAbs_Orientation ori = anE.Orientation(); +// if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) +// ori = TopAbs::Reverse( ori ); +// anOppE.Orientation( ori ); +// aChain.Add(anOppE); +// listCurEdges.Append(anOppE); +// } +// else { +// // Collision! +// MESSAGE("Error: Collision between propagated hypotheses"); +// CleanMeshOnPropagationChain(theMainEdge); +// aChain.Clear(); +// return ( aMainHyp == isLocal1DHypothesis(aMainEdgeForOppEdge) ); +// } +// } +// } +// } // if (nb == 5 && found > 0) +// } // if (aF.ShapeType() == TopAbs_WIRE) +// } // for (; itF.More(); itF.Next()) +// } // for (; itE.More(); itE.Next()) + +// listPrevEdges = listCurEdges; +// } // while (listPrevEdges.Extent() > 0) + +// CleanMeshOnPropagationChain(theMainEdge); + return true; + } + //================================================================================ + /*! + * \brief Clear propagation chain + */ + //================================================================================ + + bool clearPropagationChain( SMESH_subMesh* subMesh ) + { + if ( PropagationMgrData* data = getData( subMesh )) { + if ( data->State() == IN_CHAIN ) + return clearPropagationChain( data->GetSource() ); + return true; + } + return false; + } + + + //================================================================================ + /*! + * \brief Constructor + */ + PropagationMgr::PropagationMgr() + : SMESH_subMeshEventListener( false ) // won't be deleted by submesh + {} + //================================================================================ + /*! + * \brief Set PropagationMgr on a submesh + */ + void PropagationMgr::Set(SMESH_subMesh * submesh) + { + EventListenerData* data = EventListenerData::MakeData(submesh,WAIT_PROPAG_HYP); + + submesh->SetEventListener( getListener(), data, submesh ); + + const SMESH_Hypothesis * propagHyp = + submesh->GetFather()->GetHypothesis( submesh->GetSubShape(), propagHypFilter(), true ); + if ( propagHyp ) + getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP, + SMESH_subMesh::ALGO_EVENT, + submesh, + data, + propagHyp); + } + + //================================================================================ + /*! + * \brief React on events on 1D submeshes + */ + //================================================================================ + + void PropagationMgr::ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMesh, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp) + { + if ( !data ) + return; + if ( !hyp || hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO || hyp->GetDim() != 1 ) + return; + if ( eventType != SMESH_subMesh::ALGO_EVENT ) + return; + + bool isPropagHyp = ( StdMeshers_Propagation::GetName() != hyp->GetName() ); + + switch ( data->myType ) { + + case WAIT_PROPAG_HYP: { // no propagation hyp in chain + // -------------------------------------------------------- + if ( !isPropagHyp ) + return; + if ( !isLocal1DHypothesis( *subMesh->GetFather(), subMesh->GetSubShape())) + return; + if ( event == SMESH_subMesh::ADD_HYP || + event == SMESH_subMesh::ADD_FATHER_HYP ) // add propagation hyp + { + // build propagation chain + clearPropagationChain( subMesh ); + buildPropagationChain( subMesh ); + } + return; + } + case HAS_PROPAG_HYP: { // propag hyp on this submesh + // -------------------------------------------------------- + switch ( event ) { + case SMESH_subMesh::REMOVE_HYP: + case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp + if ( isPropagHyp ) + { + // clear propagation chain + } + return; + case SMESH_subMesh::MODIF_HYP: // hyp modif + // clear mesh in a chain + return; + } + return; + } + case IN_CHAIN: { // submesh is in propagation chain + // -------------------------------------------------------- + if ( event == SMESH_subMesh::ADD_HYP ) // add local hypothesis + if ( isPropagHyp ) + ; // collision + else + ; // rebuild propagation chain + return; + } + case LAST_IN_CHAIN: { // submesh with local 1D hyp, breaking a chain + // -------------------------------------------------------- + if ( event == SMESH_subMesh::REMOVE_HYP ) // remove local hyp + ; // rebuild propagation chain + return; + } + } // switch by SubMeshState + } +} // namespace diff --git a/src/StdMeshers/StdMeshers_Propagation.hxx b/src/StdMeshers/StdMeshers_Propagation.hxx index 40bbdff2d..fb350a7d2 100644 --- a/src/StdMeshers/StdMeshers_Propagation.hxx +++ b/src/StdMeshers/StdMeshers_Propagation.hxx @@ -28,8 +28,18 @@ #define _SMESH_PROPAGATION_HXX_ #include "SMESH_Hypothesis.hxx" +#include "SMESH_subMeshEventListener.hxx" #include "Utils_SALOME_Exception.hxx" +#include + + +// ======================================================================= +/*! + * \brief Propagation hypothesis + */ +// ======================================================================= + class StdMeshers_Propagation:public SMESH_Hypothesis { public: @@ -43,6 +53,22 @@ class StdMeshers_Propagation:public SMESH_Hypothesis static std::string GetName (); + /*! + * \brief Set EventListener managing propagation of hypotheses + * \param subMesh - edge submesh to set event listener on + * + * 1D algo is expected to call this method from it's SetEventListener() + */ + static void SetPropagationMgr(SMESH_subMesh* subMesh); + + /*! + * \brief Return an edge from which hypotheses are propagated from + * \param theMesh - mesh + * \param theEdge - edge to which hypotheses are propagated + * \retval TopoDS_Edge - source edge, also passing orientation + */ + static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge); + /*! * \brief Initialize my parameter values by the mesh built on the geometry * \param theMesh - the built mesh @@ -53,5 +79,4 @@ class StdMeshers_Propagation:public SMESH_Hypothesis */ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); }; - #endif diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 589ca5267..0b0d057ed 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -36,6 +36,7 @@ #include "SMESH_subMesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_Block.hxx" +#include "SMESH_Comment.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -74,6 +75,7 @@ DEFINE_ARRAY2(StdMeshers_Array2OfNode, using namespace std; typedef gp_XY gp_UV; +typedef SMESH_Comment TComm; //============================================================================= /*! @@ -573,7 +575,7 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes list< int > nbEdgesInWire; int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); if (nbWire != 1) { - INFOS("only 1 wire by face (quadrangles)"); + error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire); return 0; } FaceQuadStruct* quad = new FaceQuadStruct; @@ -623,9 +625,8 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes cout << ")"; } cout << endl; -#else - INFOS("face must have 4 edges / quadrangle"); #endif + error(COMPERR_BAD_SHAPE, TComm("Face must have 4 side but not ") << nbSides); delete quad; quad = 0; } @@ -668,7 +669,6 @@ faceQuadStruct::~faceQuadStruct() { for (int i = 0; i < side.size(); i++) { if (side[i]) delete side[i]; - //if (uv_edges[i]) delete [] uv_edges[i]; } if (uv_grid) delete [] uv_grid; } @@ -676,7 +676,7 @@ faceQuadStruct::~faceQuadStruct() namespace { inline const vector& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg) { - bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE ); + bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE ); double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1; return quad->isEdgeOut[i] ? @@ -735,10 +735,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, const vector& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 ); const vector& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 ); - if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) { - MESSAGE("Nodes from edges not loaded"); - return false; - } + if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) + return error(dfltErr(), "Can't find nodes on sides"); // nodes Id on "in" edges if (! quad->isEdgeOut[0]) { @@ -876,25 +874,19 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; - //cout<<"x0="<ShapeToIndex( outFace )); + return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" ) + << meshDS->ShapeToIndex( outFace )); } else { inFace = TopoDS::Face( shape2ShapeMap( outFace )); } @@ -201,9 +202,10 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a TNodeNodeMap nodeIn2OutMap; if ( ! TAssocTool::FindMatchingNodesOnFaces( inFace, &aMesh, outFace, &aMesh, shape2ShapeMap, nodeIn2OutMap )) - RETURN_BAD_RESULT("Different mesh on corresponding out and in faces: " - << meshDS->ShapeToIndex( outFace ) << " and " - << meshDS->ShapeToIndex( inFace )); + return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #") + << meshDS->ShapeToIndex( outFace ) << " and " + << meshDS->ShapeToIndex( inFace ) << " seems different" ); + // Create volumes SMDS_ElemIteratorPtr faceIt = meshDS->MeshElements( inFace )->GetElements(); @@ -252,9 +254,10 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap& n2C SMESHDS_Mesh * meshDS = myHelper->GetMeshDS(); int shapeID = myHelper->GetSubShapeID(); - if ( myLayerPositions.empty() ) - computeLayerPositions( gpXYZ( inNode ), gpXYZ( outNode )); - + if ( myLayerPositions.empty() ) { + gp_Pnt pIn = gpXYZ( inNode ), pOut = gpXYZ( outNode ); + computeLayerPositions( pIn, pOut ); + } int nbSegments = myLayerPositions.size() + 1; TNode2ColumnMap::iterator n_col = @@ -287,7 +290,7 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap& n2C //================================================================================ //================================================================================ -class TNodeDistributor: private StdMeshers_Regular_1D +class TNodeDistributor: public StdMeshers_Regular_1D { list myUsedHyps; public: @@ -309,23 +312,24 @@ public: const StdMeshers_LayerDistribution* hyp) { double len = pIn.Distance( pOut ); - if ( len <= DBL_MIN ) RETURN_BAD_RESULT("Bad points"); + if ( len <= DBL_MIN ) return error(dfltErr(),"Too close points of inner and outer shells"); if ( !hyp || !hyp->GetLayerDistribution() ) - RETURN_BAD_RESULT("Bad StdMeshers_LayerDistribution hypothesis"); + return error(dfltErr(), "Invalid LayerDistribution hypothesis"); myUsedHyps.clear(); myUsedHyps.push_back( hyp->GetLayerDistribution() ); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut ); SMESH_Hypothesis::Hypothesis_Status aStatus; if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus )) - RETURN_BAD_RESULT("StdMeshers_Regular_1D::CheckHypothesis() failed with status "< params; if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false )) - RETURN_BAD_RESULT("StdMeshers_Regular_1D::computeInternalParameters() failed"); + return error(dfltErr(),"StdMeshers_Regular_1D failed to compute layers distribution"); positions.clear(); positions.reserve( params.size() ); @@ -355,7 +359,8 @@ protected: */ //================================================================================ -bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut) +bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn, + const gp_Pnt& pOut) { if ( myNbLayerHypo ) { @@ -367,8 +372,12 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut) } if ( myDistributionHypo ) { SMESH_Mesh * mesh = myHelper->GetMesh(); - return TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut, - *mesh, myDistributionHypo ); + if ( !TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut, + *mesh, myDistributionHypo )) + { + error( TNodeDistributor::GetDistributor(*mesh)->GetComputeError() ); + return false; + } } - RETURN_BAD_RESULT("Bad hypothesis"); + RETURN_BAD_RESULT("Bad hypothesis"); } diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx index 4c604ea32..0bedb6a30 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx @@ -36,6 +36,7 @@ class StdMeshers_NumberOfLayers; class StdMeshers_LayerDistribution; class SMESH_MesherHelper; +class gp_Pnt; class StdMeshers_RadialPrism_3D: public SMESH_3D_Algo { @@ -58,7 +59,8 @@ protected: const SMDS_MeshNode* outNode, const SMDS_MeshNode* inNode); - bool computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut); + bool computeLayerPositions(const gp_Pnt& pIn, + const gp_Pnt& pOut); const StdMeshers_NumberOfLayers* myNbLayerHypo; diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 2f13e3283..9e59aa0c6 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -43,6 +43,7 @@ #include "SMESH_HypoFilter.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" +#include "SMESH_Comment.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -59,11 +60,7 @@ #include #include -#include -#include - #include -//#include using namespace std; @@ -376,25 +373,25 @@ static void compensateError(double a1, double an, */ //================================================================================ -struct VertexEventListener : public SMESH_subMeshEventListener -{ - VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh - {} - /*! - * \brief Clean mesh on edges - * \param event - algo_event or compute_event itself (of SMESH_subMesh) - * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh) - * \param subMesh - the submesh where the event occures - */ - void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, - EventListenerData*, SMESH_Hypothesis*) - { - if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events - { - subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE ); - } - } -}; // struct VertexEventListener +// struct VertexEventListener : public SMESH_subMeshEventListener +// { +// VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh +// {} +// /*! +// * \brief Clean mesh on edges +// * \param event - algo_event or compute_event itself (of SMESH_subMesh) +// * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh) +// * \param subMesh - the submesh where the event occures +// */ +// void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, +// EventListenerData*, const SMESH_Hypothesis*) +// { +// if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events +// { +// subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE ); +// } +// } +// }; // struct VertexEventListener //============================================================================= /*! @@ -408,13 +405,11 @@ struct VertexEventListener : public SMESH_subMeshEventListener void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh) { - static VertexEventListener listener; - const map < int, SMESH_subMesh * >& vSMs = subMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator itsub; - for (itsub = vSMs.begin(); itsub != vSMs.end(); itsub++) - { - subMesh->SetEventListener( &listener, 0, itsub->second ); - } +// static VertexEventListener listener; +// SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); +// while (smIt->more()) { +// subMesh->SetEventListener( &listener, 0, smIt->next() ); +// } } //============================================================================= @@ -440,9 +435,15 @@ const StdMeshers_SegmentLengthAroundVertex* StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh & theMesh, const TopoDS_Vertex & theV) { - static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentLengthAroundVertex")); - const SMESH_Hypothesis * hyp = theMesh.GetHypothesis( theV, filter, true ); - return static_cast( hyp ); + static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D")); + if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true )) + { + SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h )); + const list & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 ); + if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() ) + return static_cast( hypList.front() ); + } + return 0; } //================================================================================ @@ -461,7 +462,7 @@ void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh & theM double theLength, std::list< double > & theParameters, const TopoDS_Vertex & theVf, - const TopoDS_Vertex & theVl) const + const TopoDS_Vertex & theVl) { double f = theC3d.FirstParameter(), l = theC3d.LastParameter(); int nPar = theParameters.size(); @@ -546,7 +547,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d, double theFirstU, double theLastU, list & theParams, - const bool theReverse) const + const bool theReverse) { theParams.clear(); @@ -626,7 +627,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d, } GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l); if ( !Discret.IsDone() ) - return false; + return error( dfltErr(), "GCPnts_UniformAbscissa failed"); int NbPoints = Discret.NbPoints(); for ( int i = 2; i < NbPoints; i++ ) @@ -731,8 +732,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d, bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) { - //MESSAGE("StdMeshers_Regular_1D::Compute"); - if ( _hypType == NONE ) return false; @@ -749,38 +748,25 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l ASSERT(!VFirst.IsNull()); - const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); - if (!idFirst) { - MESSAGE (" NO NODE BUILT ON VERTEX "); - return false; - } - ASSERT(!VLast.IsNull()); + const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if (!idLast) { - MESSAGE (" NO NODE BUILT ON VERTEX "); - return false; - } + if (!idFirst || !idLast) + return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); - if (!Curve.IsNull()) { + if (!Curve.IsNull()) + { list< double > params; bool reversed = false; if ( !_mainEdge.IsNull() ) reversed = aMesh.IsReversedInChain( EE, _mainEdge ); + BRepAdaptor_Curve C3d( E ); double length = EdgeLength( E ); - try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 - OCC_CATCH_SIGNALS; -#endif - if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) { - return false; - } - redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast ); - } - catch ( Standard_Failure ) { + if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) { return false; } + redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast ); // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex) // only internal nodes receive an edge position with param on curve diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index f0e82262d..b5bae5877 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -76,14 +76,14 @@ protected: double theFirstU, double theLastU, std::list< double > & theParameters, - const bool theReverse) const; + const bool theReverse); virtual void redistributeNearVertices (SMESH_Mesh & theMesh, Adaptor3d_Curve & theC3d, double theLength, std::list< double > & theParameters, const TopoDS_Vertex & theVf, - const TopoDS_Vertex & theVl) const; + const TopoDS_Vertex & theVl); /*! * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex