From a713f0b919f062a1c9839670d4b51639c8133940 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 6 Apr 2015 21:07:26 +0300 Subject: [PATCH] 23032: EDF SMESH: Projection 1D-2D fails with Netgen 1D-2D + 22792: EDF 8159 SMESH: Multi-dimensional extrusion/extrusion along a path/revolution 1) Enable selection of sub-meshes on groups 2) Fix preview that was not shown + In SMESHGUI/CMakeList, remove includes that never need not be included --- .../gui/SMESH/images/2d_from_3d_example.png | Bin 0 -> 7418 bytes .../gui/SMESH/input/make_2dmesh_from_3d.doc | 5 +- src/SMESH/SMESH_MesherHelper.cxx | 12 +- src/SMESH/SMESH_Pattern.cxx | 8 +- src/SMESHDS/SMESH_Controls.hxx | 3 +- src/SMESHFiltersSelection/SMESH_Type.h | 5 +- .../SMESH_TypeFilter.cxx | 53 ++++- src/SMESHGUI/CMakeLists.txt | 2 - src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx | 5 +- src/SMESHGUI/SMESHGUI_Utils.cxx | 10 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 10 +- src/StdMeshers/StdMeshers_ProjectionUtils.cxx | 215 +++++++++++++----- src/StdMeshers/StdMeshers_ProjectionUtils.hxx | 24 +- src/StdMeshers/StdMeshers_Projection_2D.cxx | 63 +++-- 14 files changed, 310 insertions(+), 105 deletions(-) create mode 100644 doc/salome/gui/SMESH/images/2d_from_3d_example.png diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_example.png b/doc/salome/gui/SMESH/images/2d_from_3d_example.png new file mode 100644 index 0000000000000000000000000000000000000000..d01efd538b58cc83d0a495b756e517c32470d97d GIT binary patch literal 7418 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc index a53257eef..8b9486e0a 100644 --- a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc +++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc @@ -3,7 +3,10 @@ \page make_2dmesh_from_3d_page Generate boundary elements \n This functionality allows to generate mesh elements on the borders of -elements of a higher dimension. +elements of a higher dimension, for example, to create 2D elements +around a block of 3D elements as in the following figure. + +\image html 2d_from_3d_example.png "Missing 2D elements were generated" To generate border elements:
    diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 5dc2a89c8..eb3ba5d71 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -302,10 +302,20 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) isSeam = ( Abs( uv1.Coord(2) - myPar1[1] ) < Precision::PConfusion() || Abs( uv1.Coord(2) - myPar2[1] ) < Precision::PConfusion() ); } + if ( isSeam ) // vertices are on period boundary, check a middle point (23032) + { + double f,l, r = 0.2345; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( edge, face, f, l ); + uv2 = C2d->Value( f * r + l * ( 1.-r )); + if ( du < Precision::PConfusion() ) + isSeam = ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Precision::PConfusion() ); + else + isSeam = ( Abs( uv1.Coord(2) - uv2.Coord(2) ) < Precision::PConfusion() ); + } } if ( isSeam ) { - // store seam shape indices, negative if shape encounters twice + // store seam shape indices, negative if shape encounters twice ('real seam') mySeamShapeIds.insert( IsSeamShape( edgeID ) ? -edgeID : edgeID ); for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) { int vertexID = meshDS->ShapeToIndex( v.Current() ); diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index f8b9fb65f..7aba007ab 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -716,7 +716,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { if ( isClosed && ( iE == 0 || iE == *nbEinW )) { - // new wire begins; put EDGEs in eVec + // new wire begins; put wire EDGEs in eVec list::iterator eEnd = elIt; std::advance( eEnd, *nbEinW ); eVec.assign( elIt, eEnd ); @@ -733,7 +733,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, TopoDS_Shape v1 = TopExp::FirstVertex( edge, true ); // always FORWARD TopoDS_Shape v2 = TopExp::LastVertex( edge, true ); // always REVERSED // to make adjacent edges share key-point, we make v2 FORWARD too - // (as we have different points for same shape with different orienation) + // (as we have different points for same shape with different orientation) v2.Reverse(); // on closed face we must have REVERSED some of seam vertices @@ -745,7 +745,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, v2.Reverse(); } } - else { // on CLOSED edge (i.e. having one vertex with different orienations) + else { // on CLOSED edge (i.e. having one vertex with different orientations) for ( int is2 = 0; is2 < 2; ++is2 ) { TopoDS_Shape & v = is2 ? v2 : v1; if ( helper.IsRealSeam( v ) ) { @@ -2516,7 +2516,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, list< TopoDS_Edge >& wire = (*wlIt); int nbEdges = wire.size(); wlIt++; - if ( wlIt == wireList.end() || (*wlIt).size() != nbEdges ) // a unique size wire + if ( wlIt != wireList.end() && (*wlIt).size() != nbEdges ) // a unique size wire { // choose the best first edge of a wire setFirstEdge( wire, id1 ); diff --git a/src/SMESHDS/SMESH_Controls.hxx b/src/SMESHDS/SMESH_Controls.hxx index 28dda6dcb..5b741437a 100644 --- a/src/SMESHDS/SMESH_Controls.hxx +++ b/src/SMESHDS/SMESH_Controls.hxx @@ -24,7 +24,8 @@ #define _SMESH_CONTROLS_HXX_ // This file is named incosistently with others, i.e. not SMESHDS_Controls.hxx, -// because it was moved from ../Controls/SMESH_Controls.hxx +// because it was moved from ../Controls/SMESH_Controls.hxx. +// It was moved here for the sake of SMESHDS_GroupOnFilter #include "SMDSAbs_ElementType.hxx" diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h index 5068c9e12..9398fe649 100644 --- a/src/SMESHFiltersSelection/SMESH_Type.h +++ b/src/SMESHFiltersSelection/SMESH_Type.h @@ -59,7 +59,10 @@ namespace SMESH{ GROUP_0D, GROUP_BALL, COMPONENT, - IDSOURCE + IDSOURCE, + IDSOURCE_EDGE, // IDSource including edges + IDSOURCE_FACE, + IDSOURCE_VOLUME }; }; #endif diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx index ea3593b88..5f12c7faa 100644 --- a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx @@ -22,10 +22,10 @@ #include "SMESH_TypeFilter.hxx" +#include #include - +#include #include -#include #include #include CORBA_CLIENT_HEADER(SMESH_Gen) @@ -39,6 +39,40 @@ SMESH_TypeFilter::~SMESH_TypeFilter() { } +namespace +{ + //================================================================================ + /*! + * \brief Returns true if \a obj is SMESH_IDSource including elements of a given \a type + */ + //================================================================================ + + bool isIDSourceOfType( _PTR(SObject) obj, SMESH::ElementType type ) + { + bool Ok = false; + SalomeApp_Application* app = dynamic_cast + (SUIT_Session::session()->activeApplication()); + _PTR(GenericAttribute) anAttr; + if ( obj->FindAttribute(anAttr, "AttributeIOR")) + { + _PTR(AttributeIOR) anIOR = anAttr; + std::string aVal = anIOR->Value(); + if ( aVal.size() > 0 ) + { + CORBA::Object_var corbaObj = app->orb()->string_to_object( aVal.c_str() ); + SMESH::SMESH_IDSource_var ids = SMESH::SMESH_IDSource::_narrow( corbaObj ); + if ( ! ids->_is_nil() ) + { + SMESH::array_of_ElementType_var types = ids->GetTypes(); + for ( int i = 0, nb = types->length(); i < nb && !Ok; ++i ) + Ok = ( types[i] == type ); + } + } + } + return Ok; + } +} + bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const { bool Ok = false, extractReference = true; @@ -215,6 +249,21 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const SMESH_TypeFilter(SMESH::GROUP) .isOk( theDataOwner )); break; } + case SMESH::IDSOURCE_EDGE: + { + Ok = isIDSourceOfType( obj, SMESH::EDGE ); + break; + } + case SMESH::IDSOURCE_FACE: + { + Ok = isIDSourceOfType( obj, SMESH::FACE ); + break; + } + case SMESH::IDSOURCE_VOLUME: + { + Ok = isIDSourceOfType( obj, SMESH::VOLUME ); + break; + } } } return Ok; diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index 5ee5b6ea8..ed8b7836e 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -39,9 +39,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/SMESHFiltersSelection ${PROJECT_SOURCE_DIR}/src/SMDS ${PROJECT_SOURCE_DIR}/src/SMESHDS - ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESHUtils - ${PROJECT_SOURCE_DIR}/src/SMESH_I ${PROJECT_SOURCE_DIR}/src/Controls ${PROJECT_SOURCE_DIR}/src/SMESHClient ${PROJECT_SOURCE_DIR}/src/MEDWrapper/Base diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index b82b5d821..0a7901267 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -162,14 +162,17 @@ SMESHGUI_3TypesSelector::SMESHGUI_3TypesSelector( QWidget * parent ): aListOfFilters.append(new SMESH_TypeFilter (SMESH::GROUP_NODE)); myFilter[0] = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true); + aListOfFilters.append(0); aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH); aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_EDGE); aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_EDGE); + aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_EDGE); // for sub-mesh on group of EDGEs myFilter[1] = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true); aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH); aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_FACE); aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_FACE); + aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_FACE); // for sub-mesh on group of FACEs myFilter[2] = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true); @@ -864,7 +867,7 @@ bool SMESHGUI_ExtrusionDlg::isValuesValid() } else if ( ExtrMethod_RBut2->isChecked() ) { - aModule = (double)SpinBox_VDist->value(); + aModule = Abs((double)SpinBox_VDist->value()); } return aModule > 1.0E-38; diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx index 8fd7d6db9..1ab0c6a70 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.cxx +++ b/src/SMESHGUI/SMESHGUI_Utils.cxx @@ -189,7 +189,7 @@ namespace SMESH } CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject, - _PTR(Study) theStudy) + _PTR(Study) /*theStudy*/) { SalomeApp_Application* app = dynamic_cast (SUIT_Session::session()->activeApplication()); @@ -197,11 +197,11 @@ namespace SMESH _PTR(GenericAttribute) anAttr; if (theSObject->FindAttribute(anAttr, "AttributeIOR")) { _PTR(AttributeIOR) anIOR = anAttr; - CORBA::String_var aVal = anIOR->Value().c_str(); + std::string aVal = anIOR->Value(); // string_to_object() DOC: If the input string is not valid ... // a CORBA::SystemException is thrown. - if ( aVal && strlen( aVal ) > 0 ) - return app->orb()->string_to_object(aVal); + if ( aVal.size() > 0 ) + return app->orb()->string_to_object( aVal.c_str() ); } } return CORBA::Object::_nil(); @@ -209,7 +209,7 @@ namespace SMESH CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject) { - _PTR(Study) aStudy = GetActiveStudyDocument(); + _PTR(Study) aStudy;// = GetActiveStudyDocument(); -- aStudy is not used return SObjectToObject(theSObject,aStudy); } diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index ec4cb02c6..d01cf35f5 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -2524,14 +2524,14 @@ SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNode idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face; if ( myIsPreviewMode ) { - SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face; // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node ) // previewType = SMDSAbs_Edge; SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - TPreviewMesh * tmpMesh = getPreviewMesh(); + TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); workElements = & copyElements[0]; @@ -2561,7 +2561,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNode } else { - getPreviewMesh()->Remove( SMDSAbs_Volume ); + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); } return aGroups ? aGroups : new SMESH::ListOfGroups; @@ -2607,9 +2607,9 @@ SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects, idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType ); TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_Face; if ( myIsPreviewMode ) { - SMDSAbs_ElementType previewType = SMDSAbs_Face; SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); @@ -2637,7 +2637,7 @@ SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects, } else { - getPreviewMesh()->Remove( SMDSAbs_Volume ); + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); } declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index faeb9b706..a21f5d7aa 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +85,7 @@ using namespace std; // gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( (v) ));\ // cout< Group projection: theShape1 is a group member, - // theShape2 is another group. We find a group theShape1 is in and recall self. + // theShape2 is another group. We find the group theShape1 is in and recall self. // 2) Accosiate same shapes with different location (partners). - // 3) If vertex association is given, perform accosiation according to shape type: + // 3) If vertex association is given, perform association according to shape type: // switch ( ShapeType ) { // case TopAbs_EDGE: // case ...: @@ -499,7 +515,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // ================================================================================= // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203) // ================================================================================= - if ( theShape1.ShapeType() != theShape2.ShapeType() ) { + if ( theShape1.ShapeType() != theShape2.ShapeType() ) + { TopoDS_Shape group1, group2; if ( theShape1.ShapeType() == TopAbs_COMPOUND ) { group1 = theShape1; @@ -538,6 +555,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the for ( ; s1It.More(); s1It.Next(), s2It.Next() ) shapesQueue.push_back( make_pair( s1It.Value(), s2It.Value() )); } + theMap.SetAssocType( TShapeShapeMap::PARTNER ); return true; } @@ -546,6 +564,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the //====================================================================== // 3) HAS initial vertex association //====================================================================== + bool isVCloseness = ( theMap._assocType == TShapeShapeMap::CLOSE_VERTEX ); + theMap.SetAssocType( TShapeShapeMap::INIT_VERTEX ); switch ( theShape1.ShapeType() ) { // ---------------------------------------------------------------------- case TopAbs_EDGE: { // TopAbs_EDGE @@ -594,7 +614,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } } list< TopoDS_Edge > edges1, edges2; - int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); + int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2, isVCloseness ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); fixAssocByPropagation( nbE, edges1, edges2, theMesh1, theMesh2 ); @@ -698,8 +718,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the F2 = FF2[ 1 ]; } - TopTools_MapOfShape boundEdges; - // association of face sub-shapes and neighbour faces list< pair < TopoDS_Face, TopoDS_Edge > > FE1, FE2; list< pair < TopoDS_Face, TopoDS_Edge > >::iterator fe1, fe2; @@ -715,7 +733,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopExp::Vertices( edge1, VV1[0], VV1[1], true ); TopExp::Vertices( edge2, VV2[0], VV2[1], true ); list< TopoDS_Edge > edges1, edges2; - int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); + int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2, isVCloseness ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); InsertAssociation( face1, face2, theMap ); // assoc faces MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<< @@ -728,8 +746,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { - if ( !boundEdges.Add( *eIt1 )) continue; // already associated - InsertAssociation( *eIt1, *eIt2, theMap ); // assoc edges + if ( !InsertAssociation( *eIt1, *eIt2, theMap )) // assoc edges + continue; // already associated VV1[0] = TopExp::FirstVertex( *eIt1, true ); VV2[0] = TopExp::FirstVertex( *eIt2, true ); InsertAssociation( VV1[0], VV2[0], theMap ); // assoc vertices @@ -1011,6 +1029,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the InsertAssociation( edge1, prpEdge, theMap ); // insert with a proper orientation } InsertAssociation( theShape1, theShape2, theMap ); + theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); return true; // done } } @@ -1086,6 +1105,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the InsertAssociation( VV1[0], VV2[0], theMap ); } InsertAssociation( theShape1, theShape2, theMap ); + theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); return true; } } @@ -1150,7 +1170,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !VV1[1].IsNull() ) { InsertAssociation( VV1[0], VV2[0], theMap ); InsertAssociation( VV1[1], VV2[1], theMap ); - return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap); + if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) + { + theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); + return true; + } } } break; // try by vertex closeness @@ -1207,7 +1231,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the InsertAssociation( VV1[0], VV1[0], theMap ); InsertAssociation( VV1[1], VV1[1], theMap ); if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) + { + theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); return true; + } } } } @@ -1301,6 +1328,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the break; } } + theMap.SetAssocType( TShapeShapeMap::CLOSE_VERTEX ); InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap ); InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap ); @@ -1325,6 +1353,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the * \param VV2 - vertices of face 2 associated with ones of face 1 * \param edges1 - out list of edges of face 1 * \param edges2 - out list of edges of face 2 + * \param isClosenessAssoc - is association starting by VERTEX closeness * \retval int - nb of edges in an outer wire in a success case, else zero */ //================================================================================ @@ -1334,7 +1363,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, const TopoDS_Face& face2, TopoDS_Vertex VV2[2], list< TopoDS_Edge > & edges1, - list< TopoDS_Edge > & edges2) + list< TopoDS_Edge > & edges2, + const bool isClosenessAssoc) { bool OK = false; list< int > nbEInW1, nbEInW2; @@ -1363,46 +1393,56 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // Define if we need to reverse one of wires to make edges in lists match each other bool reverse = false; + const bool severalWires = ( nbEInW1.size() > 1 ); - if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) { + if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) + { reverse = true; - edgeIt = --edges1.end(); // check if the second vertex belongs to the first or last edge in the wire + edgeIt = --edges1.end(); // pointer to the last edge in the outer wire + if ( severalWires ) { + edgeIt = edges1.begin(); + std::advance( edgeIt, nbEInW1.front()-1 ); + } + if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) && + SMESH_Algo::isDegenerated( *edgeIt )) { + --edgeIt; // skip a degenerated edge (www.salome-platform.org/forum/forum_11/173031193) + } if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { - bool KO = true; // belongs to none - if ( nbEInW1.size() > 1 ) { // several wires - edgeIt = edges1.begin(); - std::advance( edgeIt, nbEInW1.front()-1 ); - KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); - } - if ( KO ) - CONT_BAD_RESULT("GetOrderedEdges() failed"); + CONT_BAD_RESULT("GetOrderedEdges() failed"); } } - if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) { + if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) + { reverse = !reverse; - edgeIt = --edges2.end(); - // move a degenerated edge from back to front - // http://www.salome-platform.org/forum/forum_11/173031193 - if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt ))) { - edges2.splice( edges2.begin(), edges2, edgeIt ); - edgeIt = --edges2.end(); - } // check if the second vertex belongs to the first or last edge in the wire + edgeIt = --edges2.end(); // pointer to the last edge in the outer wire + if ( severalWires ) { + edgeIt = edges2.begin(); + std::advance( edgeIt, nbEInW2.front()-1 ); + } + if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) && + SMESH_Algo::isDegenerated( *edgeIt )) { + --edgeIt; // skip a degenerated edge + } if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { - bool KO = true; // belongs to none - if ( nbEInW2.size() > 1 ) { // several wires - edgeIt = edges2.begin(); - std::advance( edgeIt, nbEInW2.front()-1 ); - KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); - } - if ( KO ) - CONT_BAD_RESULT("GetOrderedEdges() failed"); + CONT_BAD_RESULT("GetOrderedEdges() failed"); } } if ( reverse ) { reverseEdges( edges2 , nbEInW2.front()); + + if ( SMESH_Algo::isDegenerated( edges2.front() )) + { + // move a degenerated edge to the back of the outer wire + edgeIt = edges2.end(); + if ( severalWires ) { + edgeIt = edges2.begin(); + std::advance( edgeIt, nbEInW2.front() ); + } + edges2.splice( edgeIt, edges2, edges2.begin() ); + } if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) != ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))) CONT_BAD_RESULT("GetOrderedEdges() failed"); @@ -1410,6 +1450,65 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, OK = true; } // loop algos getting an outer wire + + if ( OK && nbEInW1.front() > 4 ) // care of a case where faces are closed (23032) + { + // check if the first edges are seam ones + list< TopoDS_Edge >::iterator revSeam1, revSeam2; + revSeam1 = std::find( ++edges1.begin(), edges1.end(), edges1.front().Reversed()); + revSeam2 = edges2.end(); + if ( revSeam1 != edges1.end() ) + revSeam2 = std::find( ++edges2.begin(), edges2.end(), edges2.front().Reversed()); + if ( revSeam2 != edges2.end() ) // two seams detected + { + bool reverse = + std::distance( edges1.begin(), revSeam1 ) != std::distance( edges2.begin(), revSeam2 ); + if ( !reverse && isClosenessAssoc ) + { + // compare orientations of a non-seam edges using 3D closeness; + // look for a non-seam edges + list< TopoDS_Edge >::iterator edge1 = ++edges1.begin(); + list< TopoDS_Edge >::iterator edge2 = ++edges2.begin(); + for ( ; edge1 != edges1.end(); ++edge1, ++edge2 ) + { + if (( edge1 == revSeam1 ) || + ( SMESH_Algo::isDegenerated( *edge1 )) || + ( std::find( ++edges1.begin(), edges1.end(), edge1->Reversed()) != edges1.end() )) + continue; + gp_Pnt p1 = BRep_Tool::Pnt( VV1[0] ); + gp_Pnt p2 = BRep_Tool::Pnt( VV2[0] ); + gp_Vec vec2to1( p2, p1 ); + + gp_Pnt pp1[2], pp2[2]; + const double r = 0.2345; + double f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve( *edge1, f,l ); + pp1[0] = C->Value( f * r + l * ( 1. - r )); + pp1[1] = C->Value( l * r + f * ( 1. - r )); + if ( edge1->Orientation() == TopAbs_REVERSED ) + std::swap( pp1[0], pp1[1] ); + C = BRep_Tool::Curve( *edge2, f,l ); + if ( C.IsNull() ) return 0; + pp2[0] = C->Value( f * r + l * ( 1. - r )).Translated( vec2to1 ); + pp2[1] = C->Value( l * r + f * ( 1. - r )).Translated( vec2to1 ); + if ( edge2->Orientation() == TopAbs_REVERSED ) + std::swap( pp2[0], pp2[1] ); + + double dist00 = pp1[0].SquareDistance( pp2[0] ); + double dist01 = pp1[0].SquareDistance( pp2[1] ); + reverse = ( dist00 > dist01 ); + break; + } + } + if ( reverse ) // make a seam counterpart be the first + { + list< TopoDS_Edge >::iterator outWireEnd = edges2.begin(); + std::advance( outWireEnd, nbEInW2.front() ); + edges2.splice( outWireEnd, edges2, edges2.begin(), ++revSeam2 ); + reverseEdges( edges2 , nbEInW2.front()); + } + } + } // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity @@ -1418,13 +1517,23 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // Check that Vec(VV1[0],VV1[1]) in 2D on face1 is the same // as Vec(VV2[0],VV2[1]) on face2 double vTol = BRep_Tool::Tolerance( VV1[0] ); - BRepAdaptor_Surface surface1( face1, false ); + BRepAdaptor_Surface surface1( face1, true ); + BRepAdaptor_Surface surface2( face2, true ); + // TODO: use TrsfFinder2D to superpose the faces + gp_Pnt2d v0f1UV( surface1.FirstUParameter(), surface1.FirstVParameter() ); + gp_Pnt2d v0f2UV( surface2.FirstUParameter(), surface2.FirstVParameter() ); + gp_Pnt2d v1f1UV( surface1.LastUParameter(), surface1.LastVParameter() ); + gp_Pnt2d v1f2UV( surface2.LastUParameter(), surface2.LastVParameter() ); double vTolUV = surface1.UResolution( vTol ) + surface1.VResolution( vTol ); // let's be tolerant - gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 ); - gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 ); - gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 ); - gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 ); + // VV1[0] = TopExp::FirstVertex( edges1.front(), true ); // ori is important if face is closed + // VV1[1] = TopExp::LastVertex ( edges1.front(), true ); + // VV2[0] = TopExp::FirstVertex( edges2.front(), true ); + // VV2[1] = TopExp::LastVertex ( edges2.front(), true ); + // gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 ); + // gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 ); + // gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 ); + // gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 ); gp_Vec2d v01f1Vec( v0f1UV, v1f1UV ); gp_Vec2d v01f2Vec( v0f2UV, v1f2UV ); if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV && @@ -1443,7 +1552,6 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, list< int >::iterator nbE2, nbE1 = nbEInW1.begin(); list< TopoDS_Edge >::iterator edge2Beg, edge1Beg = edges1.begin(); if ( OK ) std::advance( edge1Beg, *nbE1++ ); - // reach an end of edges of a current wire1 list< TopoDS_Edge >::iterator edge2End, edge1End; // // find corresponding wires of face2 @@ -1473,12 +1581,12 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, { // rotate edge2 untill coincidence with edge1 in 2D int i = *nbE2; - while ( i-- > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + bool sameUV = false; + while ( !( sameUV = sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) && --i > 0 ) // move edge2Beg to place before edge2End edges2.splice( edge2End, edges2, edge2Beg++ ); - if ( edge2Beg != edges2.end() && - sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + if ( sameUV ) { if ( iW1 == 0 ) OK = true; // OK is for the first wire @@ -1495,8 +1603,9 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, if ( edge2Beg->Orientation() == TopAbs_REVERSED ) std::swap( f,l ); gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); + gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); - if ( uv1.Distance( uv2 ) > vTolUV ) + if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) edge2Beg->Reverse(); } else diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx index 958d55607..ea599b7a9 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx @@ -59,6 +59,10 @@ struct StdMeshers_ShapeShapeBiDirectionMap { TopTools_DataMapOfShapeShape _map1to2, _map2to1; + enum EAssocType { + UNDEF, INIT_VERTEX, PROPAGATION, PARTNER, CLOSE_VERTEX, COMMON_VERTEX, FEW_EF }; + EAssocType _assocType; + // convention: s1 - target, s2 - source bool Bind( const TopoDS_Shape& s1, const TopoDS_Shape& s2 ) { _map1to2.Bind( s1, s2 ); return _map2to1.Bind( s2, s1 ); } @@ -72,6 +76,8 @@ struct StdMeshers_ShapeShapeBiDirectionMap // passes incorrect isShape2 return (isShape2 ? _map2to1 : _map1to2)( s ); } + StdMeshers_ShapeShapeBiDirectionMap() : _assocType( UNDEF ) {} + void SetAssocType( EAssocType type ) { if ( _assocType == UNDEF ) _assocType = type; } }; /*! @@ -148,20 +154,22 @@ namespace StdMeshers_ProjectionUtils /*! * \brief Find association of edges of faces - * \param face1 - face 1 - * \param VV1 - vertices of face 1 - * \param face2 - face 2 - * \param VV2 - vertices of face 2 associated with oned of face 1 - * \param edges1 - out list of edges of face 1 - * \param edges2 - out list of edges of face 2 - * \retval int - nb of edges in an outer wire in a success case, else zero + * \param face1 - face 1 + * \param VV1 - vertices of face 1 + * \param face2 - face 2 + * \param VV2 - vertices of face 2 associated with oned of face 1 + * \param edges1 - out list of edges of face 1 + * \param edges2 - out list of edges of face 2 + * \param isClosenessAssoc - is association starting by VERTEX closeness + * \retval int - nb of edges in an outer wire in a success case, else zero */ int FindFaceAssociation(const TopoDS_Face& face1, TopoDS_Vertex VV1[2], const TopoDS_Face& face2, TopoDS_Vertex VV2[2], std::list< TopoDS_Edge > & edges1, - std::list< TopoDS_Edge > & edges2); + std::list< TopoDS_Edge > & edges2, + const bool isClosenessAssoc=false); /*! * \brief Insert vertex association defined by a hypothesis into a map diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 67a353c75..bde99cd86 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -1088,20 +1088,22 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // Check if node projection to a face is needed Bnd_B2d uvBox; SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements(); - int nbFaceNodes = 0; - for ( ; nbFaceNodes < 3 && faceIt->more(); ) { + set< const SMDS_MeshNode* > faceNodes; + for ( ; faceNodes.size() < 3 && faceIt->more(); ) { const SMDS_MeshElement* face = faceIt->next(); SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { - nbFaceNodes++; + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE && + faceNodes.insert( node ).second ) uvBox.Add( helper.GetNodeUV( srcFace, node )); - } } } - const bool toProjectNodes = - ( nbFaceNodes > 0 && ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN )); + bool toProjectNodes = false; + if ( faceNodes.size() == 1 ) + toProjectNodes = ( uvBox.IsVoid() || uvBox.CornerMin().IsEqual( gp_XY(0,0), 1e-12 )); + else if ( faceNodes.size() > 1 ) + toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN ); // Find the corresponding source and target vertex // and flag needed to call mapper.Apply() @@ -1109,13 +1111,10 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& TopoDS_Vertex srcV1, tgtV1; bool reverse = false; - if ( _sourceHypo->HasVertexAssociation() ) { - srcV1 = _sourceHypo->GetSourceVertex(1); - tgtV1 = _sourceHypo->GetTargetVertex(1); - } else { - srcV1 = TopoDS::Vertex( TopExp_Explorer( srcFace, TopAbs_VERTEX ).Current() ); - tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true )); - } + TopExp_Explorer vSrcExp( srcFace, TopAbs_VERTEX ); + srcV1 = TopoDS::Vertex( vSrcExp.Current() ); + tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true )); + list< TopoDS_Edge > tgtEdges, srcEdges; list< int > nbEdgesInWires; SMESH_Block::GetOrderedEdges( tgtFace, tgtEdges, nbEdgesInWires, tgtV1 ); @@ -1127,7 +1126,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 ); reverse = ( ! srcE1.IsSame( srcE1bis )); if ( reverse && - _sourceHypo->HasVertexAssociation() && + //_sourceHypo->HasVertexAssociation() && nbEdgesInWires.front() > 2 && helper.IsRealSeam( tgtEdges.front() )) { @@ -1136,11 +1135,30 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // we can't use only theReverse flag to correctly associate source // and target faces in the mapper. Thus we select srcV1 so that // GetOrderedEdges() to return EDGEs in a needed order - list< TopoDS_Edge >::iterator edge = srcEdges.begin(); - for ( ; edge != srcEdges.end(); ++edge ) { - if ( srcE1bis.IsSame( *edge )) { - srcV1 = helper.IthVertex( 0, *edge ); - break; + TopoDS_Face tgtFaceBis = tgtFace; + for ( vSrcExp.Next(); vSrcExp.More(); ) + { + tgtFaceBis.Reverse(); + tgtEdges.clear(); + SMESH_Block::GetOrderedEdges( tgtFaceBis, tgtEdges, nbEdgesInWires, tgtV1 ); + bool ok = true; + list< TopoDS_Edge >::iterator edgeS = srcEdges.begin(), edgeT = tgtEdges.begin(); + for ( ; edgeS != srcEdges.end() && ok ; ++edgeS, ++edgeT ) + ok = edgeS->IsSame( shape2ShapeMap( *edgeT )); + if ( ok ) + break; // FOUND! + + reverse = !reverse; + if ( reverse ) + { + vSrcExp.Next(); + } + else + { + srcV1 = TopoDS::Vertex( vSrcExp.Current() ); + tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true )); + srcEdges.clear(); + SMESH_Block::GetOrderedEdges( srcFace, srcEdges, nbEdgesInWires, srcV1 ); } } } @@ -1168,8 +1186,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // Compute mesh on a target face mapper.Apply( tgtFace, tgtV1, reverse ); - if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) + if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) { + // std::ofstream file("/tmp/Pattern.smp" ); + // mapper.Save( file ); return error("Can't apply source mesh pattern to the face"); + } // Create the mesh -- 2.30.2