X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Algo.cxx;h=79a77f8276b9a14ea9963f62ecfab9315c01a1e5;hb=e0f019ccf9e53e6751aa85445acf2cf2831a8c24;hp=f7bd7f9bf3b2bf85824bab37264a6da3a0453e12;hpb=f5016d85b7b4b88623723027a1585c6414c4dc66;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index f7bd7f9bf..79a77f827 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,98 @@ using namespace std; +//================================================================================ +/*! + * \brief Returns \a true if two algorithms (described by \a this and the given + * algo data) are compatible by their output and input types of elements. + */ +//================================================================================ + +bool SMESH_Algo::Features::IsCompatible( const SMESH_Algo::Features& algo2 ) const +{ + if ( _dim > algo2._dim ) return algo2.IsCompatible( *this ); + // algo2 is of highter dimension + if ( _outElemTypes.empty() || algo2._inElemTypes.empty() ) + return false; + bool compatible = true; + set::const_iterator myOutType = _outElemTypes.begin(); + for ( ; myOutType != _outElemTypes.end() && compatible; ++myOutType ) + compatible = algo2._inElemTypes.count( *myOutType ); + return compatible; +} + +//================================================================================ +/*! + * \brief Return Data of the algorithm + */ +//================================================================================ + +const SMESH_Algo::Features& SMESH_Algo::GetFeatures( const std::string& algoType ) +{ + static map< string, SMESH_Algo::Features > theFeaturesByName; + if ( theFeaturesByName.empty() ) + { + // Read Plugin.xml files + vector< string > xmlPaths = SMESH_Gen::GetPluginXMLPaths(); + LDOMParser xmlParser; + for ( size_t iXML = 0; iXML < xmlPaths.size(); ++iXML ) + { + bool error = xmlParser.parse( xmlPaths[iXML].c_str() ); + if ( error ) + { + TCollection_AsciiString data; + INFOS( xmlParser.GetError(data) ); + continue; + } + // + // + LDOM_Document xmlDoc = xmlParser.getDocument(); + LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" ); + for ( int i = 0; i < algoNodeList.getLength(); ++i ) + { + LDOM_Node algoNode = algoNodeList.item( i ); + LDOM_Element& algoElem = (LDOM_Element&) algoNode; + TCollection_AsciiString algoType = algoElem.getAttribute("type"); + TCollection_AsciiString input = algoElem.getAttribute("input"); + TCollection_AsciiString output = algoElem.getAttribute("output"); + TCollection_AsciiString dim = algoElem.getAttribute("dim"); + TCollection_AsciiString label = algoElem.getAttribute("label-id"); + if ( algoType.IsEmpty() ) continue; + + Features & data = theFeaturesByName[ algoType.ToCString() ]; + data._dim = dim.IntegerValue(); + data._label = label.ToCString(); + for ( int isInput = 0; isInput < 2; ++isInput ) + { + TCollection_AsciiString& typeStr = isInput ? input : output; + set& typeSet = isInput ? data._inElemTypes : data._outElemTypes; + int beg = 1, end; + while ( beg <= typeStr.Length() ) + { + while ( beg < typeStr.Length() && !isalpha( typeStr.Value( beg ) )) + ++beg; + end = beg; + while ( end < typeStr.Length() && isalpha( typeStr.Value( end + 1 ) )) + ++end; + if ( end > beg ) + { + TCollection_AsciiString typeName = typeStr.SubString( beg, end ); + if ( typeName == "EDGE" ) typeSet.insert( SMDSGeom_EDGE ); + else if ( typeName == "TRIA" ) typeSet.insert( SMDSGeom_TRIANGLE ); + else if ( typeName == "QUAD" ) typeSet.insert( SMDSGeom_QUADRANGLE ); + } + beg = end + 1; + } + } + } + } + } + return theFeaturesByName[ algoType ]; +} + //============================================================================= /*! * @@ -82,11 +175,13 @@ using namespace std; SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, studyId, gen) { - gen->_mapAlgo[hypId] = this; + //gen->_mapAlgo[hypId] = this; _onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true; _quadraticMesh = _supportSubmeshes = false; _error = COMPERR_OK; + for ( int i = 0; i < 4; ++i ) + _neededLowerHyps[ i ] = false; } //============================================================================= @@ -110,28 +205,28 @@ SMESH_0D_Algo::SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen) { _shapeType = (1 << TopAbs_VERTEX); _type = ALGO_0D; - gen->_map0D_Algo[hypId] = this; + //gen->_map0D_Algo[hypId] = this; } SMESH_1D_Algo::SMESH_1D_Algo(int hypId, int studyId, SMESH_Gen* gen) : SMESH_Algo(hypId, studyId, gen) { _shapeType = (1 << TopAbs_EDGE); _type = ALGO_1D; - gen->_map1D_Algo[hypId] = this; + //gen->_map1D_Algo[hypId] = this; } SMESH_2D_Algo::SMESH_2D_Algo(int hypId, int studyId, SMESH_Gen* gen) : SMESH_Algo(hypId, studyId, gen) { _shapeType = (1 << TopAbs_FACE); _type = ALGO_2D; - gen->_map2D_Algo[hypId] = this; + //gen->_map2D_Algo[hypId] = this; } SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen) : SMESH_Algo(hypId, studyId, gen) { _shapeType = (1 << TopAbs_SOLID); _type = ALGO_3D; - gen->_map3D_Algo[hypId] = this; + //gen->_map3D_Algo[hypId] = this; } //============================================================================= @@ -167,15 +262,16 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis() const list & SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool ignoreAuxiliary) + const bool ignoreAuxiliary) const { - _usedHypList.clear(); + SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); + me->_usedHypList.clear(); SMESH_HypoFilter filter; if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) { - aMesh.GetHypotheses( aShape, filter, _usedHypList, true ); + aMesh.GetHypotheses( aShape, filter, me->_usedHypList, true ); if ( ignoreAuxiliary && _usedHypList.size() > 1 ) - _usedHypList.clear(); //only one compatible hypothesis allowed + me->_usedHypList.clear(); //only one compatible hypothesis allowed } return _usedHypList; } @@ -191,12 +287,13 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, const list & SMESH_Algo::GetAppliedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool ignoreAuxiliary) + const bool ignoreAuxiliary) const { - _appliedHypList.clear(); + SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); + me->_appliedHypList.clear(); SMESH_HypoFilter filter; if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) - aMesh.GetHypotheses( aShape, filter, _appliedHypList, false ); + aMesh.GetHypotheses( aShape, filter, me->_appliedHypList, false ); return _appliedHypList; } @@ -219,152 +316,6 @@ double SMESH_Algo::EdgeLength(const TopoDS_Edge & E) return length; } -//================================================================================ -/*! - * \brief Calculate normal of a mesh face - */ -//================================================================================ - -bool SMESH_Algo::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized) -{ - if ( !F || F->GetType() != SMDSAbs_Face ) - return false; - - normal.SetCoord(0,0,0); - int nbNodes = F->IsQuadratic() ? F->NbNodes()/2 : F->NbNodes(); - for ( int i = 0; i < nbNodes-2; ++i ) - { - gp_XYZ p[3]; - for ( int n = 0; n < 3; ++n ) - { - const SMDS_MeshNode* node = F->GetNode( i + n ); - p[n].SetCoord( node->X(), node->Y(), node->Z() ); - } - normal += ( p[2] - p[1] ) ^ ( p[0] - p[1] ); - } - double size2 = normal.SquareModulus(); - bool ok = ( size2 > numeric_limits::min() * numeric_limits::min()); - if ( normalized && ok ) - normal /= sqrt( size2 ); - - return ok; -} - -//================================================================================ -/*! - * \brief Find out elements orientation on a geometrical face - * \param theFace - The face correctly oriented in the shape being meshed - * \param theMeshDS - The mesh data structure - * \retval bool - true if the face normal and the normal of first element - * in the correspoding submesh point in different directions - */ -//================================================================================ - -bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face& theFace, - SMESHDS_Mesh* theMeshDS) -{ - if ( theFace.IsNull() || !theMeshDS ) - return false; - - // find out orientation of a meshed face - int faceID = theMeshDS->ShapeToIndex( theFace ); - TopoDS_Shape aMeshedFace = theMeshDS->IndexToShape( faceID ); - bool isReversed = ( theFace.Orientation() != aMeshedFace.Orientation() ); - - const SMESHDS_SubMesh * aSubMeshDSFace = theMeshDS->MeshElements( faceID ); - if ( !aSubMeshDSFace ) - return isReversed; - - // find element with node located on face and get its normal - const SMDS_FacePosition* facePos = 0; - int vertexID = 0; - gp_Pnt nPnt[3]; - gp_Vec Ne; - bool normalOK = false; - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) // loop on elements on theFace - { - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( elem && elem->NbNodes() > 2 ) { - SMDS_ElemIteratorPtr nodesIt = elem->nodesIterator(); - const SMDS_FacePosition* fPos = 0; - int i = 0, vID = 0; - while ( nodesIt->more() ) { // loop on nodes - const SMDS_MeshNode* node - = static_cast(nodesIt->next()); - if ( i == 3 ) i = 2; - nPnt[ i++ ].SetCoord( node->X(), node->Y(), node->Z() ); - // check position - const SMDS_PositionPtr& pos = node->GetPosition(); - if ( !pos ) continue; - if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) { - fPos = dynamic_cast< const SMDS_FacePosition* >( pos ); - } - else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { - vID = node->getshapeId(); - } - } - if ( fPos || ( !normalOK && vID )) { - // compute normal - gp_Vec v01( nPnt[0], nPnt[1] ), v02( nPnt[0], nPnt[2] ); - if ( v01.SquareMagnitude() > RealSmall() && - v02.SquareMagnitude() > RealSmall() ) - { - Ne = v01 ^ v02; - normalOK = ( Ne.SquareMagnitude() > RealSmall() ); - } - // we need position on theFace or at least on vertex - if ( normalOK ) { - vertexID = vID; - if ((facePos = fPos)) - break; - } - } - } - } - if ( !normalOK ) - return isReversed; - - // node position on face - double u,v; - if ( facePos ) { - u = facePos->GetUParameter(); - v = facePos->GetVParameter(); - } - else if ( vertexID ) { - TopoDS_Shape V = theMeshDS->IndexToShape( vertexID ); - if ( V.IsNull() || V.ShapeType() != TopAbs_VERTEX ) - return isReversed; - gp_Pnt2d uv = BRep_Tool::Parameters( TopoDS::Vertex( V ), theFace ); - u = uv.X(); - v = uv.Y(); - } - else - { - return isReversed; - } - - // face normal at node position - TopLoc_Location loc; - Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace, loc ); - // if ( surf.IsNull() || surf->Continuity() < GeomAbs_C1 ) - // some surfaces not detected as GeomAbs_C1 are nevertheless correct for meshing - if ( surf.IsNull() || surf->Continuity() < GeomAbs_C0 ) - { - if (!surf.IsNull()) - MESSAGE("surf->Continuity() < GeomAbs_C1 " << (surf->Continuity() < GeomAbs_C1)); - return isReversed; - } - gp_Vec d1u, d1v; - surf->D1( u, v, nPnt[0], d1u, d1v ); - gp_Vec Nf = (d1u ^ d1v).Transformed( loc ); - - if ( theFace.Orientation() == TopAbs_REVERSED ) - Nf.Reverse(); - - return Ne * Nf < 0.; -} - //================================================================================ /*! * \brief Just return false as the algorithm does not hold parameters values @@ -595,21 +546,6 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V, return 0; } -//======================================================================= -//function : GetCommonNodes -//purpose : Return nodes common to two elements -//======================================================================= - -vector< const SMDS_MeshNode*> SMESH_Algo::GetCommonNodes(const SMDS_MeshElement* e1, - const SMDS_MeshElement* e2) -{ - vector< const SMDS_MeshNode*> common; - for ( int i = 0 ; i < e1->NbNodes(); ++i ) - if ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 ) - common.push_back( e1->GetNode( i )); - return common; -} - //======================================================================= //function : GetMeshError //purpose : Finds topological errors of a sub-mesh @@ -745,6 +681,17 @@ void SMESH_Algo::CancelCompute() _error = COMPERR_CANCELED; } +//================================================================================ +/* + * If possible, returns progress of computation [0.,1.] + */ +//================================================================================ + +double SMESH_Algo::GetProgress() const +{ + return _progress; +} + //================================================================================ /*! * \brief store error and comment and then return ( error == COMPERR_OK ) @@ -792,7 +739,7 @@ SMESH_ComputeErrorPtr SMESH_Algo::GetComputeError() const //================================================================================ /*! - * \brief initialize compute error + * \brief initialize compute error before call of Compute() */ //================================================================================ @@ -807,6 +754,23 @@ void SMESH_Algo::InitComputeError() _badInputElements.clear(); _computeCanceled = false; + _computeCost = 1; + _progressTic = 0; + _progress = 0.; +} + +//================================================================================ +/*! + * \brief Return compute progress by nb of calls of this method + */ +//================================================================================ + +double SMESH_Algo::GetProgressByTic() const +{ + const_cast( this )->_progressTic++; + double x = 5 * _progressTic; + x = ( x < _computeCost ) ? ( x / _computeCost ) : 1.; + return 0.9 * sin( x * M_PI / 2 ); } //================================================================================ @@ -823,19 +787,42 @@ void SMESH_Algo::addBadInputElement(const SMDS_MeshElement* elem) _badInputElements.push_back( elem ); } +//======================================================================= +//function : addBadInputElements +//purpose : store a bad input elements or nodes preventing computation +//======================================================================= + +void SMESH_Algo::addBadInputElements(const SMESHDS_SubMesh* sm, + const bool addNodes) +{ + if ( sm ) + { + if ( addNodes ) + { + SMDS_NodeIteratorPtr nIt = sm->GetNodes(); + while ( nIt->more() ) addBadInputElement( nIt->next() ); + } + else + { + SMDS_ElemIteratorPtr eIt = sm->GetElements(); + while ( eIt->more() ) addBadInputElement( eIt->next() ); + } + } +} + //============================================================================= /*! * */ //============================================================================= -int SMESH_Algo::NumberOfWires(const TopoDS_Shape& S) -{ - int i = 0; - for (TopExp_Explorer exp(S,TopAbs_WIRE); exp.More(); exp.Next()) - i++; - return i; -} +// int SMESH_Algo::NumberOfWires(const TopoDS_Shape& S) +// { +// int i = 0; +// for (TopExp_Explorer exp(S,TopAbs_WIRE); exp.More(); exp.Next()) +// i++; +// return i; +// } //============================================================================= /*!