From b6e8c17211f3a65d729b5ffe7269c789a042ae24 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 26 Dec 2016 16:27:08 +0300 Subject: [PATCH] IPAL53863: MG-CADSurf + Viscous Layers 2D on a cylindrical face ==> crash --- src/SMESH_SWIG/smesh_algorithm.py | 4 +++ src/StdMeshers/StdMeshers_FaceSide.cxx | 28 ++++++++++++++----- src/StdMeshers/StdMeshers_ViscousLayers2D.cxx | 19 +++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index c68606886..fc48e7ba2 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -288,6 +288,8 @@ class Mesh_Algorithm: raise TypeError, "ViscousLayers are supported by 3D algorithms only" if not "ViscousLayers" in self.GetCompatibleHypothesis(): raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName() + if faces and isinstance( faces, geomBuilder.GEOM._objref_GEOM_Object ): + faces = [ faces ] if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ): faceIDs = [] for shape in faces: @@ -324,6 +326,8 @@ class Mesh_Algorithm: raise TypeError, "ViscousLayers2D are supported by 2D algorithms only" if not "ViscousLayers2D" in self.GetCompatibleHypothesis(): raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName() + if edges and not isinstance( edges, list ) and not isinstance( edges, tuple ): + edges = [edges] if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ): edgeIDs = [] for shape in edges: diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 921269126..0c7c334f2 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -469,25 +469,39 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons if ( proxySubMesh[ iE ] ) // copy data from a proxy sub-mesh { const UVPtStructVec& edgeUVPtStruct = proxySubMesh[iE]->GetUVPtStructVec(); - std::copy( edgeUVPtStruct.begin(), edgeUVPtStruct.end(), & points[iPt] ); + UVPtStruct* pointsPtr = & points[iPt]; + std::copy( edgeUVPtStruct.begin(), edgeUVPtStruct.end(), pointsPtr ); // check orientation double du1 = edgeUVPtStruct.back().param - edgeUVPtStruct[0].param; double du2 = myLast[iE] - myFirst[iE]; if ( du1 * du2 < 0 ) { - std::reverse( & points[iPt], & points[iPt + edgeUVPtStruct.size()]); + std::reverse( pointsPtr, pointsPtr + edgeUVPtStruct.size()); for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) - points[iPt+i].normParam = 1. - points[iPt+i].normParam; + pointsPtr[i].normParam = 1. - pointsPtr[i].normParam; } // update normalized params if ( myEdge.size() > 1 ) { - for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i, ++iPt ) + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) { - UVPtStruct & uvPt = points[iPt]; + UVPtStruct & uvPt = pointsPtr[i]; uvPt.normParam = prevNormPar + uvPt.normParam * paramSize; uvPt.x = uvPt.y = uvPt.normParam; } - --iPt; // to point to the 1st VERTEX of the next EDGE + iPt += edgeUVPtStruct.size() - 1; // to point to the 1st VERTEX of the next EDGE + } + // update UV on a seam EDGE + if ( fHelper.IsRealSeam( myEdgeID[ iE ])) + { + // check if points lye on the EDGE + const UVPtStruct& pm = edgeUVPtStruct[ edgeUVPtStruct.size()/2 ]; + gp_Pnt pNode = SMESH_TNodeXYZ( pm.node ); + gp_Pnt pCurv = myC3dAdaptor[ iE ].Value( pm.param ); + double tol = BRep_Tool::Tolerance( myEdge[ iE ]) * 10; + bool isPointOnEdge = ( pNode.SquareDistance( pCurv ) < tol * tol ); + if ( isPointOnEdge ) + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) + pointsPtr[i].SetUV( myC2d[ iE ]->Value( pointsPtr[i].param ).XY() ); } } else @@ -495,7 +509,7 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons for ( ; u_node != u2node.end(); ++u_node, ++iPt ) { if ( myNormPar[ iE ]-eps < u_node->first ) - break; // u_node is at VERTEX of the next EDGE + break; // u_node is at VERTEX of the next EDGE UVPtStruct & uvPt = points[iPt]; uvPt.node = u_node->second; diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index 32cf255ec..2de6e474c 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -1744,11 +1744,13 @@ bool _ViscousBuilder2D::shrink() } } // loop on FACEs sharing E + // Check if L is an already shrinked seam + if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) + if ( L._wire->Edge( L._edgeInd ).Orientation() == TopAbs_FORWARD ) + continue; // Commented as a case with a seam EDGE (issue 0052461) is hard to support // because SMESH_ProxyMesh can't hold different sub-meshes for two // 2D representations of the seam. But such a case is not a real practice one. - // Check if L is an already shrinked seam - // if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) // { // for ( int iL2 = iL1-1; iL2 > -1; --iL2 ) // { @@ -2438,6 +2440,19 @@ bool _ViscousBuilder2D::refine() nodeDataVec.front().param = L._wire->FirstU( L._edgeInd ); nodeDataVec.back() .param = L._wire->LastU ( L._edgeInd ); + if (( nodeDataVec[0].node == nodeDataVec.back().node ) && + ( _helper.GetPeriodicIndex() == 1 || _helper.GetPeriodicIndex() == 2 )) // closed EDGE + { + const int iCoord = _helper.GetPeriodicIndex(); + gp_XY uv = nodeDataVec[0].UV(); + uv.SetCoord( iCoord, L._lEdges[0]._uvOut.Coord( iCoord )); + nodeDataVec[0].SetUV( uv ); + + uv = nodeDataVec.back().UV(); + uv.SetCoord( iCoord, L._lEdges.back()._uvOut.Coord( iCoord )); + nodeDataVec.back().SetUV( uv ); + } + _ProxyMeshOfFace::_EdgeSubMesh* edgeSM = getProxyMesh()->GetEdgeSubMesh( L._wire->EdgeID( L._edgeInd )); edgeSM->SetUVPtStructVec( nodeDataVec ); -- 2.39.2