X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Prism_3D.cxx;h=6d28721e3246bbfd1dd45bb366f8a4ebca28a134;hb=55138dfa2581fbdfbffcb4f49ab35e7f0e769a2e;hp=dd2c271d5992b6999e738384e4a00e88539ad942;hpb=8439462bf49c859d3430637a1cb00fb180a2af8c;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index dd2c271d5..6d28721e3 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, @@ -99,7 +101,7 @@ namespace { const SMDS_MeshNode* & node1, const SMDS_MeshNode* & node2) { - if ( param == 1.0 || column->size() == 1) { + if ( param >= 1.0 || column->size() == 1) { node1 = node2 = column->back(); return 0; } @@ -183,7 +185,7 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh& a SMESH_Hypothesis::Hypothesis_Status& aStatus) { // Check shape geometry - +/* PAL16229 aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY; // find not quadrangle faces @@ -214,7 +216,7 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh& a if ( nbFace != nbEdge + 2 ) RETURN_BAD_RESULT("Bad nb of faces: " << nbFace << " but must be " << nbEdge + 2); } - +*/ // no hypothesis aStatus = SMESH_Hypothesis::HYP_OK; return true; @@ -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(); @@ -274,15 +275,20 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh TNodeColumn& column = bot_column->second; // bottom node parameters and coords - gp_XYZ botParams = tBotNode.GetParams(); myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords(); + gp_XYZ botParams = tBotNode.GetParams(); // compute top node parameters - gp_XYZ topParams; 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"); + gp_XYZ topParams = botParams; + topParams.SetZ( 1 ); + if ( column.size() > 2 ) { + gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; + if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams )) + return error(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 +314,11 @@ 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("Can't compute coordinates by normalized parameters"); + + SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]); + SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode)); + SHOWYXZ("ShellPoint ",coords); // create a node node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); @@ -320,7 +330,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 +351,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(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(TCom("No side nodes found above node ") << n->GetID() ); } } // create prisms @@ -373,12 +383,44 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, int shapeID = helper->GetSubShapeID(); int nbNodes = columns.size(); + int nbZ = columns[0]->size(); + if ( nbZ < 2 ) return; + + // find out orientation + bool isForward = true; + SMDS_VolumeTool vTool; + int z = 1; + switch ( nbNodes ) { + case 3: { + const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1], + (*columns[1])[z-1], + (*columns[2])[z-1] }; + const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], + (*columns[1])[z], + (*columns[2])[z] }; + SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], + topNodes[0], topNodes[1], topNodes[2]); + vTool.Set( &tmpVol ); + isForward = vTool.IsForward(); + break; + } + case 4: { + const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1], + (*columns[2])[z-1], (*columns[3])[z-1] }; + const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], + (*columns[2])[z], (*columns[3])[z] }; + SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3], + topNodes[0], topNodes[1], topNodes[2], topNodes[3]); + vTool.Set( &tmpVol ); + isForward = vTool.IsForward(); + break; + } + } // vertical loop on columns - for ( int z = 1; z < columns[0]->size(); ++z) + for ( z = 1; z < nbZ; ++z ) { SMDS_MeshElement* vol = 0; - SMDS_VolumeTool vTool; switch ( nbNodes ) { case 3: { @@ -388,11 +430,7 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], (*columns[1])[z], (*columns[2])[z] }; - // assure good orientation - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], - topNodes[0], topNodes[1], topNodes[2]); - vTool.Set( &tmpVol ); - if ( vTool.IsForward() ) + if ( isForward ) vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], topNodes[0], topNodes[1], topNodes[2]); else @@ -405,11 +443,7 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, (*columns[2])[z-1], (*columns[3])[z-1] }; const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], (*columns[2])[z], (*columns[3])[z] }; - // assure good orientation - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3], - topNodes[0], topNodes[1], topNodes[2], topNodes[3]); - vTool.Set( &tmpVol ); - if ( vTool.IsForward() ) + if ( isForward ) vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], botNodes[3], topNodes[0], topNodes[1], topNodes[2], topNodes[3]); else @@ -459,7 +493,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS(); if ( !botSMDS || botSMDS->NbElements() == 0 ) - RETURN_BAD_RESULT("Empty horiz submesh"); + return error(TCom("No elememts on face #") << botSM->GetId()); bool needProject = false; if ( !topSMDS || @@ -467,12 +501,15 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() botSMDS->NbNodes() != topSMDS->NbNodes()) { if ( myBlock.HasNotQuadElemOnTop() ) - RETURN_BAD_RESULT("Different triangles on 2 sides"); + return error(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(TCom("Mesh on faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); + ///RETURN_BAD_RESULT("Need to project but not allowed"); if ( needProject ) { @@ -486,18 +523,21 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(), topFace, myBlock.Mesh(), shape2ShapeMap) ) - RETURN_BAD_RESULT("FindSubShapeAssociation failed"); + return error(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(TCom("Mesh on faces #") << botSM->GetId() + <<" and #"<< topSM->GetId() << " seems different" ); // Fill myBotToColumnMap int zSize = myBlock.VerticalSize(); + TNode prevTNode; TNodeNodeMap::iterator bN_tN = n2nMap.begin(); for ( ; bN_tN != n2nMap.end(); ++bN_tN ) { @@ -507,8 +547,16 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() continue; // wall columns are contained in myBlock // 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"); + if ( zSize > 2 ) { + gp_XYZ paramHint(-1,-1,-1); + if ( prevTNode.IsNeighbor( bN )) + paramHint = prevTNode.GetParams(); + if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), + ID_BOT_FACE, paramHint )) + return error(TCom("Can't compute normalized parameters for node ") + << botNode->GetID() << " on the face #"<< botSM->GetId() ); + prevTNode = bN; + } // create node column TNode2ColumnMap::iterator bN_col = myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first; @@ -546,6 +594,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop() // Fill myBotToColumnMap int zSize = myBlock.VerticalSize(); + TNode prevTNode; SMDS_NodeIteratorPtr nIt = botSMDS->GetNodes(); while ( nIt->more() ) { @@ -554,13 +603,20 @@ bool StdMeshers_Prism_3D::projectBottomToTop() continue; // strange // 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"); + gp_XYZ paramHint(-1,-1,-1); + if ( prevTNode.IsNeighbor( bN )) + paramHint = prevTNode.GetParams(); + if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), + ID_BOT_FACE, paramHint )) + return error(TCom("Can't compute normalized parameters for node ") + << botNode->GetID() << " on the face #"<< botSM->GetId() ); + prevTNode = bN; // 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(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 +649,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(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(TCom("No side nodes found above node ") << n->GetID() ); nodes[ i ] = column->back(); } } @@ -662,6 +718,23 @@ bool StdMeshers_Prism_3D::setFaceAndEdgesXYZ( const int faceID, const gp_XYZ& pa return true; } +//================================================================================ +/*! + * \brief Return true if this node and other one belong to one face + */ +//================================================================================ + +bool TNode::IsNeighbor( const TNode& other ) const +{ + if ( !other.myNode || !myNode ) return false; + + SMDS_ElemIteratorPtr fIt = other.myNode->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + if ( fIt->next()->GetNodeIndex( myNode ) >= 0 ) + return true; + return false; +} + //================================================================================ /*! * \brief Constructor. Initialization is needed @@ -711,6 +784,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 +796,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 +834,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 +874,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 than 2 faces with not quadrangle elements: ") + < 1 ); - + // ---------------------------------------------------------- if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ? @@ -873,7 +951,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 +1005,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 +1023,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 +1036,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 +1050,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 @@ -1123,7 +1204,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, SMESH_Block::TFace& tFace = myFace[ fID - ID_FirstF ]; tFace.Set( fID, sideFace->Surface(), pcurves, isForward ); - SHOWYXZ( endl<<"F "<< iF << " id " << fID << " FRW " << sideFace->IsForward(), ); + SHOWYXZ( endl<<"F "<< iF << " id " << fID << " FRW " << sideFace->IsForward(), sideFace->Value(0,0)); // edges 3D geometry vector< int > edgeIdVec; SMESH_Block::GetFaceEdgesIDs( fID, edgeIdVec );