From 55510e5ccd337f72bb1caa755b131cf0916d91b3 Mon Sep 17 00:00:00 2001 From: skl Date: Wed, 22 Jul 2009 09:13:29 +0000 Subject: [PATCH] Implementation of Quadrangle (Mapping) for faces built on 3 edges (0018911 from Mantis). --- .../gui/SMESH/images/hypo_quad_params_1.png | Bin 0 -> 40985 bytes .../gui/SMESH/images/hypo_quad_params_res.png | Bin 0 -> 5902 bytes .../gui/SMESH/input/2d_meshing_hypo.doc | 16 + idl/SMESH_BasicHypothesis.idl | 26 ++ src/SMESH/SMESH_MesherHelper.cxx | 24 + src/SMESHGUI/SMESHGUI.cxx | 1 + src/SMESHGUI/SMESHGUI_Hypotheses.cxx | 6 +- src/StdMeshers/Makefile.am | 6 +- src/StdMeshers/StdMeshers_FaceSide.cxx | 38 +- src/StdMeshers/StdMeshers_FaceSide.hxx | 8 +- .../StdMeshers_QuadrangleParams.cxx | 165 +++++++ .../StdMeshers_QuadrangleParams.hxx | 80 ++++ src/StdMeshers/StdMeshers_Quadrangle_2D.cxx | 256 ++++++++--- src/StdMeshers/StdMeshers_Quadrangle_2D.hxx | 5 +- src/StdMeshersGUI/Makefile.am | 9 +- .../StdMeshersGUI_NbSegmentsCreator.cxx | 4 +- .../StdMeshersGUI_NbSegmentsCreator.h | 4 +- .../StdMeshersGUI_StdHypothesisCreator.cxx | 77 +++- .../StdMeshersGUI_SubShapeSelectorWdg.cxx | 427 ++++++++++++++++++ .../StdMeshersGUI_SubShapeSelectorWdg.h | 115 +++++ src/StdMeshersGUI/StdMeshers_images.ts | 4 + src/StdMeshersGUI/StdMeshers_msg_en.ts | 12 + src/StdMeshers_I/Makefile.am | 4 +- .../StdMeshers_QuadrangleParams_i.cxx | 188 ++++++++ .../StdMeshers_QuadrangleParams_i.hxx | 80 ++++ src/StdMeshers_I/StdMeshers_i.cxx | 3 + 26 files changed, 1471 insertions(+), 87 deletions(-) create mode 100755 doc/salome/gui/SMESH/images/hypo_quad_params_1.png create mode 100644 doc/salome/gui/SMESH/images/hypo_quad_params_res.png create mode 100644 src/StdMeshers/StdMeshers_QuadrangleParams.cxx create mode 100644 src/StdMeshers/StdMeshers_QuadrangleParams.hxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h create mode 100644 src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx create mode 100644 src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_1.png b/doc/salome/gui/SMESH/images/hypo_quad_params_1.png new file mode 100755 index 0000000000000000000000000000000000000000..de1d7df0a3c975dccdb009c0e98a9cf456bc81ee GIT binary patch literal 40985 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 z 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
  • \ref max_element_area_anchor "Max Element Area"
  • \ref length_from_edges_anchor "Length from Edges"
  • +
  • \ref hypo_quad_params_anchor "Quadrangle parameters"
  • \ref quadrangle_preference_anchor "Quadrangle Preference"
  • \ref triangle_preference_anchor "Triangle Preference"
  • @@ -38,6 +39,21 @@ length calculated as an average edge length for a given wire. See Also a sample TUI Script of a \ref tui_length_from_edges "Length from Edges" hypothesis operation. +
    +\anchor hypo_quad_params_anchor +

    Quadrangle parameters

    + +Quadrangle parameters is a general hypothesis for +Quadrangle (Mapping). This hypothesis gives a possibility +of using Quadrangle (Mapping) mechanism for faces built on 3 edges. +The hypothesis requires some vertex to be selected from the face; this vertex will be +used as degenerated edge. The resulting mesh will include several triangles near this +vertex. Hypothesis construction and resulting mesh is displayed at the following figures: + +\image html hypo_quad_params_1.png + +\image html hypo_quad_params_res.png +
    \anchor quadrangle_preference_anchor

    Quadrangle Preference

    diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index e8b0824a4..37db80292 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -681,6 +681,32 @@ module StdMeshers double GetLength(); }; + /*! + * StdMeshers_QuadrangleParams: interface of "Quadrangle Params" hypothesis + */ + interface StdMeshers_QuadrangleParams : SMESH::SMESH_Hypothesis + { + /*! + * Set base vertex for triangles + */ + void SetTriaVertex( in long vertID ); + + /*! + * Returns base vertex for triangles + */ + long GetTriaVertex(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); + }; + /*! * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm */ diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 356457cd2..eb138d2ed 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -727,6 +727,10 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, { SMESHDS_Mesh * meshDS = GetMeshDS(); SMDS_MeshFace* elem = 0; + + if( n1==n2 || n2==n3 || n3==n1 ) + return elem; + if(!myCreateQuadratic) { if(id) elem = meshDS->AddFaceWithID(n1, n2, n3, id); @@ -764,6 +768,26 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, { SMESHDS_Mesh * meshDS = GetMeshDS(); SMDS_MeshFace* elem = 0; + + if( n1==n2 ) { + return AddFace(n1,n3,n4,id,force3d); + } + if( n1==n3 ) { + return AddFace(n1,n2,n4,id,force3d); + } + if( n1==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if( n2==n3 ) { + return AddFace(n1,n2,n4,id,force3d); + } + if( n2==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if( n3==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if(!myCreateQuadratic) { if(id) elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id); diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 4561074f7..7cbec92d7 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -2077,6 +2077,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 1100: // EDIT HYPOTHESIS { + cout<<"EDIT HYPOTHESIS"<GetMeshDS(); @@ -155,6 +156,34 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, //dump(); } +//================================================================================ +/*! + * \brief Constructor of a side for vertex using data from other FaceSide + * \param theVertex - the vertex + * \param theSide - the side + */ +//================================================================================ + +StdMeshers_FaceSide::StdMeshers_FaceSide(const SMDS_MeshNode* theNode, + const gp_Pnt2d thePnt2d, + const StdMeshers_FaceSide* theSide) +{ + myC2d.resize(1); + myLength = 0; + myMesh = theSide->GetMesh(); + myDefaultPnt2d = thePnt2d; + + myPoints = theSide->GetUVPtStruct(); + myNbPonits = myNbSegments = myPoints.size(); + std::vector::iterator it = myPoints.begin(); + for(; it!=myPoints.end(); it++) { + (*it).u = thePnt2d.X(); + (*it).v = thePnt2d.Y(); + (*it).y = 0.0; + (*it).node = theNode; + } +} + //================================================================================ /*! * \brief Return info on nodes on the side @@ -175,8 +204,7 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, map< double, const SMDS_MeshNode*> u2node; //int nbOnDegen = 0; - for ( int i = 0; i < myEdge.size(); ++i ) - { + for ( int i = 0; i < myEdge.size(); ++i ) { // put 1st vertex node TopoDS_Vertex VFirst, VLast; TopExp::Vertices( myEdge[i], VFirst, VLast, true); @@ -184,7 +212,8 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param if ( node ) { // internal nodes may be missing u2node.insert( make_pair( prevNormPar, node )); - } else if ( i == 0 ) { + } + else if ( i == 0 ) { MESSAGE(" NO NODE on VERTEX" ); return myPoints; } @@ -470,7 +499,8 @@ gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const double r = ( U - prevU )/ ( myNormPar[ i ] - prevU ); return myC2d[ i ]->Value( myFirst[i] * ( 1 - r ) + myLast[i] * r ); } - return gp_Pnt2d( 1e+100, 1e+100 ); + //return gp_Pnt2d( 1e+100, 1e+100 ); + return myDefaultPnt2d; } //================================================================================ diff --git a/src/StdMeshers/StdMeshers_FaceSide.hxx b/src/StdMeshers/StdMeshers_FaceSide.hxx index 202b6a6d4..f340dad04 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.hxx +++ b/src/StdMeshers/StdMeshers_FaceSide.hxx @@ -93,7 +93,12 @@ public: SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes); - + /*! + * \brief Wrap for vertex using data from other FaceSide + */ + StdMeshers_FaceSide(const SMDS_MeshNode* theNode, + const gp_Pnt2d thePnt2d, + const StdMeshers_FaceSide* theSide); /*! * \brief Return wires of a face as StdMeshers_FaceSide's */ @@ -202,6 +207,7 @@ protected: int myNbPonits, myNbSegments; SMESH_Mesh* myMesh; bool myMissingVertexNodes, myIgnoreMediumNodes; + gp_Pnt2d myDefaultPnt2d; }; diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.cxx b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx new file mode 100644 index 000000000..ad3fee841 --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx @@ -0,0 +1,165 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_QuadrangleParams.cxx +// Author : Sergey KUUL, OCC +// Module : SMESH +// +#include "StdMeshers_QuadrangleParams.hxx" + +#include "SMESH_Algo.hxx" +#include "SMESH_Mesh.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_QuadrangleParams::StdMeshers_QuadrangleParams(int hypId, int studyId, + SMESH_Gen * gen) + :SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "QuadrangleParams"; + _param_algo_dim = 2; + _triaVertexID = -1; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_QuadrangleParams::~StdMeshers_QuadrangleParams() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_QuadrangleParams::SetTriaVertex(int id) +{ + if ( id != _triaVertexID ) { + _triaVertexID = id; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save) +{ + save << _triaVertexID << " " << _objEntry; + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load) +{ + bool isOK = true; + isOK = (load >> _triaVertexID); + if (!isOK) + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> _objEntry); + + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp) +{ + return hyp.LoadFrom( load ); +} + +//================================================================================ +/*! + * \brief Redifined method + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + if ( !theMesh || theShape.IsNull() ) + return false; + + return true; +} + +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_QuadrangleParams::SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* /*mesh*/) +{ + return true; +} + diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.hxx b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx new file mode 100644 index 000000000..ab1c56fab --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_QuadrangleParams.hxx +// Author : Sergey KUUL, OCC +// Module : SMESH +// +#ifndef _SMESH_QUADRANGLEPARAMS_HXX_ +#define _SMESH_QUADRANGLEPARAMS_HXX_ + + + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class STDMESHERS_EXPORT StdMeshers_QuadrangleParams: + public SMESH_Hypothesis +{ +public: + StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_QuadrangleParams(); + + void SetTriaVertex(int id); + + void SetObjectEntry( const char* entry ) { _objEntry = entry; } + + const char* GetObjectEntry() { return _objEntry.c_str(); } + + int GetTriaVertex() const { return _triaVertexID; } + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + friend std::ostream& operator << (std::ostream & save, + StdMeshers_QuadrangleParams & hyp); + friend std::istream& operator >> (std::istream & load, + StdMeshers_QuadrangleParams & hyp); + + /*! + * \brief Initialize start and end length 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 + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape); + + /*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* theMesh=0); + +protected: + int _triaVertexID; + std::string _objEntry; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 0a13e88ea..bd55a02c4 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -29,6 +29,8 @@ #include "StdMeshers_FaceSide.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" @@ -74,12 +76,14 @@ typedef SMESH_Comment TComm; */ //============================================================================= -StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMESH_Gen* gen) +StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, + SMESH_Gen* gen) : SMESH_2D_Algo(hypId, studyId, gen) { MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D"); _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("QuadrangleParams"); _compatibleHypothesis.push_back("QuadranglePreference"); _compatibleHypothesis.push_back("TrianglePreference"); myTool = 0; @@ -110,25 +114,69 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis bool isOk = true; aStatus = SMESH_Hypothesis::HYP_OK; - - const list &hyps = GetUsedHypothesis(aMesh, aShape, false); + const list &hyps = + GetUsedHypothesis(aMesh, aShape, false); const SMESHDS_Hypothesis *theHyp = 0; - if(hyps.size() > 0){ - theHyp = *hyps.begin(); + if( hyps.size() == 1 ) { + myTriaVertexID = -1; + theHyp = hyps.front(); + if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) { + const StdMeshers_QuadrangleParams* theHyp1 = + (const StdMeshers_QuadrangleParams*)theHyp; + myTriaVertexID = theHyp1->GetTriaVertex(); + myQuadranglePreference= false; + myTrianglePreference= false; + } if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { myQuadranglePreference= true; myTrianglePreference= false; + myTriaVertexID = -1; } else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ myQuadranglePreference= false; myTrianglePreference= true; + myTriaVertexID = -1; } } + + else if( hyps.size() > 1 ) { + theHyp = hyps.front(); + if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) { + const StdMeshers_QuadrangleParams* theHyp1 = + (const StdMeshers_QuadrangleParams*)theHyp; + myTriaVertexID = theHyp1->GetTriaVertex(); + theHyp = hyps.back(); + if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { + myQuadranglePreference= true; + myTrianglePreference= false; + } + else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ + myQuadranglePreference= false; + myTrianglePreference= true; + } + } + else { + if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { + myQuadranglePreference= true; + myTrianglePreference= false; + } + else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ + myQuadranglePreference= false; + myTrianglePreference= true; + } + const StdMeshers_QuadrangleParams* theHyp2 = + (const StdMeshers_QuadrangleParams*)hyps.back(); + myTriaVertexID = theHyp2->GetTriaVertex(); + } + } + else { myQuadranglePreference = false; myTrianglePreference = false; + myTriaVertexID = -1; } + return isOk; } @@ -237,7 +285,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i].node; SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) { + meshDS->SetMeshElementOnShape(face, geomFaceID); + } } } @@ -311,9 +361,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < ilow) @@ -324,7 +373,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if(!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -338,9 +387,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + k - 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -401,9 +449,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > iup) @@ -413,7 +460,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); if(!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -426,9 +473,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -475,9 +521,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < jlow) @@ -488,7 +533,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if(!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -501,9 +546,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*k - 2].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -547,9 +591,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > jup) @@ -559,7 +602,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); if(!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -572,9 +615,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -640,15 +682,18 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, int dh = Max(nbdown, nbup) - nbhoriz; int dv = Max(nbright, nbleft) - nbvertic; - int kdh = 0; - if(dh>0) kdh = 1; - int kdv = 0; - if(dv>0) kdv = 1; + //int kdh = 0; + //if(dh>0) kdh = 1; + //int kdv = 0; + //if(dv>0) kdv = 1; int nbNodes = (nbhoriz-2)*(nbvertic-2); - int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2; - if( kdh==1 && kdv==1 ) nbFaces3 -= 2; - int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv); + //int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2; + int nbFaces3 = dh + dv; + //if( kdh==1 && kdv==1 ) nbFaces3 -= 2; + //if( dh>0 && dv>0 ) nbFaces3 -= 2; + //int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv); + int nbFaces4 = (nbhoriz-1)*(nbvertic-1); std::vector aVec(17); for(int i=0; i<17; i++) aVec[i] = 0; @@ -658,11 +703,19 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, int nbbndedges = nbdown + nbup + nbright + nbleft -4; int nbintedges = ( nbFaces4*4 + nbFaces3*3 - nbbndedges ) / 2; aVec[0] = nbNodes + nbintedges; + if( aNbNodes.size()==5 ) { + aVec[4] = nbFaces3 + aNbNodes[3] -1; + aVec[6] = nbFaces4 - aNbNodes[3] +1; + } } else { aVec[0] = nbNodes; aVec[3] = nbFaces3; aVec[5] = nbFaces4; + if( aNbNodes.size()==5 ) { + aVec[3] = nbFaces3 + aNbNodes[3] - 1; + aVec[5] = nbFaces4 - aNbNodes[3] + 1; + } } SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); @@ -720,7 +773,41 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes int nbSides = 0; list< TopoDS_Edge >::iterator edgeIt = edges.begin(); - if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges + if ( nbEdgesInWire.front() == 3 ) { // exactly 3 edges + if(myTriaVertexID>0) { + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); + if(!V.IsNull()) { + TopoDS_Edge E1,E2,E3; + for(; edgeIt != edges.end(); ++edgeIt) { + TopoDS_Edge E = TopoDS::Edge(*edgeIt); + TopoDS_Vertex VF, VL; + TopExp::Vertices(E, VF, VL, true); + if( VF.IsSame(V) ) + E1 = E; + else if( VL.IsSame(V) ) + E3 = E; + else + E2 = E; + } + quad->side.reserve(4); + quad->side.push_back( new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back( new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back( new StdMeshers_FaceSide(F, E3, &aMesh, false, ignoreMediumNodes)); + std::vector UVPSleft = quad->side[0]->GetUVPtStruct(true,0); + std::vector UVPStop = quad->side[1]->GetUVPtStruct(false,1); + std::vector UVPSright = quad->side[2]->GetUVPtStruct(true,1); + const SMDS_MeshNode* aNode = UVPSleft[0].node; + gp_Pnt2d aPnt2d( UVPSleft[0].u, UVPSleft[0].v ); + StdMeshers_FaceSide* VertFS = + new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1]); + quad->side.push_back(VertFS); + return quad; + } + } + return 0; + } + else if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ ) quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh, nbSides aVec = (*anIt).second; IsQuadratic = (aVec[2] > aVec[1]); + if ( nbEdgesInWire.front() == 3 ) { // exactly 3 edges + if(myTriaVertexID>0) { + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); + if(!V.IsNull()) { + TopoDS_Edge E1,E2,E3; + for(; edgeIt != edges.end(); ++edgeIt) { + TopoDS_Edge E = TopoDS::Edge(*edgeIt); + TopoDS_Vertex VF, VL; + TopExp::Vertices(E, VF, VL, true); + if( VF.IsSame(V) ) + E1 = E; + else if( VL.IsSame(V) ) + E3 = E; + else + E2 = E; + } + SMESH_subMesh * sm = aMesh.GetSubMesh(E1); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if(anIt==aResMap.end()) return false; + std::vector aVec = (*anIt).second; + if(IsQuadratic) + aNbNodes[0] = (aVec[0]-1)/2 + 2; + else + aNbNodes[0] = aVec[0] + 2; + sm = aMesh.GetSubMesh(E2); + anIt = aResMap.find(sm); + if(anIt==aResMap.end()) return false; + aVec = (*anIt).second; + if(IsQuadratic) + aNbNodes[1] = (aVec[0]-1)/2 + 2; + else + aNbNodes[1] = aVec[0] + 2; + sm = aMesh.GetSubMesh(E3); + anIt = aResMap.find(sm); + if(anIt==aResMap.end()) return false; + aVec = (*anIt).second; + if(IsQuadratic) + aNbNodes[2] = (aVec[0]-1)/2 + 2; + else + aNbNodes[2] = aVec[0] + 2; + aNbNodes[3] = aNbNodes[1]; + aNbNodes.resize(5); + nbSides = 4; + } + } + } if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges for(; edgeIt != edges.end(); edgeIt++) { SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt ); @@ -1083,10 +1217,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, } // normalized 2d values on grid - for (int i = 0; i < nbhoriz; i++) - { - for (int j = 0; j < nbvertic; j++) - { + for (int i = 0; i < nbhoriz; i++) { + for (int j = 0; j < nbvertic; j++) { int ij = j * nbhoriz + i; // --- droite i cste : x = x0 + y(x1-x0) double x0 = uv_e0[i].normParam; // bas - sud @@ -1110,10 +1242,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, gp_UV a2( uv_e2.back().u, uv_e2.back().v ); gp_UV a3( uv_e2.front().u, uv_e2.front().v ); - for (int i = 0; i < nbhoriz; i++) - { - for (int j = 0; j < nbvertic; j++) - { + for (int i = 0; i < nbhoriz; i++) { + for (int j = 0; j < nbvertic; j++) { int ij = j * nbhoriz + i; double x = uv_grid[ij].x; double y = uv_grid[ij].y; @@ -1446,13 +1576,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshFace* F = myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1509,13 +1639,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshFace* F = myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1587,13 +1717,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1629,13 +1759,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshFace* F = myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1742,13 +1872,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } // end nrAddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), NodesLast.Value(i+1,2), NodesLast.Value(i,2)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2), NodesLast.Value(i+1,2), NodesLast.Value(i+1,2)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } // if( (drl+addv) > 0 ) @@ -1907,10 +2037,18 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, if(IsQuadratic) { aVec[6] = nbFaces; aVec[0] = nbNodes + nbFaces*4; + if( aNbNodes.size()==5 ) { + aVec[4] = aNbNodes[3] - 1; + aVec[6] = nbFaces - aNbNodes[3] + 1; + } } else { aVec[0] = nbNodes; aVec[5] = nbFaces; + if( aNbNodes.size()==5 ) { + aVec[3] = aNbNodes[3] - 1; + aVec[5] = nbFaces - aNbNodes[3] + 1; + } } SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); @@ -1938,15 +2076,17 @@ void StdMeshers_Quadrangle_2D::SplitQuad(SMESHDS_Mesh *theMeshDS, SMDS_MeshFace* face; if(a.Distance(c) > b.Distance(d)){ face = myTool->AddFace(theNode2, theNode4 , theNode1); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); face = myTool->AddFace(theNode2, theNode3, theNode4); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); } else{ face = myTool->AddFace(theNode1, theNode2 ,theNode3); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); face = myTool->AddFace(theNode1, theNode3, theNode4); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); } } + + diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 6c26fde4a..25083af32 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -121,11 +121,14 @@ protected: // true if QuadranglePreference hypothesis is assigned that forces // construction of quadrangles if the number of nodes on opposite edges - // is not the same in the case where the global number of nodes on edges is even + // is not the same in the case where the global number of nodes on edges + // is even bool myQuadranglePreference; bool myTrianglePreference; + int myTriaVertexID; + SMESH_MesherHelper* myTool; // tool for working with quadratic elements }; diff --git a/src/StdMeshersGUI/Makefile.am b/src/StdMeshersGUI/Makefile.am index 6d1ceae87..8e31360dc 100644 --- a/src/StdMeshersGUI/Makefile.am +++ b/src/StdMeshersGUI/Makefile.am @@ -36,7 +36,8 @@ salomeinclude_HEADERS = \ StdMeshersGUI_NbSegmentsCreator.h \ StdMeshersGUI_ObjectReferenceParamWdg.h \ StdMeshersGUI_LayerDistributionParamWdg.h \ - StdMeshersGUI_EdgeDirectionParamWdg.h + StdMeshersGUI_EdgeDirectionParamWdg.h \ + StdMeshersGUI_SubShapeSelectorWdg.h # Libraries targets lib_LTLIBRARIES = libStdMeshersGUI.la @@ -48,7 +49,8 @@ dist_libStdMeshersGUI_la_SOURCES = \ StdMeshersGUI_NbSegmentsCreator.cxx \ StdMeshersGUI_ObjectReferenceParamWdg.cxx \ StdMeshersGUI_LayerDistributionParamWdg.cxx \ - StdMeshersGUI_EdgeDirectionParamWdg.cxx + StdMeshersGUI_EdgeDirectionParamWdg.cxx \ + StdMeshersGUI_SubShapeSelectorWdg.cxx MOC_FILES = \ StdMeshersGUI_StdHypothesisCreator_moc.cxx \ @@ -57,7 +59,8 @@ MOC_FILES = \ StdMeshersGUI_NbSegmentsCreator_moc.cxx \ StdMeshersGUI_ObjectReferenceParamWdg_moc.cxx \ StdMeshersGUI_LayerDistributionParamWdg_moc.cxx \ - StdMeshersGUI_EdgeDirectionParamWdg_moc.cxx + StdMeshersGUI_EdgeDirectionParamWdg_moc.cxx \ + StdMeshersGUI_SubShapeSelectorWdg_moc.cxx nodist_libStdMeshersGUI_la_SOURCES= \ $(MOC_FILES) diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx index d89746054..93b3ca60a 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx @@ -26,7 +26,7 @@ #include "StdMeshersGUI_NbSegmentsCreator.h" #include "StdMeshersGUI_DistrTable.h" #include "StdMeshersGUI_DistrPreview.h" -#include "StdMeshersGUI_EdgeDirectionParamWdg.h" +#include "StdMeshersGUI_SubShapeSelectorWdg.h" #include #include @@ -200,7 +200,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() myReversedEdgesBox = new QGroupBox(tr( "SMESH_REVERCE_EDGES" ), fr); QHBoxLayout* edgeLay = new QHBoxLayout( myReversedEdgesBox ); - myDirectionWidget = new StdMeshersGUI_EdgeDirectionParamWdg(); + myDirectionWidget = new StdMeshersGUI_SubShapeSelectorWdg(); QString anEntry = getShapeEntry(); if ( anEntry == "" ) anEntry = h->GetObjectEntry(); diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h index 188674497..6053e8d34 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h @@ -44,7 +44,7 @@ class QButtonGroup; class QGroupBox; class QGridLayout; class QRadioButton; -class StdMeshersGUI_EdgeDirectionParamWdg; +class StdMeshersGUI_SubShapeSelectorWdg; typedef struct { @@ -94,7 +94,7 @@ private: QRadioButton* myCutNeg; QGroupBox* myReversedEdgesBox; - StdMeshersGUI_EdgeDirectionParamWdg* myDirectionWidget; + StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget; }; #endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx index 66976e317..43563ea45 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx @@ -33,7 +33,8 @@ #include #include "StdMeshersGUI_ObjectReferenceParamWdg.h" #include "StdMeshersGUI_LayerDistributionParamWdg.h" -#include "StdMeshersGUI_EdgeDirectionParamWdg.h" +//#include "StdMeshersGUI_EdgeDirectionParamWdg.h" +#include "StdMeshersGUI_SubShapeSelectorWdg.h" #include // SALOME GUI includes @@ -445,8 +446,10 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const StdMeshers::StdMeshers_Arithmetic1D_var h = StdMeshers::StdMeshers_Arithmetic1D::_narrow( hypothesis() ); - StdMeshersGUI_EdgeDirectionParamWdg* w = - widget< StdMeshersGUI_EdgeDirectionParamWdg >( 2 ); + //StdMeshersGUI_EdgeDirectionParamWdg* w = + // widget< StdMeshersGUI_EdgeDirectionParamWdg >( 2 ); + StdMeshersGUI_SubShapeSelectorWdg* w = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 ); h->SetStartLength( params[0].myValue.toDouble() ); h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); @@ -478,8 +481,8 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const StdMeshers::StdMeshers_StartEndLength_var h = StdMeshers::StdMeshers_StartEndLength::_narrow( hypothesis() ); - StdMeshersGUI_EdgeDirectionParamWdg* w = - widget< StdMeshersGUI_EdgeDirectionParamWdg >( 2 ); + StdMeshersGUI_SubShapeSelectorWdg* w = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 ); h->SetStartLength( params[0].myValue.toDouble() ); h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); @@ -557,6 +560,20 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const geomFromWdg ( getWidgetForParam( 3 )), // tgt1 geomFromWdg ( getWidgetForParam( 5 ))); // tgt2 } + else if( hypType()=="QuadrangleParams" ) + { + StdMeshers::StdMeshers_QuadrangleParams_var h = + StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() ); + StdMeshersGUI_SubShapeSelectorWdg* w = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 ); + if (w) { + if( w->GetListOfIDs()->length()>0 ) { + h->SetTriaVertex( w->GetListOfIDs()[0] ); + } + const char * entry = w->GetMainShapeEntry(); + h->SetObjectEntry( entry ); + } + } } return valueStr; } @@ -678,7 +695,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_REVERCE_EDGES" ); p.append( item ); - StdMeshersGUI_EdgeDirectionParamWdg* aDirectionWidget = new StdMeshersGUI_EdgeDirectionParamWdg(); + //StdMeshersGUI_EdgeDirectionParamWdg* aDirectionWidget = + // new StdMeshersGUI_EdgeDirectionParamWdg(); + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); if ( anEntry == "" ) anEntry = h->GetObjectEntry(); @@ -729,7 +749,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_REVERCE_EDGES" ); p.append( item ); - StdMeshersGUI_EdgeDirectionParamWdg* aDirectionWidget = new StdMeshersGUI_EdgeDirectionParamWdg(); + //StdMeshersGUI_EdgeDirectionParamWdg* aDirectionWidget = + // new StdMeshersGUI_EdgeDirectionParamWdg(); + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); if ( anEntry == "" ) anEntry = h->GetObjectEntry(); @@ -854,6 +877,32 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ), h->GetTargetVertex( 2 ))); } + else if( hypType()=="QuadrangleParams" ) + { + StdMeshers::StdMeshers_QuadrangleParams_var h = + StdMeshers::StdMeshers_QuadrangleParams::_narrow( hyp ); + + item.myName = tr( "SMESH_BASE_VERTEX" ); + p.append( item ); + + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); + aDirectionWidget->SetMaxSize(1); + aDirectionWidget->SetSubShType(TopAbs_VERTEX); + QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); + if ( anEntry == "" ) + anEntry = h->GetObjectEntry(); + aDirectionWidget->SetMainShapeEntry( anEntry ); + SMESH::long_array_var aVec = new SMESH::long_array; + int vertID = h->GetTriaVertex(); + if(vertID>0) { + aVec->length(1); + aVec[0] = vertID; + } + aDirectionWidget->SetListOfIDs( aVec ); + aDirectionWidget->showPreview( true ); + customWidgets()->append ( aDirectionWidget ); + } else res = false; return res; @@ -974,6 +1023,7 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" ); types.insert( "SegmentLengthAroundVertex", "SEGMENT_LENGTH_AROUND_VERTEX" ); types.insert( "MaxLength", "MAX_LENGTH" ); + types.insert( "QuadrangleParams", "QUADRANGLE_PARAMS" ); } QString res; @@ -1046,10 +1096,17 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa param.myValue = w->GetValue(); return true; } - if ( widget->inherits( "StdMeshersGUI_EdgeDirectionParamWdg" )) + //if ( widget->inherits( "StdMeshersGUI_EdgeDirectionParamWdg" )) + //{ + // const StdMeshersGUI_EdgeDirectionParamWdg * w = + // static_cast( widget ); + // param.myValue = w->GetValue(); + // return true; + //} + if ( widget->inherits( "StdMeshersGUI_SubShapeSelectorWdg" )) { - const StdMeshersGUI_EdgeDirectionParamWdg * w = - static_cast( widget ); + const StdMeshersGUI_SubShapeSelectorWdg * w = + static_cast( widget ); param.myValue = w->GetValue(); return true; } diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx new file mode 100644 index 000000000..b5b8b6490 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -0,0 +1,427 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_SubShapeSelectorWdg.cxx +// Author : Open CASCADE S.A.S. (dmv) +// SMESH includes +// +#include "StdMeshersGUI_SubShapeSelectorWdg.h" + +// SMESH Includes +#include +#include "SMESHGUI_MeshUtils.h" +#include +#include +#include +#include "SMESHGUI_GroupUtils.h" +#include "SMESH_Gen_i.hxx" +#include "SMESHGUI_GEOMGenUtils.h" + +// SVTK Includes +#include +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include + +// SUIT Includes +#include + +// GEOM Includes +#include + +// Qt includes +#include +#include +#include +#include +#include + +// OCCT includes +#include +#include +#include +#include +#include + +// SALOME KERNEL includes +#include + +#define SPACING 6 +#define MARGIN 0 + +//================================================================================ +/*! + * Constructor + */ +//================================================================================ + +StdMeshersGUI_SubShapeSelectorWdg +::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent ): + QWidget( parent ) +{ + QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) ); + + QGridLayout* edgesLayout = new QGridLayout( this ); + edgesLayout->setMargin( MARGIN ); + edgesLayout->setSpacing( SPACING ); + + myListWidget = new QListWidget( this ); + myAddButton = new QPushButton( tr( "SMESH_BUT_ADD" ), this ); + myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this ); + myListWidget->setSelectionMode( QListWidget::ExtendedSelection ); + + edgesLayout->addWidget(myListWidget, 0, 0, 3, 3); + edgesLayout->addWidget(myAddButton, 0, 4); + edgesLayout->addWidget(myRemoveButton, 1, 4); + + edgesLayout->setRowStretch(2, 5); + edgesLayout->setColumnStretch(2, 5); + + setLayout( edgesLayout ); + setMinimumWidth( 300 ); + + myMaxSize = 1000; + mySubShType = TopAbs_EDGE; + + init(); +} + +//================================================================================ +/*! + * Destructor + */ +//================================================================================ + +StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg() +{ + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { + myPreviewActor->RemoveFromRender( myRenderer ); + aViewWindow->Repaint(); + } + myEntry = ""; + myParamValue = ""; + myMainShape.Nullify(); + + delete myPreviewActor; +} + +//================================================================================ +/*! + * Create a layout, initialize fields + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::init() +{ + myParamValue = ""; + myListOfIDs.clear(); + mySelectedIDs.clear(); + + mySMESHGUI = SMESHGUI::GetSMESHGUI(); + mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI ); + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + + connect( myAddButton, SIGNAL(clicked()), SLOT(onAdd())); + connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove())); + + connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + connect( myListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); + + updateState(); +} + +//================================================================================ +/*! + * Create a layout, initialize fields + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible) +{ + if ( myIsShown != visible ) { + myPreviewActor->SetShown( visible ); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->Repaint(); + + myIsShown = visible; + } +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument() +{ + mySelectedIDs.clear(); + + // get selected mesh + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + int nbSel = aList.Extent(); + + if (nbSel < 1) + return; + + SALOME_ListIteratorOfListIO anIt (aList); + + for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects + Handle(SALOME_InteractiveObject) IO = anIt.Value(); + + GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() ); + if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study + GEOM::GEOM_Object_ptr aGeomFatherObj = aGeomObj->GetMainShape(); + QString aFatherEntry = ""; + QString aMainFatherEntry = ""; + TopoDS_Shape shape; + if ( !CORBA::is_nil( aGeomFatherObj ) ) { + // Get Main Shape + GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry ); + if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) { // Main Shape is a Group + GEOM::GEOM_Object_ptr aMainFatherObj = aGeomMain->GetMainShape(); + if ( !CORBA::is_nil( aMainFatherObj ) ) + aMainFatherEntry = aMainFatherObj->GetStudyEntry(); + } + aFatherEntry = aGeomFatherObj->GetStudyEntry(); + } + + if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) { + if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object + GEOMBase::GetShape(aGeomObj, shape); + if ( !shape.IsNull() ) { + TopExp_Explorer exp( shape, mySubShType ); + for ( ; exp.More(); exp.Next() ) { + int index = myPreviewActor->GetIndexByShape( exp.Current() ); + if ( index ) { + mySelectedIDs.append( index ); + myPreviewActor->HighlightID( index ); + } + } + } + } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ ) { + GEOMBase::GetShape(aGeomObj, shape); + if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) { + int index = myPreviewActor->GetIndexByShape( shape ); + if ( index ) { + mySelectedIDs.append( index ); + myPreviewActor->HighlightID( index ); + } + } + } + } + } else { // Selected Actor from Actor Collection + QString anEntry = IO->getEntry(); + QString str = "_"; + int index = anEntry.lastIndexOf( str ); + anEntry.remove(0, index+1); + int ind = anEntry.toInt(); + if ( ind ) + mySelectedIDs.append( ind ); + } + } +} + +//================================================================================= +// function : onAdd() +// purpose : Called when Add Button Clicked +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onAdd() +{ + if ( mySelectedIDs.size() < 1 ) + return; + + myListWidget->blockSignals( true ); + for (int i = 0; i < mySelectedIDs.size(); i++) { + if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) { + QString anID = QString(" %1").arg( mySelectedIDs.at(i) ); + + QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget ); + anItem->setSelected(true); + + myListOfIDs.append( mySelectedIDs.at(i) ); + } + } + onListSelectionChanged(); + + myListWidget->blockSignals( false ); + + if( myListOfIDs.size() >= myMaxSize ) + myAddButton->setEnabled( false ); +} + +//================================================================================= +// function : onRemove() +// purpose : Called when Remove Button Clicked +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onRemove() +{ + if ( myListWidget->count() < 1 ) + return; + + myListWidget->blockSignals( true ); + QList selItems = myListWidget->selectedItems(); + QListWidgetItem* item; + foreach(item, selItems) { + QString idStr = item->text(); + int id = idStr.toInt(); + + int index = myListOfIDs.indexOf( id ); + myListOfIDs.removeAt( index ); + delete item; + } + + onListSelectionChanged(); + myListWidget->blockSignals( false ); + + myAddButton->setEnabled( true ); +} + +//================================================================================= +// function : onListSelectionChanged() +// purpose : Called when selection in element list is changed +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged() +{ + mySelectionMgr->clearSelected(); + TColStd_MapOfInteger aIndexes; + QList selItems = myListWidget->selectedItems(); + QListWidgetItem* anItem; + foreach(anItem, selItems) + myPreviewActor->HighlightID( anItem->text().toInt() ); +} + +//================================================================================= +// function : setGeomShape +// purpose : Called to set geometry +//================================================================================ +void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry ) +{ + if ( theEntry != "") { + myParamValue = theEntry; + myEntry = theEntry; + myMainShape = GetTopoDSByEntry( theEntry ); + updateState(); + } +} + +//================================================================================= +// function : updateState +// purpose : update Widget state +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::updateState() +{ + bool state = false; + if ( !myMainShape.IsNull() ) + state = true; + + myListWidget->setEnabled( state ); + myAddButton->setEnabled( state ); + myRemoveButton->setEnabled( state ); + + if (state = true) { + myPreviewActor = new SMESH_PreviewActorsCollection(); + myPreviewActor->SetSelector( mySelector ); + //myPreviewActor->Init( myMainShape, TopAbs_EDGE, myEntry ); + myPreviewActor->Init( myMainShape, mySubShType, myEntry ); + myPreviewActor->SetShown( false ); + myIsShown = false; + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { + myRenderer = aViewWindow->getRenderer(); + myPreviewActor->AddToRender( myRenderer ); + aViewWindow->Repaint(); + } + } +} + +//================================================================================= +// function : GetGeomObjectByEntry +// purpose : Called to get GeomObject +//================================================================================= +GEOM::GEOM_Object_var StdMeshersGUI_SubShapeSelectorWdg::GetGeomObjectByEntry( const QString& theEntry ) +{ + GEOM::GEOM_Object_var aGeomObj; + SALOMEDS::Study_var aStudy = SMESHGUI::GetSMESHGen()->GetCurrentStudy(); + if (aStudy != 0) { + SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( theEntry.toLatin1().data() ); + SALOMEDS::GenericAttribute_var anAttr; + + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + } + } + return aGeomObj; +} + +//================================================================================= +// function : setObjectByEntry +// purpose : Called to get GeomObject +//================================================================================= +TopoDS_Shape StdMeshersGUI_SubShapeSelectorWdg::GetTopoDSByEntry( const QString& theEntry ) +{ + TopoDS_Shape shape; + GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry ); + GEOMBase::GetShape(aGeomObj, shape); + return shape; +} + +//================================================================================= +// function : GetListOfIds +// purpose : Called to get the list of SubShapes IDs +//================================================================================= +SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs() +{ + SMESH::long_array_var anArray = new SMESH::long_array; + int size = myListOfIDs.size(); + anArray->length( size ); + if ( size ) { + for (int i = 0; i < size; i++) { + anArray[i] = myListOfIDs.at(i); + } + } + return anArray; +} + +//================================================================================= +// function : SetListOfIds +// purpose : Called to set the list of SubShapes IDs +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds) +{ + mySelectedIDs.clear(); + myListOfIDs.clear(); + int size = theIds->length(); + for ( int i = 0; i < size; i++ ) + mySelectedIDs.append( theIds[ i ] ); + onAdd(); +} + diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h new file mode 100644 index 000000000..6447516fb --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h @@ -0,0 +1,115 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_SubShapeSelectorWdg.h +// Author : Open CASCADE S.A.S. (dmv) +// +#ifndef STDMESHERSGUI_SUBSHAPESELECTORWDG_H +#define STDMESHERSGUI_SUBSHAPESELECTORWDG_H + +// SMESH includes +#include +#include "SMESH_StdMeshersGUI.hxx" +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include +#include +#include + +#include + +class SMESHGUI; +class LightApp_SelectionMgr; +class SVTK_Selector; +class QPushButton; +class QLineEdit; +class QCheckBox; +class QListWidget; +class SMESH_Actor; +class SMESH_PreviewActorsCollection; +class vtkRenderer; + +class STDMESHERSGUI_EXPORT StdMeshersGUI_SubShapeSelectorWdg : public QWidget +{ + Q_OBJECT + +public: + StdMeshersGUI_SubShapeSelectorWdg( QWidget* parent = 0 ); + ~StdMeshersGUI_SubShapeSelectorWdg(); + + SMESH::long_array_var GetListOfIDs(); + void SetListOfIDs( SMESH::long_array_var ); + + void SetMainShapeEntry( const QString& theEntry ); + const char* GetMainShapeEntry() { return myEntry.toLatin1().data();} + + TopoDS_Shape GetMainShape() { return myMainShape; } + + static GEOM::GEOM_Object_var GetGeomObjectByEntry( const QString& ); + static TopoDS_Shape GetTopoDSByEntry( const QString& ); + + QString GetValue() const { return myParamValue; } + + void showPreview ( bool ); + + void SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; } + void SetSubShType(TopAbs_ShapeEnum aSubShType) { mySubShType = aSubShType; } + +private: + void updateState(); + +private slots: + void onAdd(); + void onRemove(); + void SelectionIntoArgument(); + void onListSelectionChanged(); + +private: + void init(); + +private: + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + SVTK_Selector* mySelector; + SMESH::SMESH_Mesh_var myMesh; + TopoDS_Shape myMainShape; + QString myEntry; + vtkRenderer* myRenderer; + + QListWidget* myListWidget; + QPushButton* myAddButton; + QPushButton* myRemoveButton; + QList mySelectedIDs; + QList myListOfIDs; + + QString myParamValue; + bool myIsShown; + + // for manage possible size of myListOfIDs + int myMaxSize; + // for manage type of selected subshape + TopAbs_ShapeEnum mySubShType; + + SMESH_PreviewActorsCollection* myPreviewActor; +}; + +#endif // STDMESHERSGUI_SUBSHAPESELECTORWDG_H diff --git a/src/StdMeshersGUI/StdMeshers_images.ts b/src/StdMeshersGUI/StdMeshers_images.ts index 132661aa0..cb63c4f18 100644 --- a/src/StdMeshersGUI/StdMeshers_images.ts +++ b/src/StdMeshersGUI/StdMeshers_images.ts @@ -217,5 +217,9 @@ ICON_SMESH_TREE_HYPO_StartEndLength mesh_tree_hypo_length.png + + ICON_DLG_QUADRANGLE_PARAMS + mesh_hypo_length.png + diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts index 30651e813..e49d525e8 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.ts +++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts @@ -249,6 +249,10 @@ SMESH_REVERCE_EDGES Reverce Edges + + SMESH_BASE_VERTEX + Base vertex + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS Segment Length Around Vertex @@ -317,6 +321,14 @@ SMESH_TARGET_VERTEX2 Target Vertex 2 + + SMESH_QUADRANGLE_PARAMS_HYPOTHESIS + Quadrangle parameters + + + SMESH_QUADRANGLE_PARAMS_TITLE + Hypothesis Construction + StdMeshersGUI_LayerDistributionParamWdg diff --git a/src/StdMeshers_I/Makefile.am b/src/StdMeshers_I/Makefile.am index 526d71fc5..0238db867 100644 --- a/src/StdMeshers_I/Makefile.am +++ b/src/StdMeshers_I/Makefile.am @@ -60,6 +60,7 @@ salomeinclude_HEADERS = \ StdMeshers_UseExisting_1D2D_i.hxx \ StdMeshers_TrianglePreference_i.hxx \ StdMeshers_MaxLength_i.hxx \ + StdMeshers_QuadrangleParams_i.hxx \ SMESH_StdMeshers_I.hxx # Libraries targets @@ -97,7 +98,8 @@ dist_libStdMeshersEngine_la_SOURCES = \ StdMeshers_SegmentLengthAroundVertex_i.cxx \ StdMeshers_UseExisting_1D2D_i.cxx \ StdMeshers_TrianglePreference_i.cxx \ - StdMeshers_MaxLength_i.cxx + StdMeshers_MaxLength_i.cxx \ + StdMeshers_QuadrangleParams_i.cxx # additionnal information to compil and link file libStdMeshersEngine_la_CPPFLAGS = \ diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx new file mode 100644 index 000000000..9113359b6 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx @@ -0,0 +1,188 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_QuadrangleParams_i.cxx +// Author : Sergey KUUL, OCC +// Module : SMESH +// $Header$ +// +#include "StdMeshers_QuadrangleParams_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i + (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i" ); + myBaseImpl = new ::StdMeshers_QuadrangleParams(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i" ); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::SetTriaVertex + * + * Set base vertex for triangles + */ +//============================================================================= + +void StdMeshers_QuadrangleParams_i::SetTriaVertex(CORBA::Long vertID) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetTriaVertex" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetTriaVertex( vertID ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + /* SMESH::TPythonDump() << _this() << ".SetEdgesToReverse( " + << theList << " )";*/ +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_QuadrangleParams_i::SetObjectEntry( const char* entry ) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + + try { + this->GetImpl()->SetObjectEntry( entry ); + // Update Python script + // SMESH::TPythonDump() << _this() << ".SetObjectEntry( '" << entry << "' )"; + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_QuadrangleParams_i::GetObjectEntry() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetTriaVertex + * + * Get base vertex for triangles + */ +//============================================================================= + +CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetTriaVertex(); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_QuadrangleParams* StdMeshers_QuadrangleParams_i::GetImpl() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::GetImpl" ); + return ( ::StdMeshers_QuadrangleParams* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean StdMeshers_QuadrangleParams_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} + diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx new file mode 100644 index 000000000..ed2977f19 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2008 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_QuadrangleParams_i.hxx +// Author : Sergey KUUL, OCC +// Module : SMESH +// $Header$ +// +#ifndef _SMESH_QUADRANGLEPARAMS_I_HXX_ +#define _SMESH_QUADRANGLEPARAMS_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + +// ====================================================== +// QuadrangleParams hypothesis +// ====================================================== +class STDMESHERS_I_EXPORT StdMeshers_QuadrangleParams_i: + public virtual POA_StdMeshers::StdMeshers_QuadrangleParams, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_QuadrangleParams_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_QuadrangleParams_i(); + + // Set length + //void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) + // throw ( SALOME::SALOME_Exception ); + + // Get length + //CORBA::Double GetLength(CORBA::Boolean theIsStart); + + //Set base vertex for triangles + void SetTriaVertex(CORBA::Long vertID); + + //Get base vertex for triangles + CORBA::Long GetTriaVertex(); + + //Set the Entry of the Object + void SetObjectEntry(const char* theEntry); + + //Get Object Entry + char* GetObjectEntry(); + + // Get implementation + ::StdMeshers_QuadrangleParams* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index 8d73b56d8..c17dfa98b 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -51,6 +51,7 @@ #include "StdMeshers_LayerDistribution_i.hxx" #include "StdMeshers_SegmentLengthAroundVertex_i.hxx" #include "StdMeshers_MaxLength_i.hxx" +#include "StdMeshers_QuadrangleParams_i.hxx" #include "StdMeshers_Regular_1D_i.hxx" #include "StdMeshers_MEFISTO_2D_i.hxx" @@ -127,6 +128,8 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "SegmentLengthAroundVertex") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "QuadrangleParams") == 0) + aCreator = new StdHypothesisCreator_i; // Algorithms else if (strcmp(aHypName, "Regular_1D") == 0) -- 2.30.2