#include "SMESH_HypoFilter.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
+typedef SMESH_Comment TComm;
+
using namespace std;
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 );
{
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 );
+ }
}
}
}
// 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 ")
+ <<meshDS->ShapeToIndex(VFirst));
+ if (!nLast)
+ return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+ <<meshDS->ShapeToIndex(VLast));
+
vector<const SMDS_MeshNode*> nodes( nbNodes, (const SMDS_MeshNode*)0 );
nodes.front() = nFirst;
nodes.back() = nLast;
}
// 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 );
}
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-//#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Surface.hxx>
-// #include <Geom_Curve.hxx>
-// #include <Geom2d_Curve.hxx>
-// #include <Handle_Geom2d_Curve.hxx>
-// #include <Handle_Geom_Curve.hxx>
#include <gp_Pnt2d.hxx>
#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 &);
//=============================================================================
/*!
*/
//=============================================================================
-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";
*/
//=============================================================================
-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");
// 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()) {
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);
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();
}
}
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);
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
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);
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];
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
// 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();
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,
}
}
if ( np ) delete [] np;
- //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
return ClearAndReturn( aQuads, true );
}
*/
//=============================================================================
-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;
//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;
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;
}
#include "SMESH_subMesh.hxx"
#include "SMESH_Block.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
#include "StdMeshers_FaceSide.hxx"
#include "StdMeshers_MaxElementArea.hxx"
TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
// helper builds quadratic mesh if necessary
- myTool = new SMESH_MesherHelper(aMesh);
- auto_ptr<SMESH_MesherHelper> helperDeleter( myTool );
+ SMESH_MesherHelper helper(aMesh);
+ myTool = &helper;
_quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
const bool ignoreMediumNodes = _quadraticMesh;
{
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);
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")<<wires[0]->NbSegments());
if (_hypLengthFromEdges && _edgeLength < DBL_MIN )
_edgeLength = 100;
}
else
{
- MESSAGE("Error in Triangulation");
+ error(ierr,"Error in Triangulation (aptrte())");
}
}
if (nudslf != NULL) delete[]nudslf;
{
const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
- MESSAGE("Wrong nb UVPtStruct: "<<uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
- return false;
+ return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
+ << iW << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
}
if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
- return false;
+ return error(dfltErr(),"Internal error");
}
vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
#include "SMESH_MeshEditor.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
//purpose :
//=======================================================================
StdMeshers_Penta_3D::StdMeshers_Penta_3D()
-: myErrorStatus(1)
+: myErrorStatus(SMESH_ComputeError::New())
{
myTol3D=0.1;
myWallNodesMaps.resize( SMESH_Block::NbFaces() );
StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
{
- if ( myTool )
- delete myTool;
}
//=======================================================================
{
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;
}
//=======================================================================
void StdMeshers_Penta_3D::MakeNodes()
{
- myErrorStatus=0;
- //
const int aNbSIDs=9;
int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
double aX, aY, aZ;
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
"SMESHBlock: ComputeParameters operation failed");
- myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+ myErrorStatus=myBlock.GetError();
return;
}
aTNode.SetNormCoord(aCoords);
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;
}
}
//
// suporting shape ID
ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
return;
}
meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
}
}
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
return;
}
const int z,
StdMeshers_TNode& aTN)
{
- myErrorStatus=0;
- //
double aX, aY, aZ, aD, aTol2, minD;
gp_Pnt aP1, aP2;
//
//=======================================================================
void StdMeshers_Penta_3D::MakeVolumeMesh()
{
- myErrorStatus=0;
- //
int i, j, ij, ik, i1, i2, aSSID;
//
SMESH_Mesh* pMesh = GetMesh();
continue;
aID0 = pNode->GetID();
aJ[k] = GetIndexOnLayer(aID0);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
return;
}
//=======================================================================
void StdMeshers_Penta_3D::MakeMeshOnFxy1()
{
- myErrorStatus=0;
- //
int aID0, aJ, aLevel, ij, aNbNodes, k;
//
SMDS_NodeIteratorPtr itn;
k = aNbNodes-1; // reverse a face
aItNodes = pE0->nodesIterator();
while (aItNodes->more()) {
- //const SMDS_MeshElement* pNode = aItNodes->next();
const SMDS_MeshNode* pNode =
static_cast<const SMDS_MeshNode*> (aItNodes->next());
if(myTool->IsMedium(pNode))
continue;
aID0 = pNode->GetID();
aJ = GetIndexOnLayer(aID0);
- if (myErrorStatus) {
+ if (!myErrorStatus->IsOK()) {
MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
return;
}
//=======================================================================
void StdMeshers_Penta_3D::ClearMeshOnFxy1()
{
- myErrorStatus=0;
- //
SMESH_subMesh* aSubMesh;
SMESH_Mesh* pMesh=GetMesh();
//
//=======================================================================
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;
const gp_XYZ& aParams,
StdMeshers_TNode& aTN)
{
- myErrorStatus=0;
- //
- // int iErr;
double aX, aY, aZ;
//
gp_Pnt aP;
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;
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;
//=======================================================================
void StdMeshers_Penta_3D::MakeBlock()
{
- myErrorStatus=0;
- //
bool bFound;
int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
//
}
}
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;
}
}
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 #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aFTr )<<": "<<iNbE<<" edges" ;
return;
}
const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
iNbEV=aMEV.Extent();
if (iNbEV!=3){
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=7; // too few edges meet in base vertex
+ myErrorStatus->myName=7; // too few edges meet in base vertex
+ myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<<iNbEV<<" edges";
return;
}
//
//
if (!bFound) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=8; // can not find reper V001
+ myErrorStatus->myName=8; // can not find reper V001
+ myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #")
+ <<pMesh->GetMeshDS()->ShapeToIndex( aV000 );
return;
}
//DEB
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 ")<<iNbE;
return;
}
//
iErr = myBlock.ErrorStatus();
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
- myErrorStatus=100; // SMESHBlock: Load operation failed
+ myErrorStatus=myBlock.GetError(); // SMESHBlock: Load operation failed
return;
}
}
//=======================================================================
void StdMeshers_Penta_3D::CheckData()
{
- myErrorStatus=0;
- //
int i, iNb;
int iNbEx[]={8, 12, 6};
//
//
if (myShape.IsNull()){
MESSAGE("StdMeshers_Penta_3D::CheckData() ");
- myErrorStatus=2; // null shape
+ myErrorStatus->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) ")<<aST;
return;
}
//
iNb=aM.Extent();
if (iNb!=iNbEx[i]){
MESSAGE("StdMeshers_Penta_3D::CheckData() ");
- myErrorStatus=4; // number of subshape is not compatible
+ myErrorStatus->myName=4; // number of subshape is not compatible
+ myErrorStatus->myComment="Wrong number of subshapes of a block";
return;
}
}
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 :
myShapeIDMap.Clear();
bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
if (!bOk) {
- myErrorStatus=2;
+ myErrorStatus=6;
return;
}
}
}
}
if (!bOk) {
- myErrorStatus=4; // problems with point computation
+ myErrorStatus=5; // problems with point computation
return;
}
aP3D.SetXYZ(aXYZ);
#include <TColStd_MapOfInteger.hxx>
#include "SMESH_Block.hxx"
-
+#include "SMESH_ComputeError.hxx"
#include "SMESH_MesherHelper.hxx"
typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
int ErrorStatus() const;
+ SMESH_ComputeErrorPtr GetError() const;
+
protected:
TopoDS_Shell myShell;
bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
int ErrorStatus() const {
+ if (myErrorStatus->IsOK())
+ return 0;
+ return myErrorStatus->myName;
+ }
+
+ SMESH_ComputeErrorPtr GetComputeError() const {
return myErrorStatus;
}
TopoDS_Shape myShape;
StdMeshers_SMESHBlock myBlock;
void * myMesh;
- int myErrorStatus;
+ SMESH_ComputeErrorPtr myErrorStatus;
//
vector <StdMeshers_TNode> myTNodes;
int myISize;
#include "SMDS_VolumeTool.hxx"
#include "SMDS_VolumeOfNodes.hxx"
#include "SMDS_EdgePosition.hxx"
+#include "SMESH_Comment.hxx"
#include "utilities.h"
// }
typedef StdMeshers_ProjectionUtils TAssocTool;
+typedef SMESH_Comment TCom;
enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0,
ID_TOP_FACE = SMESH_Block::ID_Fxy1,
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<SMESH_MesherHelper> 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();
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();
// 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() );
// 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();
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
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 ||
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 )
{
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
// 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;
// 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
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();
}
}
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
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;
notQuadElemSubMesh.push_back( sm );
}
else {
- RETURN_BAD_RESULT("not meshed face");
+ return error(COMPERR_BAD_INPUT_MESH,TCom("Not meshed face #")<<sm->GetId());
}
// check if a quadrangle face is meshed with a quadranglar grid
if ( notQuadGeomSubMesh.back() != sm &&
// 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")
+ <<nbNotQuad);
if ( nbNotQuadMeshed > 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")
+ <<nbNotQuadMeshed);
// get found submeshes
if ( hasNotQuad )
else
ok = ( notQuadGeomSubMesh == notQuadElemSubMesh );
if ( !ok )
- RETURN_BAD_RESULT("Side face meshed with not quadrangle elements");
+ return error(COMPERR_BAD_INPUT_MESH, "Side face meshed with not quadrangle elements");
}
myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
-
+
// ----------------------------------------------------------
if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ?
// 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 ));
// 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
// --------------------------------------------------------
{
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 "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
{
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;
{
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
#include "SMESHDS_Mesh.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
#include <vector.h>
#include <map.h>
*/
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
// 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
};
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)
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen.hxx"
+#include "SMESH_Comment.hxx"
#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
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
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
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();
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
// --------------------------------------------------------------
// 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
}
// 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: ")<<nbNodes);
// Create edges
// -------------
#include "SMESH_Pattern.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_EdgePosition.hxx"
#include "utilities.h"
// do not break but iterate over DependsOn()
}
default:
- const map< int, SMESH_subMesh * >& 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() );
}
}
};
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
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");
}
// --------------------
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 <mapper>
// and <theReverse> flag needed to call mapper.Apply()
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
// 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
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
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
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
{
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
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
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() );
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() );
// 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],
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],
nodes[4],
nodes[5],
nodes[6],
- nodes[7]); break;
+ nodes[7], id, force3d); break;
default: // polyhedron
const SMDS_PolyhedralVolumeOfNodes * poly =
dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
if ( !poly )
RETURN_BAD_RESULT("Unexpected volume type");
- vector<int> 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() );
#include "utilities.h"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMDS_SetIterator.hxx"
+
using namespace std;
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId,
- SMESH_Gen * gen)
- : SMESH_Hypothesis(hypId, studyId, gen)
-{
- _name = GetName();
- _param_algo_dim = -1; // 1D auxiliary
-}
+namespace {
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::~StdMeshers_Propagation()
-{
+ // =======================================================================
+ /*!
+ * \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
*/
//=============================================================================
-ostream & StdMeshers_Propagation::SaveTo (ostream & save)
+StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Gen * gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
{
- return save;
+ _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
*/
-//=============================================================================
-istream & StdMeshers_Propagation::LoadFrom (istream & load)
+TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theEdge)
{
- return load;
+ return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
}
//=============================================================================
-/*!
- *
- */
//=============================================================================
-ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)
-{
- return hyp.SaveTo(save);
-}
-
+// PROPAGATION MANAGEMENT
//=============================================================================
-/*!
- *
- */
//=============================================================================
-istream & operator >> (istream & load, StdMeshers_Propagation & hyp)
-{
- return hyp.LoadFrom(load);
-}
-//=============================================================================
-/*!
- * 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
- */
-//================================================================================
+namespace {
-bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
- const TopoDS_Shape& /*theShape*/)
-{
- return false;
-}
+ 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
+
+ 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;
+ };
+
+ //=============================================================================
+ /*!
+ * \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() ));
+
+ 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;
+
+// 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 <theMainEdge>
+// list<SMESH_subMesh*> & 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 <anE>
+// 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
#define _SMESH_PROPAGATION_HXX_
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMeshEventListener.hxx"
#include "Utils_SALOME_Exception.hxx"
+#include <TopoDS_Edge.hxx>
+
+
+// =======================================================================
+/*!
+ * \brief Propagation hypothesis
+ */
+// =======================================================================
+
class StdMeshers_Propagation:public SMESH_Hypothesis
{
public:
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
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
};
-
#endif
#include "SMESH_subMesh.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
using namespace std;
typedef gp_XY gp_UV;
+typedef SMESH_Comment TComm;
//=============================================================================
/*!
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;
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;
}
{
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;
}
namespace {
inline const vector<UVPtStruct>& 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] ?
const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
const vector<UVPtStruct>& 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]) {
uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
- //cout<<"x0="<<x0<<" x1="<<x1<<" y0="<<y0<<" y1="<<y1<<endl;
- //cout<<"x="<<x<<" y="<<y<<endl;
- //cout<<"param_b="<<param_b<<" param_t="<<param_t<<" param_r="<<param_r<<" param_l="<<param_l<<endl;
- //cout<<"u="<<u<<" v="<<v<<endl;
-
return uv;
}
-//=======================================================================
-//function : ComputeQuadPref
-//purpose :
//=======================================================================
/*!
- * Special function for creation only quandrangle faces
+ * Create only quandrangle faces
*/
-bool StdMeshers_Quadrangle_2D::ComputeQuadPref
- (SMESH_Mesh & aMesh,
- const TopoDS_Shape& aShape,
- FaceQuadStruct* quad) throw (SALOME_Exception)
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh,
+ const TopoDS_Shape& aShape,
+ FaceQuadStruct* quad)
+ throw (SALOME_Exception)
{
Unexpect aCatch(SalomeException);
if ( !outerShell.IsSame( It.Value() ))
innerShell = It.Value();
if ( nbShells != 2 )
- RETURN_BAD_RESULT("Must be 2 shells");
+ return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not")<<nbShells);
// ----------------------------------
// Associate subshapes of the shells
if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
innerShell, &aMesh,
shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
// ------------------
// Make mesh
TopoDS_Face outFace = TopoDS::Face( exp.Current() );
TopoDS_Face inFace;
if ( !shape2ShapeMap.IsBound( outFace )) {
- RETURN_BAD_RESULT("Association not found for face " << meshDS->ShapeToIndex( outFace ));
+ return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" )
+ << meshDS->ShapeToIndex( outFace ));
} else {
inFace = TopoDS::Face( shape2ShapeMap( outFace ));
}
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();
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 =
//================================================================================
//================================================================================
-class TNodeDistributor: private StdMeshers_Regular_1D
+class TNodeDistributor: public StdMeshers_Regular_1D
{
list <const SMESHDS_Hypothesis *> myUsedHyps;
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 "<<aStatus);
+ return error(dfltErr(), "StdMeshers_Regular_1D::CheckHypothesis() failed"
+ "with LayerDistribution hypothesis");
BRepAdaptor_Curve C3D(edge);
double f = C3D.FirstParameter(), l = C3D.LastParameter();
list< double > 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() );
*/
//================================================================================
-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 )
{
}
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");
}
class StdMeshers_NumberOfLayers;
class StdMeshers_LayerDistribution;
class SMESH_MesherHelper;
+class gp_Pnt;
class StdMeshers_RadialPrism_3D: public SMESH_3D_Algo
{
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;
#include "SMESH_HypoFilter.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include <GCPnts_UniformDeflection.hxx>
#include <Precision.hxx>
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-
#include <string>
-//#include <math.h>
using namespace std;
*/
//================================================================================
-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
//=============================================================================
/*!
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() );
+// }
}
//=============================================================================
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<const StdMeshers_SegmentLengthAroundVertex*>( 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 <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
+ if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
+ return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
+ }
+ return 0;
}
//================================================================================
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();
double theFirstU,
double theLastU,
list<double> & theParams,
- const bool theReverse) const
+ const bool theReverse)
{
theParams.clear();
}
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++ )
bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
- //MESSAGE("StdMeshers_Regular_1D::Compute");
-
if ( _hypType == NONE )
return false;
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
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