From: eap Date: Fri, 9 Oct 2015 14:47:17 +0000 (+0300) Subject: 23179: EDF 11603 - Problem with extrusion when path is not well oriented X-Git-Tag: V7_7_0_WIN~3 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=512d3547bc726e9bb5732b1d0692e1141ca258e1 23179: EDF 11603 - Problem with extrusion when path is not well oriented HYDRO module: Feature #523: river, channel, embankment meshing --- diff --git a/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png b/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png index f233cc640..3e3c63b23 100644 Binary files a/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png and b/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png differ diff --git a/doc/salome/gui/SMESH/input/constructing_meshes.doc b/doc/salome/gui/SMESH/input/constructing_meshes.doc index 9e5e639be..2ec8a4987 100644 --- a/doc/salome/gui/SMESH/input/constructing_meshes.doc +++ b/doc/salome/gui/SMESH/input/constructing_meshes.doc @@ -229,6 +229,9 @@ have been defined will be discretized. ~~~~~~ + If the file contents are incorrect, there can be an error at + activation of Mesh module: "fatal parsing error: error + triggered by consumer in line ..."
\image html hypo_sets.png diff --git a/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc b/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc index 89a919ef3..6a90f376e 100644 --- a/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc +++ b/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc @@ -5,13 +5,18 @@ Medial Axis Projection algorithm can be used for meshing faces with sinuous borders and having channel-like shape, for which is it difficult to define 1D hypotheses so that generated quadrangles to be -of good shape. +of good shape. The algorithm can be also applied to faces with ring +topology, which can be viewed as a closed 'channel'. In the latter +case radial discretization of a ring can be specified by +using Number of Layers or Distribution of Layers +hypothesis. -\image html quad_from_ma_mesh.png "A mesh of a river model" +\image html quad_from_ma_mesh.png "A mesh of a river model to the left and of a ring-face to the right" The algorithm assures good shape of quadrangles by constructing Medial Axis between sinuous borders of the face and using it to -discretize the borders. +discretize the borders. (Shape of quadrangles can be not perfect at +locations where opposite sides of a 'channel' are far from being parallel.) \image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders" diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 037acb584..4c264d50a 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -441,7 +441,8 @@ void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm) { if ( sm ) _sm_current.push_back( sm ); - else + + else if ( !_sm_current.empty() ) _sm_current.pop_back(); } diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 9cc4d2378..2c2fc35e0 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -5986,6 +5986,10 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], ASSERT( theTrack ); SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS(); + if ( !pSubMeshDS ) + return ExtrusionAlongTrack( theElements, theTrack->GetFather(), theN1, + theHasAngles, theAngles, theLinearVariation, + theHasRefPoint, theRefPoint, theMakeGroups ); aItE = pSubMeshDS->GetElements(); while ( aItE->more() ) { diff --git a/src/SMESHUtils/SMESH_MAT2d.cxx b/src/SMESHUtils/SMESH_MAT2d.cxx index d423f8be8..970d560e5 100644 --- a/src/SMESHUtils/SMESH_MAT2d.cxx +++ b/src/SMESHUtils/SMESH_MAT2d.cxx @@ -344,6 +344,9 @@ namespace if ( !_edge || !seg2._edge ) return true; + if ( _edge->twin() == seg2._edge ) + return true; + const TVDCell* cell1 = this->_edge->twin()->cell(); const TVDCell* cell2 = seg2. _edge->twin()->cell(); if ( cell1 == cell2 ) @@ -367,8 +370,8 @@ namespace else if ( edgeMedium1->is_primary() && edgeMedium2->is_primary() ) { if ( edgeMedium1->twin() == edgeMedium2 && - SMESH_MAT2d::Branch::getBndSegment( edgeMedium1 ) == - SMESH_MAT2d::Branch::getBndSegment( edgeMedium2 )) + SMESH_MAT2d::Branch::getGeomEdge( edgeMedium1 ) == + SMESH_MAT2d::Branch::getGeomEdge( edgeMedium2 )) // this is an ignored MA edge between inSegment's on one EDGE forming a convex corner return true; } @@ -413,7 +416,7 @@ namespace */ //================================================================================ - void bndSegsToMesh( const vector< BndSeg >& bndSegs ) + void bndSegsToMesh( const vector< vector< BndSeg > >& bndSegsPerEdge ) { #ifdef _MYDEBUG_ if ( !getenv("bndSegsToMesh")) return; @@ -431,31 +434,35 @@ namespace text << "from salome.smesh import smeshBuilder\n"; text << "smesh = smeshBuilder.New(salome.myStudy)\n"; text << "m=smesh.Mesh()\n"; - for ( size_t i = 0; i < bndSegs.size(); ++i ) + for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE ) { - if ( !bndSegs[i]._edge ) - text << "# " << i << " NULL edge\n"; - else if ( !bndSegs[i]._edge->vertex0() || - !bndSegs[i]._edge->vertex1() ) - text << "# " << i << " INFINITE edge\n"; - else if ( addedEdges.insert( bndSegs[i]._edge ).second && - addedEdges.insert( bndSegs[i]._edge->twin() ).second ) + const vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ]; + for ( size_t i = 0; i < bndSegs.size(); ++i ) { - v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first; - int n0 = v2n->second; - if ( n0 == v2Node.size() ) - text << "n" << n0 << " = m.AddNode( " - << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", " - << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n"; - - v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first; - int n1 = v2n->second; - if ( n1 == v2Node.size() ) - text << "n" << n1 << " = m.AddNode( " - << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", " - << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n"; - - text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n"; + if ( !bndSegs[i]._edge ) + text << "# E=" << iE << " i=" << i << " NULL edge\n"; + else if ( !bndSegs[i]._edge->vertex0() || + !bndSegs[i]._edge->vertex1() ) + text << "# E=" << iE << " i=" << i << " INFINITE edge\n"; + else if ( addedEdges.insert( bndSegs[i]._edge ).second && + addedEdges.insert( bndSegs[i]._edge->twin() ).second ) + { + v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first; + int n0 = v2n->second; + if ( n0 == v2Node.size() ) + text << "n" << n0 << " = m.AddNode( " + << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", " + << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n"; + + v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first; + int n1 = v2n->second; + if ( n1 == v2Node.size() ) + text << "n" << n1 << " = m.AddNode( " + << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", " + << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n"; + + text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n"; + } } } text << "\n"; @@ -985,7 +992,7 @@ namespace bndSegs[0].setIndexToEdge( 0 ); } - //bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges + bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges // Find TVDEdge's of Branches and associate them with bndSegs @@ -1374,6 +1381,15 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge, while ( points._params[i+1] < u ) ++i; } + if ( points._params[i] == points._params[i+1] ) // coincident points at some end + { + int di = ( points._params[0] == points._params[i] ) ? +1 : -1; + while ( points._params[i] == points._params[i+1] ) + i += di; + if ( i < 0 || i+1 >= points._params.size() ) + i = 0; + } + double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] ); if ( !points._maEdges[ i ].second ) // no branch at the EDGE end, look for a closest branch diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index 6218de9f8..d51714ae7 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -947,7 +947,8 @@ std::string SMESH_GroupOnFilter_i::FilterToString() const { SMESH::Filter::Criterion& crit = criteria[ i ]; - if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup ) + if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup && + crit.ThresholdID.in() && crit.ThresholdID.in()[0] ) { CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( crit.ThresholdID ); if ( SMESH_GroupBase_i * g = SMESH::DownCast< SMESH_GroupBase_i*>( obj )) diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 44a1bfdfa..0b927273c 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -2844,7 +2844,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the if ( !aMeshImp ) return aGroups._retn(); TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape ); aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); - if ( !aSubMesh || !aSubMesh->GetSubMeshDS() ) + if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ ) return aGroups._retn(); } diff --git a/src/SMESH_SWIG/StdMeshersBuilder.py b/src/SMESH_SWIG/StdMeshersBuilder.py index ce50a39cb..98acce5f6 100644 --- a/src/SMESH_SWIG/StdMeshersBuilder.py +++ b/src/SMESH_SWIG/StdMeshersBuilder.py @@ -1100,8 +1100,7 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm): pass # end of StdMeshersBuilder_Prism3D class -## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism" -# depending on geometry +## Defines a Prism 3D algorithm # # It is created by calling smeshBuilder.Mesh.Prism(geom=0) # @@ -1133,30 +1132,12 @@ class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D): self.nbLayers = None return -## Defines a Radial Quadrangle 1D-2D algorithm +## Base class for algorithms supporting radial distribution hypotheses # -# It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0) -# -# @ingroup l2_algos_radialq -class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm): - - ## name of the dynamic method in smeshBuilder.Mesh class - # @internal - meshMethod = "Quadrangle" - ## type of algorithm used with helper function in smeshBuilder.Mesh class - # @internal - algoType = RADIAL_QUAD - ## doc string of the method - # @internal - docHelper = "Creates quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment" +class StdMeshersBuilder_RadialAlgorithm(Mesh_Algorithm): - ## Private constructor. - # @param mesh parent mesh object algorithm is assigned to - # @param geom geometry (shape/sub-shape) algorithm is assigned to; - # if it is @c 0 (default), the algorithm is assigned to the main shape - def __init__(self, mesh, geom=0): + def __init__(self): Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, self.algoType) self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0) self.nbLayers = None @@ -1259,12 +1240,42 @@ class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm): pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class +## Defines a Radial Quadrangle 1D-2D algorithm +# +# It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0) +# +# @ingroup l2_algos_radialq +class StdMeshersBuilder_RadialQuadrangle1D2D(StdMeshersBuilder_RadialAlgorithm): + + ## name of the dynamic method in smeshBuilder.Mesh class + # @internal + meshMethod = "Quadrangle" + ## type of algorithm used with helper function in smeshBuilder.Mesh class + # @internal + algoType = RADIAL_QUAD + ## doc string of the method + # @internal + docHelper = "Creates quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment" + + ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape + def __init__(self, mesh, geom=0): + StdMeshersBuilder_RadialAlgorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0) + self.nbLayers = None + pass + + ## Defines a Quadrangle (Medial Axis Projection) 1D-2D algorithm # # It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.QUAD_MA_PROJ,geom=0) # # @ingroup l2_algos_quad_ma -class StdMeshersBuilder_QuadMA_1D2D(Mesh_Algorithm): +class StdMeshersBuilder_QuadMA_1D2D(StdMeshersBuilder_RadialAlgorithm): ## name of the dynamic method in smeshBuilder.Mesh class # @internal @@ -1281,7 +1292,7 @@ class StdMeshersBuilder_QuadMA_1D2D(Mesh_Algorithm): # @param geom geometry (shape/sub-shape) algorithm is assigned to; # if it is @c 0 (default), the algorithm is assigned to the main shape def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) + StdMeshersBuilder_RadialAlgorithm.__init__(self) self.Create(mesh, geom, self.algoType) pass diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 8f49d4937..22ea69d83 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -3987,6 +3987,7 @@ class Mesh: if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object): RefPoint = self.smeshpyD.GetPointStruct(RefPoint) if isinstance( RefPoint, list ): + if not RefPoint: RefPoint = [0,0,0] RefPoint = SMESH.PointStruct( *RefPoint ) if isinstance( PathMesh, Mesh ): PathMesh = PathMesh.GetMesh() @@ -4019,8 +4020,9 @@ class Mesh: # only SMESH::Extrusion_Error otherwise # @ingroup l2_modif_extrurev def ExtrusionAlongPathX(self, Base, Path, NodeStart, - HasAngles, Angles, LinearVariation, - HasRefPoint, RefPoint, MakeGroups, ElemType): + HasAngles=False, Angles=[], LinearVariation=False, + HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False, + ElemType=SMESH.FACE): n,e,f = [],[],[] if ElemType == SMESH.NODE: n = Base if ElemType == SMESH.EDGE: e = Base @@ -4050,7 +4052,7 @@ class Mesh: # only SMESH::Extrusion_Error otherwise # @ingroup l2_modif_extrurev def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart, - HasAngles, Angles, HasRefPoint, RefPoint, + HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[], MakeGroups=False, LinearVariation=False): n,e,f = [],IDsOfElements,IDsOfElements gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, @@ -4080,7 +4082,7 @@ class Mesh: # only SMESH::Extrusion_Error otherwise # @ingroup l2_modif_extrurev def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart, - HasAngles, Angles, HasRefPoint, RefPoint, + HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[], MakeGroups=False, LinearVariation=False): n,e,f = [],theObject,theObject gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart, @@ -4109,7 +4111,7 @@ class Mesh: # only SMESH::Extrusion_Error otherwise # @ingroup l2_modif_extrurev def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart, - HasAngles, Angles, HasRefPoint, RefPoint, + HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[], MakeGroups=False, LinearVariation=False): n,e,f = [],theObject,[] gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart, @@ -4138,7 +4140,7 @@ class Mesh: # only SMESH::Extrusion_Error otherwise # @ingroup l2_modif_extrurev def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart, - HasAngles, Angles, HasRefPoint, RefPoint, + HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[], MakeGroups=False, LinearVariation=False): n,e,f = [],[],theObject gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart, diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index 9481ff1d7..a57b03463 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -85,6 +85,7 @@ class Mesh_Algorithm: attr = hypo_so_i.FindAttribute("AttributeIOR")[1] if attr is not None: anIOR = attr.Value() + if not anIOR: continue # prevent exception in orb.string_to_object() hypo_o_i = salome.orb.string_to_object(anIOR) if hypo_o_i is not None: # Check if this is a hypothesis @@ -128,6 +129,7 @@ class Mesh_Algorithm: attr = algo_so_i.FindAttribute("AttributeIOR")[1] if attr is not None: anIOR = attr.Value() + if not anIOR: continue # prevent exception in orb.string_to_object() algo_o_i = salome.orb.string_to_object(anIOR) if algo_o_i is not None: # Check if this is an algorithm diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx index 680279e75..a9b924724 100644 --- a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx @@ -1039,7 +1039,7 @@ namespace const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves; double uMA; - SMESH_MAT2d::BoundaryPoint bp[2]; + SMESH_MAT2d::BoundaryPoint bp[2]; // 2 sinuous sides const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0); { // add to thePointsOnE NodePoint's of ends of theSinuEdges @@ -1138,7 +1138,7 @@ namespace // projection is set to the BoundaryPoint of this projection // evaluate distance to neighbor projections - const double rShort = 0.2; + const double rShort = 0.33; bool isShortPrev[2], isShortNext[2], isPrevCloser[2]; TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP; --u2NPPrev; ++u2NPNext; @@ -1306,8 +1306,8 @@ namespace TIterator u2NPprev = sameU2NP.front(); TIterator u2NPnext = sameU2NP.back() ; - if ( u2NPprev->first > 0. ) --u2NPprev; - if ( u2NPnext->first < 1. ) ++u2NPprev; + if ( u2NPprev->first < 0. ) ++u2NPprev; + if ( u2NPnext->first > 1. ) --u2NPnext; set< int >::iterator edgeID = edgeInds.begin(); for ( ; edgeID != edgeInds.end(); ++edgeID ) @@ -1322,8 +1322,8 @@ namespace if ( u0 == u1 ) { - if ( np->_node ) --u2NPprev; - else ++u2NPnext; + if ( u2NPprev != thePointsOnE.begin() ) --u2NPprev; + if ( u2NPnext != --thePointsOnE.end() ) ++u2NPnext; np = &get( u2NPprev->second, iSide ); u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace ); np = &get( u2NPnext->second, iSide ); @@ -1331,7 +1331,7 @@ namespace } // distribute points and create nodes - double du = ( u1 - u0 ) / ( sameU2NP.size() + !existingNode ); + double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 /*!existingNode*/ ); double u = u0 + du; for ( size_t i = 0; i < sameU2NP.size(); ++i ) { @@ -1503,8 +1503,8 @@ namespace theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew ); } - if ( theFace._quad->side[ 1 ].NbPoints() != - theFace._quad->side[ 3 ].NbPoints()) + if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() || + theFace._quad->side[ 3 ].GetUVPtStruct().empty() ) return false; } // if ( theFace.IsRing() ) @@ -1553,6 +1553,7 @@ namespace vector< int > edgeIDs ( theSinuEdges.size() ); // IDs in the main shape vector< bool > isComputed( theSinuEdges.size() ); curves.resize( theSinuEdges.size(), 0 ); + bool allComputed = true; for ( size_t i = 0; i < theSinuEdges.size(); ++i ) { curves[i] = BRep_Tool::Curve( theSinuEdges[i], f,l ); @@ -1561,6 +1562,8 @@ namespace SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] ); edgeIDs [i] = sm->GetId(); isComputed[i] = ( !sm->IsEmpty() ); + if ( !isComputed[i] ) + allComputed = false; } const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0); @@ -1568,7 +1571,9 @@ namespace vector< std::size_t > edgeIDs1, edgeIDs2; // indices in theSinuEdges vector< SMESH_MAT2d::BranchPoint > divPoints; - branch.getOppositeGeomEdges( edgeIDs1, edgeIDs2, divPoints ); + if ( !allComputed ) + branch.getOppositeGeomEdges( edgeIDs1, edgeIDs2, divPoints ); + for ( size_t i = 0; i < edgeIDs1.size(); ++i ) if ( isComputed[ edgeIDs1[i]] && isComputed[ edgeIDs2[i]] ) @@ -1587,15 +1592,20 @@ namespace return false; } - // map param on MA to parameters of nodes on a pair of theSinuEdges + // map (param on MA) to (parameters of nodes on a pair of theSinuEdges) TMAPar2NPoints pointsOnE; vector maParams; + set projectedEdges; // treated EDGEs which 'isComputed' // compute params of nodes on EDGEs by projecting division points from MA for ( size_t iEdgePair = 0; iEdgePair < edgeIDs1.size(); ++iEdgePair ) // loop on pairs of opposite EDGEs { + if ( projectedEdges.count( edgeIDs1[ iEdgePair ]) || + projectedEdges.count( edgeIDs2[ iEdgePair ]) ) + continue; + // -------------------------------------------------------------------------------- if ( isComputed[ edgeIDs1[ iEdgePair ]] != // one EDGE is meshed isComputed[ edgeIDs2[ iEdgePair ]]) @@ -1610,6 +1620,8 @@ namespace if ( !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iEdgeComputed ], /*skipMedium=*/true, nodeParams )) return false; + projectedEdges.insert( iEdgeComputed ); + SMESH_MAT2d::BoundaryPoint& bndPnt = bp[ 1-iSideComputed ]; SMESH_MAT2d::BranchPoint brp; NodePoint npN, npB; // NodePoint's initialized by node and BoundaryPoint @@ -1618,10 +1630,10 @@ namespace double maParam1st, maParamLast, maParam; if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.begin()->first, brp )) - return false; + return false; branch.getParameter( brp, maParam1st ); if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.rbegin()->first, brp )) - return false; + return false; branch.getParameter( brp, maParamLast ); map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = nodeParams.end(); @@ -1641,28 +1653,6 @@ namespace npB = NodePoint( bndPnt ); pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 ))); } - - // move iEdgePair forward; - // find divPoints most close to max MA param - if ( edgeIDs1.size() > 1 ) - { - maParamLast = pointsOnE.rbegin()->first; - int iClosest; - double minDist = 1.; - for ( ; iEdgePair < edgeIDs1.size()-1; ++iEdgePair ) - { - branch.getParameter( divPoints[iEdgePair], maParam ); - double d = Abs( maParamLast - maParam ); - if ( d < minDist ) - minDist = d, iClosest = iEdgePair; - else - break; - } - if ( Abs( maParamLast - 1. ) < minDist ) - break; // the last pair treated - else - iEdgePair = iClosest; - } } // -------------------------------------------------------------------------------- else if ( !isComputed[ edgeIDs1[ iEdgePair ]] && // none of EDGEs is meshed