From: admin Date: Tue, 13 Sep 2005 11:31:53 +0000 (+0000) Subject: This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. X-Git-Tag: BR-D5-38-2003_D2005-12-10~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=fe629a0269417f4f1eb2d1e6bbb994a1d7e4bbd9;p=modules%2Fsmesh.git This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. Cherrypick from master 2005-09-13 11:31:52 UTC jfa 'Rool-back bad changes to the script': idl/SMESH_Hypothesis.idl resources/mesh_hypo_edit.png resources/mesh_merge_elements.png src/Driver/Driver_Mesh.h src/Driver/Driver_SMESHDS_Mesh.h src/DriverMED/DriverMED_Family.cxx src/SMDS/SMDS_EdgePosition.hxx src/SMDS/SMDS_FacePosition.hxx src/SMDS/SMDS_Mesh.cxx src/SMDS/SMDS_Mesh.hxx src/SMDS/SMDS_MeshElement.hxx src/SMDS/SMDS_MeshGroup.hxx src/SMDS/SMDS_MeshNode.hxx src/SMDS/SMDS_MeshObject.hxx src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx src/SMDS/SMDS_Position.hxx src/SMDS/SMDS_SpacePosition.hxx src/SMDS/SMDS_VertexPosition.hxx src/SMESH/SMESH_HypoFilter.cxx src/SMESH/SMESH_HypoFilter.hxx src/SMESHDS/SMESHDS_Mesh.cxx src/SMESHDS/SMESHDS_SubMesh.cxx src/SMESHDS/SMESHDS_SubMesh.hxx src/SMESHGUI/SMESHGUI.cxx src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx src/SMESHGUI/SMESHGUI_GroupDlg.cxx src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx src/SMESHGUI/SMESHGUI_Selection.cxx src/SMESHGUI/SMESHGUI_VTKUtils.cxx src/SMESH_I/SMESH_1D_Algo_i.cxx src/SMESH_I/SMESH_1D_Algo_i.hxx src/SMESH_I/SMESH_2D_Algo_i.cxx src/SMESH_I/SMESH_2D_Algo_i.hxx src/SMESH_I/SMESH_3D_Algo_i.cxx src/SMESH_I/SMESH_3D_Algo_i.hxx src/SMESH_I/SMESH_Mesh_i.hxx src/SMESH_I/SMESH_subMesh_i.cxx src/SMESH_I/SMESH_subMesh_i.hxx src/SMESH_SWIG/Makefile.in src/SMESH_SWIG/SMESH_test.py src/StdMeshers/StdMeshers_Hexa_3D.cxx src/StdMeshers/StdMeshers_MEFISTO_2D.cxx src/StdMeshers/StdMeshers_Penta_3D.cxx src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx src/StdMeshers_I/StdMeshers_LocalLength_i.hxx src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx src/StdMeshers_I/StdMeshers_Propagation_i.cxx src/StdMeshers_I/StdMeshers_Propagation_i.hxx src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx --- diff --git a/idl/SMESH_Hypothesis.idl b/idl/SMESH_Hypothesis.idl new file mode 100644 index 000000000..69832b9ed --- /dev/null +++ b/idl/SMESH_Hypothesis.idl @@ -0,0 +1,102 @@ +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Hypothesis.idl +// Author : Paul RASCLE, EDF +// $Header$ + +#ifndef _SMESH_HYPOTHESIS_IDL_ +#define _SMESH_HYPOTHESIS_IDL_ + +#include "SALOME_Exception.idl" +#include "SALOME_GenericObj.idl" + +module SMESH +{ + enum Dimension + { + DIM_1D, + DIM_2D, + DIM_3D + }; + + interface SMESH_Hypothesis : SALOME::GenericObj + { + /*! + * Get the Hypothesis typeName + */ + string GetName(); + + /*! + * Get the Hypothesis plugin library Name + */ + string GetLibName(); + + /*! + * Get the internal Id + */ + long GetId(); + + /*! + * Verify whether hypothesis supports given entity type + */ + boolean IsDimSupported( in Dimension type ); + }; + + typedef sequence ListOfHypothesisName; + + interface SMESH_Algo : SMESH_Hypothesis + { + /*! + * Get list of hypothesis that can be used with this algorithm + */ + ListOfHypothesisName GetCompatibleHypothesis(); + + }; + + interface SMESH_1D_Algo : SMESH_Algo + { + /*! + * + */ + }; + + interface SMESH_2D_Algo : SMESH_Algo + { + /*! + * + */ + }; + + interface SMESH_3D_Algo : SMESH_Algo + { + /*! + * + */ + }; +}; + + // ----------------------------------------------------------------- + // Specific Algorithms in separate idl file + // ----------------------------------------------------------------- + + +#endif diff --git a/resources/mesh_hypo_edit.png b/resources/mesh_hypo_edit.png new file mode 100644 index 000000000..8f61dea7c Binary files /dev/null and b/resources/mesh_hypo_edit.png differ diff --git a/resources/mesh_merge_elements.png b/resources/mesh_merge_elements.png new file mode 100644 index 000000000..3bc292fc4 Binary files /dev/null and b/resources/mesh_merge_elements.png differ diff --git a/src/Driver/Driver_Mesh.h b/src/Driver/Driver_Mesh.h new file mode 100644 index 000000000..14ca22fd1 --- /dev/null +++ b/src/Driver/Driver_Mesh.h @@ -0,0 +1,63 @@ +// SMESH Driver : implementaion of driver for reading and writing +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Mesh_Reader.h +// Module : SMESH + +#ifndef _INCLUDE_DRIVER_MESH +#define _INCLUDE_DRIVER_MESH + +#include + +#if defined WNT && defined WIN32 && defined DRIVER_EXPORTS +#define DRIVER_WNT_EXPORT __declspec( dllexport ) +#else +#define DRIVER_WNT_EXPORT +#endif + +class DRIVER_WNT_EXPORT Driver_Mesh +{ + public: + Driver_Mesh(); + virtual ~Driver_Mesh(){} + + enum Status { + DRS_OK, + DRS_EMPTY, // a file contains no mesh with the given name + DRS_WARN_RENUMBER, // a file has overlapped ranges of element numbers, + // so the numbers from the file are ignored + DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data + DRS_FAIL // general failure (exception etc.) + }; + + virtual Status Perform() = 0; + void SetMeshId(int theMeshId); + void SetFile(const std::string& theFileName); + + protected: + std::string myFile; + int myMeshId; + +}; + +#endif diff --git a/src/Driver/Driver_SMESHDS_Mesh.h b/src/Driver/Driver_SMESHDS_Mesh.h new file mode 100644 index 000000000..30e059522 --- /dev/null +++ b/src/Driver/Driver_SMESHDS_Mesh.h @@ -0,0 +1,44 @@ +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef _INCLUDE_DRIVER_SMESHDS_MESH +#define _INCLUDE_DRIVER_SMESHDS_MESH + +#include "Driver_Mesh.h" + +class SMESHDS_Mesh; + +#if defined WNT && defined WIN32 && defined DRIVER_EXPORTS +#define DRIVER_WNT_EXPORT __declspec( dllexport ) +#else +#define DRIVER_WNT_EXPORT +#endif + +class DRIVER_WNT_EXPORT Driver_SMESHDS_Mesh: public Driver_Mesh +{ + public: + Driver_SMESHDS_Mesh(); + void SetMesh(SMESHDS_Mesh *theMesh); + + protected: + SMESHDS_Mesh *myMesh; + +}; + +#endif diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx new file mode 100644 index 000000000..47a923dbd --- /dev/null +++ b/src/DriverMED/DriverMED_Family.cxx @@ -0,0 +1,390 @@ +// SMESH DriverMED : tool to split groups on families +// +// Copyright (C) 2003 CEA +// +// 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.org +// +// +// +// File : DriverMED_Family.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#include "DriverMED_Family.h" +#include "MED_Factory.hxx" + +#include + +using namespace std; + +//============================================================================= +/*! + * Split each group from list on some parts (families) + * on the basis of the elements membership in other groups from this list. + * Resulting families have no common elements. + */ +//============================================================================= +list DriverMED_Family::MakeFamilies + (const map & theSubMeshes, + const list& theGroups, + const bool doGroupOfNodes, + const bool doGroupOfEdges, + const bool doGroupOfFaces, + const bool doGroupOfVolumes) +{ + list aFamilies; + + string anAllNodesGroupName = "Group_Of_All_Nodes"; + string anAllEdgesGroupName = "Group_Of_All_Edges"; + string anAllFacesGroupName = "Group_Of_All_Faces"; + string anAllVolumesGroupName = "Group_Of_All_Volumes"; + + // Reserve four ids for families of free elements + // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes). + // 'Free' means here not belonging to any group. + int aNodeFamId = FIRST_NODE_FAMILY; + int aElemFamId = FIRST_ELEM_FAMILY; + + // Process sub-meshes + map::const_iterator aSMIter = theSubMeshes.begin(); + for (; aSMIter != theSubMeshes.end(); aSMIter++) + { + if ( aSMIter->second->IsComplexSubmesh() ) + continue; // submesh containing other submeshs + list aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first); + list::iterator aSMFamsIter = aSMFams.begin(); + for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++) + { + DriverMED_FamilyPtr aFam2 = (*aSMFamsIter); + + list::iterator aFamsIter = aFamilies.begin(); + while (aFamsIter != aFamilies.end()) + { + DriverMED_FamilyPtr aFam1 = *aFamsIter; + list::iterator aCurrIter = aFamsIter++; + if (aFam1->myType == aFam2->myType) + { + DriverMED_FamilyPtr aCommon (new DriverMED_Family); + aFam1->Split(aFam2, aCommon); + if (!aCommon->IsEmpty()) + { + aFamilies.push_back(aCommon); + } + if (aFam1->IsEmpty()) + { + aFamilies.erase(aCurrIter); + } + if (aFam2->IsEmpty()) break; + } + } + // The rest elements of family + if (!aFam2->IsEmpty()) + { + aFamilies.push_back(aFam2); + } + } + } + + // Process groups + list::const_iterator aGroupsIter = theGroups.begin(); + for (; aGroupsIter != theGroups.end(); aGroupsIter++) + { + DriverMED_FamilyPtr aFam2 (new DriverMED_Family); + aFam2->Init(*aGroupsIter); + + list::iterator aFamsIter = aFamilies.begin(); + while (aFamsIter != aFamilies.end()) + { + DriverMED_FamilyPtr aFam1 = *aFamsIter; + list::iterator aCurrIter = aFamsIter++; + if (aFam1->myType == aFam2->myType) + { + DriverMED_FamilyPtr aCommon (new DriverMED_Family); + aFam1->Split(aFam2, aCommon); + if (!aCommon->IsEmpty()) + { + aFamilies.push_back(aCommon); + } + if (aFam1->IsEmpty()) + { + aFamilies.erase(aCurrIter); + } + if (aFam2->IsEmpty()) break; + } + } + // The rest elements of group + if (!aFam2->IsEmpty()) + { + aFamilies.push_back(aFam2); + } + } + + list::iterator aFamsIter = aFamilies.begin(); + for (; aFamsIter != aFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFam = *aFamsIter; + if (aFam->myType == SMDSAbs_Node) { + aFam->SetId(aNodeFamId++); + if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName); + } + else { + aFam->SetId(aElemFamId--); + if (aFam->myType == SMDSAbs_Edge) { + if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName); + } + else if (aFam->myType == SMDSAbs_Face) { + if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName); + } + else if (aFam->myType == SMDSAbs_Volume) { + if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName); + } + } + } + + // Create families for elements, not belonging to any group + if (doGroupOfNodes) + { + DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family); + aFreeNodesFam->SetId(REST_NODES_FAMILY); + aFreeNodesFam->myType = SMDSAbs_Node; + aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName); + aFamilies.push_back(aFreeNodesFam); + } + + if (doGroupOfEdges) + { + DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family); + aFreeEdgesFam->SetId(REST_EDGES_FAMILY); + aFreeEdgesFam->myType = SMDSAbs_Edge; + aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName); + aFamilies.push_back(aFreeEdgesFam); + } + + if (doGroupOfFaces) + { + DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family); + aFreeFacesFam->SetId(REST_FACES_FAMILY); + aFreeFacesFam->myType = SMDSAbs_Face; + aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName); + aFamilies.push_back(aFreeFacesFam); + } + + if (doGroupOfVolumes) + { + DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family); + aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY); + aFreeVolumesFam->myType = SMDSAbs_Volume; + aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName); + aFamilies.push_back(aFreeVolumesFam); + } + + DriverMED_FamilyPtr aNullFam (new DriverMED_Family); + aNullFam->SetId(0); + aNullFam->myType = SMDSAbs_All; + aFamilies.push_back(aNullFam); + + return aFamilies; +} + +//============================================================================= +/*! + * Create TFamilyInfo for this family + */ +//============================================================================= +MED::PFamilyInfo +DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, + const MED::PMeshInfo& theMeshInfo) const +{ + string aValue; + + ostringstream aStr; + + aStr << "FAM_" << myId; + set::const_iterator aGrIter = myGroupNames.begin(); + for (; aGrIter != myGroupNames.end(); aGrIter++) + { + aStr << "_" << *aGrIter; + } + + aValue = aStr.str(); + /* + MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, + MED::TIntVector anAttrIds (1, myId); // Id=0, + MED::TIntVector anAttrVals (1, myId); // Value=0 + */ + + MED::PFamilyInfo anInfo = theWrapper->CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames); +/* + anAttrDescs, + anAttrIds, + anAttrVals); +*/ + +// cout << endl; +// cout << "Groups: "; +// set::iterator aGrIter = myGroupNames.begin(); +// for (; aGrIter != myGroupNames.end(); aGrIter++) +// { +// cout << " " << *aGrIter; +// } +// cout << endl; +// +// cout << "Elements: "; +// set::iterator anIter = myElements.begin(); +// for (; anIter != myElements.end(); anIter++) +// { +// cout << " " << (*anIter)->GetID(); +// } +// cout << endl; + + return anInfo; +} + +//============================================================================= +/*! + * Initialize the tool by SMESHDS_GroupBase + */ +//============================================================================= +void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup) +{ + // Elements + myElements.clear(); + SMDS_ElemIteratorPtr elemIt = theGroup->GetElements(); + while (elemIt->more()) + { + myElements.insert(elemIt->next()); + } + + // Type + myType = theGroup->GetType(); + + // Groups list + myGroupNames.clear(); + myGroupNames.insert(string(theGroup->GetStoreName())); +} + +//============================================================================= +/*! + * Split on some parts (families) + * on the basis of the elements type. + */ +//============================================================================= +list DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh, + const int theId) +{ + list aFamilies; + DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family); + DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family); + DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family); + DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family); + + char submeshGrpName[ 30 ]; + sprintf( submeshGrpName, "SubMesh %d", theId ); + + SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes(); + while (aNodesIter->more()) + { + const SMDS_MeshNode* aNode = aNodesIter->next(); + aNodesFamily->AddElement(aNode); + } + + SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements(); + while (anElemsIter->more()) + { + const SMDS_MeshElement* anElem = anElemsIter->next(); + switch (anElem->GetType()) + { + case SMDSAbs_Edge: + anEdgesFamily->AddElement(anElem); + break; + case SMDSAbs_Face: + aFacesFamily->AddElement(anElem); + break; + case SMDSAbs_Volume: + aVolumesFamily->AddElement(anElem); + break; + default: + break; + } + } + + if (!aNodesFamily->IsEmpty()) { + aNodesFamily->SetType(SMDSAbs_Node); + aNodesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aNodesFamily); + } + if (!anEdgesFamily->IsEmpty()) { + anEdgesFamily->SetType(SMDSAbs_Edge); + anEdgesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(anEdgesFamily); + } + if (!aFacesFamily->IsEmpty()) { + aFacesFamily->SetType(SMDSAbs_Face); + aFacesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aFacesFamily); + } + if (!aVolumesFamily->IsEmpty()) { + aVolumesFamily->SetType(SMDSAbs_Volume); + aVolumesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aVolumesFamily); + } + + return aFamilies; +} + +//============================================================================= +/*! + * Remove from elements, common with , + * Remove from elements, common with , + * Create family from common elements, with combined groups list. + */ +//============================================================================= +void DriverMED_Family::Split (DriverMED_FamilyPtr by, + DriverMED_FamilyPtr common) +{ + // Elements + set::iterator anIter = by->myElements.begin(); + while ( anIter != by->myElements.end()) + { + if (myElements.find(*anIter) != myElements.end()) + { + common->myElements.insert(*anIter); + myElements.erase(*anIter); + by->myElements.erase(anIter++); + } + else + anIter++; + } + + if (!common->IsEmpty()) + { + // Groups list + common->myGroupNames = myGroupNames; + set::iterator aGrNamesIter = by->myGroupNames.begin(); + for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++) + { + common->myGroupNames.insert(*aGrNamesIter); + } + + // Type + common->myType = myType; + } +} diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx new file mode 100644 index 000000000..fd297d3ab --- /dev/null +++ b/src/SMDS/SMDS_EdgePosition.hxx @@ -0,0 +1,60 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_EdgePosition.hxx +// Module : SMESH + +#ifndef _SMDS_EdgePosition_HeaderFile +#define _SMDS_EdgePosition_HeaderFile + +#include "SMDS_Position.hxx" + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_EdgePosition:public SMDS_Position +{ + + public: + SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0); + const virtual double * Coords() const; + SMDS_TypeOfPosition GetTypeOfPosition() const; + void SetUParameter(double aUparam); + double GetUParameter() const; + + private: + + double myUParameter; + +}; + +#endif diff --git a/src/SMDS/SMDS_FacePosition.hxx b/src/SMDS/SMDS_FacePosition.hxx new file mode 100644 index 000000000..8ca74130f --- /dev/null +++ b/src/SMDS/SMDS_FacePosition.hxx @@ -0,0 +1,61 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_FacePosition.hxx +// Module : SMESH + +#ifndef _SMDS_FacePosition_HeaderFile +#define _SMDS_FacePosition_HeaderFile + +#include "SMDS_Position.hxx" + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_FacePosition:public SMDS_Position +{ + + public: + SMDS_FacePosition(int aFaceId=0, double aUParam=0, + double aVParam=0); + const virtual double * Coords() const; + SMDS_TypeOfPosition GetTypeOfPosition() const; + void SetUParameter(double aUparam); + void SetVParameter(double aVparam); + double GetUParameter() const; + double GetVParameter() const; + + private: + double myUParameter; + double myVParameter; +}; +#endif diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx new file mode 100644 index 000000000..6381e547e --- /dev/null +++ b/src/SMDS/SMDS_Mesh.cxx @@ -0,0 +1,2203 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "utilities.h" +#include "SMDS_Mesh.hxx" +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VolumeOfFaces.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_FaceOfEdges.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_PolygonalFaceOfNodes.hxx" + +#include +#include +using namespace std; + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new mesh object +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh::SMDS_Mesh() + :myParent(NULL), + myNodeIDFactory(new SMDS_MeshElementIDFactory()), + myElementIDFactory(new SMDS_MeshElementIDFactory()), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new child mesh +/// Note that the tree structure of SMDS_Mesh seems to be unused in this version +/// (2003-09-08) of SMESH +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) + :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), + myElementIDFactory(parent->myElementIDFactory), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a submesh and add it to the current mesh +/////////////////////////////////////////////////////////////////////////////// + +SMDS_Mesh *SMDS_Mesh::AddSubMesh() +{ + SMDS_Mesh *submesh = new SMDS_Mesh(this); + myChildren.insert(myChildren.end(), submesh); + return submesh; +} + +/////////////////////////////////////////////////////////////////////////////// +///create a MeshNode and add it to the current Mesh +///An ID is automatically assigned to the node. +///@return : The created node +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) +{ + return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///create a MeshNode and add it to the current Mesh +///@param ID : The ID of the MeshNode to create +///@return : The created node or NULL if a node with this ID already exists +/////////////////////////////////////////////////////////////////////////////// +SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) +{ + // find the MeshNode corresponding to ID + const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); + if(!node){ + SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); + myNodes.Add(node); + myNodeIDFactory->BindID(ID,node); + return node; + }else + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a MeshEdge and add it to the current Mesh +/// @return : The created MeshEdge +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + if(!node1 || !node2) return NULL; + return SMDS_Mesh::AddEdgeWithID(node1, node2, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a MeshEdge and add it to the current Mesh +/// @return : The created MeshEdge +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new edge and at it to the mesh +/// @param idnode1 ID of the first node +/// @param idnode2 ID of the second node +/// @param ID ID of the edge to create +/// @return The created edge or NULL if an element with this ID already exists or +/// if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID) +{ + SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); + if(myElementIDFactory->BindID(ID, edge)) { + SMDS_MeshNode *node1,*node2; + node1=const_cast(n1); + node2=const_cast(n2); + node1->AddInverseElement(edge); + node2->AddInverseElement(edge); + myEdges.Add(edge); + return edge; + } + else { + delete edge; + return NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes. An ID is automatically affected to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + if(!node1 || !node2 || !node3) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its nodes +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) +{ + SMDS_MeshFace * face=createTriangle(n1, n2, n3); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes. An ID is automatically affected to the +/// created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + if(!node1 || !node2 || !node3 || !node4) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its nodes +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3) +{ + if (!hasConstructionEdges()) + return NULL; + return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); + myFaces.Add(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4) +{ + if (!hasConstructionEdges()) + return NULL; + return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); + myFaces.Add(face); + + if (!registerElement(ID, face)) + { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron and add it to the mesh. +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron and add it to the mesh. +///@param ID The ID of the new volume +///@return The created tetrahedron or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + if(!node1 || !node2 || !node3 || !node4) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron and add it to the mesh. +///@param ID The ID of the new volume +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.Add(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); + myVolumes.Add(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid and add it to the mesh. +///Nodes 1,2,3 and 4 define the base of the pyramid +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid and add it to the mesh. +///Nodes 1,2,3 and 4 define the base of the pyramid +///@param ID The ID of the new volume +///@return The created pyramid or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid and add it to the mesh. +///Nodes 1,2,3 and 4 define the base of the pyramid +///@param ID The ID of the new volume +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); + SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.Add(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); + myVolumes.Add(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism and add it to the mesh. +///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism and add it to the mesh. +///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. +///@param ID The ID of the new volume +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism and add it to the mesh. +///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); + SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + myVolumes.Add(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); + myVolumes.Add(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///@return The created hexahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///@param ID The ID of the new volume +///@return The created hexahedron or NULL if an element with this ID already +///exists or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8) + return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node7, node8, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexahedron and add it to the mesh. +///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. +///@param ID The ID of the new volume +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5); + SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); + SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + myVolumes.Add(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { +// volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); + myVolumes.Add(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, + const int ID) +{ + int nbNodes = nodes_ids.size(); + std::vector nodes (nbNodes); + for (int i = 0; i < nbNodes; i++) { + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + if (!nodes[i]) return NULL; + } + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID + (std::vector nodes, + const int ID) +{ + SMDS_MeshFace * face; + + if (hasConstructionEdges()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else + { + face = new SMDS_PolygonalFaceOfNodes(nodes); + myFaces.Add(face); + } + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes. +/// An ID is automatically affected to the created face. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector nodes) +{ + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @param ID The ID of the new volume +/// @return The created volume or NULL if an element with this ID already exists +/// or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID + (std::vector nodes_ids, + std::vector quantities, + const int ID) +{ + int nbNodes = nodes_ids.size(); + std::vector nodes (nbNodes); + for (int i = 0; i < nbNodes; i++) { + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + if (!nodes[i]) return NULL; + } + return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @param ID The ID of the new volume +/// @return The created volume +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID + (std::vector nodes, + std::vector quantities, + const int ID) +{ + SMDS_MeshVolume* volume; + if (hasConstructionFaces()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else if (hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else { + volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); + myVolumes.Add(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @return The created volume +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume + (std::vector nodes, + std::vector quantities) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Registers element with the given ID, maintains inverse connections +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element) +{ + if (myElementIDFactory->BindID(ID, element)) { + SMDS_ElemIteratorPtr it = element->nodesIterator(); + while (it->more()) { + SMDS_MeshNode *node = static_cast + (const_cast(it->next())); + node->AddInverseElement(element); + } + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the node whose ID is 'ID'. +/////////////////////////////////////////////////////////////////////////////// +const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const +{ + return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a triangle and add it to the current mesh. This methode do not bind a +///ID to the create triangle. +/////////////////////////////////////////////////////////////////////////////// +SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) +{ + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node1); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); + myFaces.Add(face); + return face; + } + else + { + SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); + myFaces.Add(face); + return face; + } +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a quadrangle and add it to the current mesh. This methode do not bind +///a ID to the create triangle. +/////////////////////////////////////////////////////////////////////////////// +SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4) +{ + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node4); + edge4=FindEdgeOrCreate(node4,node1); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); + myFaces.Add(face); + return face; + } + else + { + SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); + myFaces.Add(face); + return face; + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove a node and all the elements which own this node +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) +{ + RemoveElement(node, true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove an edge and all the elements which own this edge +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) +{ + RemoveElement(edge,true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove an face and all the elements which own this face +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) +{ + RemoveElement(face, true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove a volume +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) +{ + RemoveElement(volume, true); +} + +//======================================================================= +//function : RemoveFromParent +//purpose : +//======================================================================= + +bool SMDS_Mesh::RemoveFromParent() +{ + if (myParent==NULL) return false; + else return (myParent->RemoveSubMesh(this)); +} + +//======================================================================= +//function : RemoveSubMesh +//purpose : +//======================================================================= + +bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) +{ + bool found = false; + + list::iterator itmsh=myChildren.begin(); + for (; itmsh!=myChildren.end() && !found; itmsh++) + { + SMDS_Mesh * submesh = *itmsh; + if (submesh == aMesh) + { + found = true; + myChildren.erase(itmsh); + } + } + + return found; +} + +//======================================================================= +//function : ChangeElementNodes +//purpose : +//======================================================================= + +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, + const SMDS_MeshNode * nodes[], + const int nbnodes) +{ + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while(itn->more()) + oldNodes.insert( itn->next() ); + + // change nodes + bool Ok = false; + switch ( elem->GetType() ) + { + case SMDSAbs_Edge: { + if ( nbnodes == 2 ) { + const SMDS_MeshEdge* edge = dynamic_cast( elem ); + if ( edge ) + Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); + } + break; + } + case SMDSAbs_Face: { + const SMDS_FaceOfNodes* face = dynamic_cast( elem ); + if ( face ) { + Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); + } else { + /// ??? begin + const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + if (face) { + Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + /// ??? end + } + break; + } + //case SMDSAbs_PolygonalFace: { + // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + // if (face) { + // Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + // } + // break; + //} + case SMDSAbs_Volume: { + const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); + if ( vol ) + Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); + break; + } + default: + MESSAGE ( "WRONG ELEM TYPE"); + } + + if ( Ok ) { // update InverseElements + + // AddInverseElement to new nodes + for ( int i = 0; i < nbnodes; i++ ) + if ( oldNodes.find( nodes[i] ) == oldNodes.end() ) + // new node + const_cast( nodes[i] )->AddInverseElement( elem ); + else + // remove from oldNodes a node that remains in elem + oldNodes.erase( nodes[i] ); + + + // RemoveInverseElement from the nodes removed from elem + set::iterator it; + for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) + { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement( elem ); + } + } + + //MESSAGE ( "::ChangeNodes() Ok = " << Ok); + + return Ok; +} + +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : to change nodes of polyhedral volume +//======================================================================= +bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + std::vector nodes, + std::vector quantities) +{ + if (elem->GetType() != SMDSAbs_Volume) { + MESSAGE("WRONG ELEM TYPE"); + return false; + } + + const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast(elem); + if (!vol) { + return false; + } + + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + oldNodes.insert(itn->next()); + } + + // change nodes + bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + if (!Ok) { + return false; + } + + // update InverseElements + + // AddInverseElement to new nodes + int nbnodes = nodes.size(); + for (int i = 0; i < nbnodes; i++) { + if (oldNodes.find(nodes[i]) == oldNodes.end()) { + // new node + const_cast(nodes[i])->AddInverseElement(elem); + } else { + // remove from oldNodes a node that remains in elem + oldNodes.erase(nodes[i]); + } + } + + // RemoveInverseElement from the nodes removed from elem + set::iterator it; + for (it = oldNodes.begin(); it != oldNodes.end(); it++) { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement(elem); + } + + return Ok; +} + +//======================================================================= +//function : FindEdge +//purpose : +//======================================================================= + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + if((node1==NULL)||(node2==NULL)) return NULL; + return FindEdge(node1,node2); +} + +//#include "Profiler.h" +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + const SMDS_MeshEdge * toReturn=NULL; + //PROFILER_Init(); + //PROFILER_Set(); + SMDS_ElemIteratorPtr it1=node1->edgesIterator(); + //PROFILER_Get(0); + //PROFILER_Set(); + while(it1->more()) + { + const SMDS_MeshEdge * e=static_cast + (it1->next()); + SMDS_ElemIteratorPtr it2=e->nodesIterator(); + while(it2->more()) + { + if(it2->next()->GetID()==node2->GetID()) + { + toReturn=e; + break; + } + } + } + //PROFILER_Get(1); + return toReturn; +} + + +SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + SMDS_MeshEdge * toReturn=NULL; + toReturn=const_cast(FindEdge(node1,node2)); + if(toReturn==NULL) + { + toReturn=new SMDS_MeshEdge(node1,node2); + myEdges.Add(toReturn); + } + return toReturn; +} + +//======================================================================= +//function : FindFace +//purpose : +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; + return FindFace(node1, node2, node3); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found; + + SMDS_ElemIteratorPtr it1=node1->facesIterator(); + while(it1->more()) + { + face=static_cast(it1->next()); + if(face->NbNodes()!=3) continue; + SMDS_ElemIteratorPtr it2=face->nodesIterator(); + node2found=false; + node3found=false; + while(it2->more()) + { + node=it2->next(); + if(node->GetID()==node2->GetID()) node2found=true; + if(node->GetID()==node3->GetID()) node3found=true; + } + if(node2found&&node3found) + return face; + } + return NULL; +} + +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) + { + toReturn=createTriangle(node1,node2,node3); + } + return toReturn; +} + +//======================================================================= +//function : FindFace +//purpose : +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3, + int idnode4) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + const SMDS_MeshNode * node4=FindNode(idnode4); + if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL; + return FindFace(node1, node2, node3, node4); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found, node4found; + SMDS_ElemIteratorPtr it1=node1->facesIterator(); + while(it1->more()) + { + face=static_cast(it1->next()); + if(face->NbNodes()!=4) continue; + SMDS_ElemIteratorPtr it2=face->nodesIterator(); + node2found=false; + node3found=false; + node4found=false; + while(it2->more()) + { + node=it2->next(); + if(node->GetID()==node2->GetID()) node2found=true; + if(node->GetID()==node3->GetID()) node3found=true; + if(node->GetID()==node4->GetID()) node4found=true; + } + if(node2found&&node3found&&node4found) + return face; + } + return NULL; +} + +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) +{ + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3,node4)); + if(toReturn==NULL) + { + toReturn=createQuadrangle(node1,node2,node3,node4); + } + return toReturn; +} + +//======================================================================= +//function : FindElement +//purpose : +//======================================================================= + +const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const +{ + return myElementIDFactory->MeshElement(IDelem); +} + +//======================================================================= +//function : FindFace +//purpose : find polygon +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes_ids) const +{ + int nbnodes = nodes_ids.size(); + std::vector poly_nodes (nbnodes); + for (int inode = 0; inode < nbnodes; inode++) { + const SMDS_MeshNode * node = FindNode(nodes_ids[inode]); + if (node == NULL) return NULL; + } + return FindFace(poly_nodes); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes) +{ + int nbNodes = nodes.size(); + if (nbNodes < 1) return NULL; + + bool isFound = true; + const SMDS_MeshFace * face; + set faces; + + for (int inode = 0; inode < nbNodes && isFound; inode++) { + set new_faces; + + SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator(); + while (itF->more()) { + face = static_cast(itF->next()); + if (face->NbNodes() == nbNodes) { + if (inode == 0 || faces.find(face) != faces.end()) { + new_faces.insert(face); + } + } + } + faces = new_faces; + if (new_faces.size() == 0) { + isFound = false; + } + } + + if (isFound) + return face; + + return NULL; +} + +//======================================================================= +//function : DumpNodes +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpNodes() const +{ + MESSAGE("dump nodes of mesh : "); + SMDS_NodeIteratorPtr itnode=nodesIterator(); + while(itnode->more()) MESSAGE(itnode->next()); +} + +//======================================================================= +//function : DumpEdges +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpEdges() const +{ + MESSAGE("dump edges of mesh : "); + SMDS_EdgeIteratorPtr itedge=edgesIterator(); + while(itedge->more()) MESSAGE(itedge->next()); +} + +//======================================================================= +//function : DumpFaces +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpFaces() const +{ + MESSAGE("dump faces of mesh : "); + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) MESSAGE(itface->next()); +} + +//======================================================================= +//function : DumpVolumes +//purpose : +//======================================================================= + +void SMDS_Mesh::DumpVolumes() const +{ + MESSAGE("dump volumes of mesh : "); + SMDS_VolumeIteratorPtr itvol=volumesIterator(); + while(itvol->more()) MESSAGE(itvol->next()); +} + +//======================================================================= +//function : DebugStats +//purpose : +//======================================================================= + +void SMDS_Mesh::DebugStats() const +{ + MESSAGE("Debug stats of mesh : "); + + MESSAGE("===== NODES ====="<more()) + { + const SMDS_MeshNode *node = itnode->next(); + + sizeofnodes += sizeof(*node); + + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while(it->more()) + { + const SMDS_MeshElement *me = it->next(); + sizeofnodes += sizeof(me); + } + + } + + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) + { + const SMDS_MeshElement *face = itface->next(); + sizeoffaces += sizeof(*face); + + } + MESSAGE("total size of node elements = " << sizeofnodes);; + MESSAGE("total size of face elements = " << sizeoffaces);; + + //#endif +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of nodes +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbNodes() const +{ + return myNodes.Size(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of edges (including construction edges) +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbEdges() const +{ + return myEdges.Size(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of faces (including construction faces) +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbFaces() const +{ + return myFaces.Size(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of volumes +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbVolumes() const +{ + return myVolumes.Size(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of child mesh of this mesh. +/// Note that the tree structure of SMDS_Mesh seems to be unused in this version +/// (2003-09-08) of SMESH +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbSubMesh() const +{ + return myChildren.size(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Destroy the mesh and all its elements +/// All pointer on elements owned by this mesh become illegals. +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh::~SMDS_Mesh() +{ + list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + { + delete *itc; + itc++; + } + + SetOfNodes::Iterator itn(myNodes); + for (; itn.More(); itn.Next()) + delete itn.Value(); + + SetOfEdges::Iterator ite(myEdges); + for (; ite.More(); ite.Next()) + { + SMDS_MeshElement* elem = ite.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + + SetOfFaces::Iterator itf(myFaces); + for (; itf.More(); itf.Next()) + { + SMDS_MeshElement* elem = itf.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + + SetOfVolumes::Iterator itv(myVolumes); + for (; itv.More(); itv.Next()) + { + SMDS_MeshElement* elem = itv.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + + if(myParent==NULL) + { + delete myNodeIDFactory; + delete myElementIDFactory; + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return true if this mesh create faces with edges. +/// A false returned value mean that faces are created with nodes. A concequence +/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasConstructionEdges() +{ + return myHasConstructionEdges; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return true if this mesh create volumes with faces +/// A false returned value mean that volumes are created with nodes or edges. +/// (see hasConstructionEdges) +/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be +/// unavailable. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasConstructionFaces() +{ + return myHasConstructionFaces; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return true if nodes are linked to the finit elements, they are belonging to. +/// Currently, It always return true. +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::hasInverseElements() +{ + return myHasInverseElements; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating construction edges (see hasConstructionEdges) +/// @param b true to have construction edges, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setConstructionEdges(bool b) +{ + myHasConstructionEdges=b; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating construction faces (see hasConstructionFaces) +/// @param b true to have construction faces, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setConstructionFaces(bool b) +{ + myHasConstructionFaces=b; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Make this mesh creating link from nodes to elements (see hasInverseElements) +/// @param b true to link nodes to elements, else false. +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::setInverseElements(bool b) +{ + if(!b) MESSAGE("Error : inverseElement=false not implemented"); + myHasInverseElements=b; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return an iterator on nodes of the current mesh factory +/////////////////////////////////////////////////////////////////////////////// +class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator +{ + SMDS_ElemIteratorPtr myIterator; + public: + SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it) + {} + + bool more() + { + return myIterator->more(); + } + + const SMDS_MeshNode* next() + { + return static_cast(myIterator->next()); + } +}; + +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const +{ + return SMDS_NodeIteratorPtr + (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator())); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return an iterator on elements of the current mesh factory +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const +{ + return myElementIDFactory->elementsIterator(); +} + +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on edges of the current mesh. +/////////////////////////////////////////////////////////////////////////////// +class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator +{ + typedef SMDS_Mesh::SetOfEdges SetOfEdges; + SetOfEdges::Iterator myIterator; + public: + SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s) + {} + + bool more() + { + while(myIterator.More()) + { + if(myIterator.Value()->GetID()!=-1) + return true; + myIterator.Next(); + } + return false; + } + + const SMDS_MeshEdge* next() + { + const SMDS_MeshEdge* current = myIterator.Value(); + myIterator.Next(); + return current; + } +}; + +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const +{ + return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges)); +} + +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on faces of the current mesh. +/////////////////////////////////////////////////////////////////////////////// +class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator +{ + typedef SMDS_Mesh::SetOfFaces SetOfFaces; + SetOfFaces::Iterator myIterator; + public: + SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s) + {} + + bool more() + { + while(myIterator.More()) + { + if(myIterator.Value()->GetID()!=-1) + return true; + myIterator.Next(); + } + return false; + } + + const SMDS_MeshFace* next() + { + const SMDS_MeshFace* current = myIterator.Value(); + myIterator.Next(); + return current; + } +}; + +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +{ + return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces)); +} + +/////////////////////////////////////////////////////////////////////////////// +///Return an iterator on volumes of the current mesh. +/////////////////////////////////////////////////////////////////////////////// +class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator +{ + typedef SMDS_Mesh::SetOfVolumes SetOfVolumes; + SetOfVolumes::Iterator myIterator; + public: + SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s) + {} + + bool more() + { + return myIterator.More() != Standard_False; + } + + const SMDS_MeshVolume* next() + { + const SMDS_MeshVolume* current = myIterator.Value(); + myIterator.Next(); + return current; + } +}; + +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +{ + return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes)); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Do intersection of sets (more than 2) +/////////////////////////////////////////////////////////////////////////////// +static set * intersectionOfSets( + set vs[], int numberOfSets) +{ + set* rsetA=new set(vs[0]); + set* rsetB; + + for(int i=0; i(); + set_intersection( + rsetA->begin(), rsetA->end(), + vs[i+1].begin(), vs[i+1].end(), + inserter(*rsetB, rsetB->begin())); + delete rsetA; + rsetA=rsetB; + } + return rsetA; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the list of finit elements owning the given element +/////////////////////////////////////////////////////////////////////////////// +static set * getFinitElements(const SMDS_MeshElement * element) +{ + int numberOfSets=element->NbNodes(); + set *initSet = new set[numberOfSets]; + + SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); + + int i=0; + while(itNodes->more()) + { + const SMDS_MeshNode * n=static_cast(itNodes->next()); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + + //initSet[i]=set(); + while(itFe->more()) + initSet[i].insert(itFe->next()); + + i++; + } + set *retSet=intersectionOfSets(initSet, numberOfSets); + delete [] initSet; + return retSet; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the list of nodes used only by the given elements +/////////////////////////////////////////////////////////////////////////////// +static set * getExclusiveNodes( + set& elements) +{ + set * toReturn=new set(); + set::iterator itElements=elements.begin(); + + while(itElements!=elements.end()) + { + SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); + itElements++; + + while(itNodes->more()) + { + const SMDS_MeshNode * n=static_cast(itNodes->next()); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + set s; + while(itFe->more()) + s.insert(itFe->next()); + if(s==elements) toReturn->insert(n); + } + } + return toReturn; +} + +/////////////////////////////////////////////////////////////////////////////// +///Find the children of an element that are made of given nodes +///@param setOfChildren The set in which matching children will be inserted +///@param element The element were to search matching children +///@param nodes The nodes that the children must have to be selected +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren, + const SMDS_MeshElement * element, set& nodes) +{ + + switch(element->GetType()) + { + case SMDSAbs_Node: + MESSAGE("Internal Error: This should not append"); + break; + case SMDSAbs_Edge: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } + } + } break; + case SMDSAbs_Face: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } + } + if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + } break; + case SMDSAbs_Volume: + { + if(hasConstructionFaces()) + { + SMDS_ElemIteratorPtr ite=element->facesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + else if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +///@param removenodes if true remaining nodes will be removed +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + const bool removenodes) +{ + list removedElems; + list removedNodes; + RemoveElement( elem, removedElems, removedNodes, removenodes ); +} + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +///@param removedElems contains all removed elements +///@param removedNodes contains all removed nodes +///@param removenodes if true remaining nodes will be removed +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + list& removedElems, + list& removedNodes, + bool removenodes) +{ + // get finite elements built on elem + set * s1; + if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || + !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face || + elem->GetType() == SMDSAbs_Volume) + { + s1 = new set(); + s1->insert(elem); + } + else + s1 = getFinitElements(elem); + + // get exclusive nodes (which would become free afterwards) + set * s2; + if (elem->GetType() == SMDSAbs_Node) // a node is removed + { + // do not remove nodes except elem + s2 = new set(); + s2->insert(elem); + removenodes = true; + } + else + s2 = getExclusiveNodes(*s1); + + // form the set of finite and construction elements to remove + set s3; + set::iterator it=s1->begin(); + while(it!=s1->end()) + { + addChildrenWithNodes(s3, *it ,*s2); + s3.insert(*it); + it++; + } + if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); + + // remove finite and construction elements + it=s3.begin(); + while(it!=s3.end()) + { + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn=(*it)->nodesIterator(); + while(itn->more()) + { + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); + n->RemoveInverseElement( (*it) ); + } + + switch((*it)->GetType()) + { + case SMDSAbs_Node: + MESSAGE("Internal Error: This should not happen"); + break; + case SMDSAbs_Edge: + myEdges.Remove(static_cast + (const_cast(*it))); + break; + case SMDSAbs_Face: + myFaces.Remove(static_cast + (const_cast(*it))); + break; + case SMDSAbs_Volume: + myVolumes.Remove(static_cast + (const_cast(*it))); + break; + } + //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); + removedElems.push_back( (*it) ); + myElementIDFactory->ReleaseID((*it)->GetID()); + delete (*it); + it++; + } + + // remove exclusive (free) nodes + if(removenodes) + { + it=s2->begin(); + while(it!=s2->end()) + { + //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); + myNodes.Remove(static_cast + (const_cast(*it))); + myNodeIDFactory->ReleaseID((*it)->GetID()); + removedNodes.push_back( (*it) ); + delete *it; + it++; + } + } + + delete s2; + delete s1; +} + +/*! + * Checks if the element is present in mesh. + * Useful to determine dead pointers. + */ +bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const +{ + // we should not imply on validity of *elem, so iterate on containers + // of all types in the hope of finding somewhere there + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + if (elem == itn->next()) + return true; + SMDS_EdgeIteratorPtr ite = edgesIterator(); + while (ite->more()) + if (elem == ite->next()) + return true; + SMDS_FaceIteratorPtr itf = facesIterator(); + while (itf->more()) + if (elem == itf->next()) + return true; + SMDS_VolumeIteratorPtr itv = volumesIterator(); + while (itv->more()) + if (elem == itv->next()) + return true; + return false; +} + +//======================================================================= +//function : MaxNodeID +//purpose : +//======================================================================= + +int SMDS_Mesh::MaxNodeID() const +{ + return myNodeIDFactory->GetMaxID(); +} + +//======================================================================= +//function : MinNodeID +//purpose : +//======================================================================= + +int SMDS_Mesh::MinNodeID() const +{ + return myNodeIDFactory->GetMinID(); +} + +//======================================================================= +//function : MaxElementID +//purpose : +//======================================================================= + +int SMDS_Mesh::MaxElementID() const +{ + return myElementIDFactory->GetMaxID(); +} + +//======================================================================= +//function : MinElementID +//purpose : +//======================================================================= + +int SMDS_Mesh::MinElementID() const +{ + return myElementIDFactory->GetMinID(); +} + +//======================================================================= +//function : Renumber +//purpose : Renumber all nodes or elements. +//======================================================================= + +void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +{ + if ( deltaID == 0 ) + return; + + SMDS_MeshElementIDFactory * idFactory = + isNodes ? myNodeIDFactory : myElementIDFactory; + + // get existing elements in the order of ID increasing + map elemMap; + SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator(); + while ( idElemIt->more() ) { + SMDS_MeshElement* elem = const_cast(idElemIt->next()); + int id = elem->GetID(); + elemMap.insert(map::value_type(id, elem)); + } + // release their ids + map::iterator elemIt = elemMap.begin(); + for ( ; elemIt != elemMap.end(); elemIt++ ) + { + int id = (*elemIt).first; + idFactory->ReleaseID( id ); + } + // set new IDs + int ID = startID; + elemIt = elemMap.begin(); + for ( ; elemIt != elemMap.end(); elemIt++ ) + { + idFactory->BindID( ID, (*elemIt).second ); + ID += deltaID; + } +} + +//======================================================================= +//function : GetElementType +//purpose : Return type of element or node with id +//======================================================================= + +SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const +{ + SMDS_MeshElement* elem = 0; + if( iselem ) + elem = myElementIDFactory->MeshElement( id ); + else + elem = myNodeIDFactory->MeshElement( id ); + + if( !elem ) + { + //throw SALOME_Exception(LOCALIZED ("this element isn't exist")); + return SMDSAbs_All; + } + else + return elem->GetType(); +} \ No newline at end of file diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx new file mode 100644 index 000000000..612082ce4 --- /dev/null +++ b/src/SMDS/SMDS_Mesh.hxx @@ -0,0 +1,362 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_Mesh.hxx +// Module : SMESH + +#ifndef _SMDS_Mesh_HeaderFile +#define _SMDS_Mesh_HeaderFile + +#include "SMDS_MeshNode.hxx" +#include "SMDS_MeshEdge.hxx" +#include "SMDS_MeshFace.hxx" +#include "SMDS_MeshVolume.hxx" +#include "SMDS_MeshElementIDFactory.hxx" +#include "SMDS_ElemIterator.hxx" +#include + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +#include +#include +#include + +typedef SMDS_Iterator SMDS_NodeIterator; +typedef boost::shared_ptr > SMDS_NodeIteratorPtr; +typedef SMDS_Iterator SMDS_EdgeIterator; +typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; +typedef SMDS_Iterator SMDS_FaceIterator; +typedef boost::shared_ptr > SMDS_FaceIteratorPtr; +typedef SMDS_Iterator SMDS_VolumeIterator; +typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; + +class SMDS_WNT_EXPORT SMDS_Mesh:public SMDS_MeshObject{ +public: + + SMDS_Mesh(); + + SMDS_NodeIteratorPtr nodesIterator() const; + SMDS_EdgeIteratorPtr edgesIterator() const; + SMDS_FaceIteratorPtr facesIterator() const; + SMDS_VolumeIteratorPtr volumesIterator() const; + SMDS_ElemIteratorPtr elementsIterator() const; + + SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) const; + + SMDS_Mesh *AddSubMesh(); + + virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); + virtual SMDS_MeshNode* AddNode(double x, double y, double z); + + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3); + + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6); + + virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, + const int ID); + + virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes, + const int ID); + + virtual SMDS_MeshFace* AddPolygonalFace (std::vector nodes); + + virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID + (std::vector nodes_ids, + std::vector quantities, + const int ID); + + virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID + (std::vector nodes, + std::vector quantities, + const int ID); + + virtual SMDS_MeshVolume* AddPolyhedralVolume + (std::vector nodes, + std::vector quantities); + + virtual void RemoveElement(const SMDS_MeshElement * elem, + std::list& removedElems, + std::list& removedNodes, + const bool removenodes = false); + virtual void RemoveElement(const SMDS_MeshElement * elem, bool removenodes = false); + virtual void RemoveNode(const SMDS_MeshNode * node); + virtual void RemoveEdge(const SMDS_MeshEdge * edge); + virtual void RemoveFace(const SMDS_MeshFace * face); + virtual void RemoveVolume(const SMDS_MeshVolume * volume); + + virtual bool RemoveFromParent(); + virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); + + static bool ChangeElementNodes(const SMDS_MeshElement * elem, + const SMDS_MeshNode * nodes[], + const int nbnodes); + static bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, + std::vector nodes, + std::vector quantities); + + virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); + // Renumber all nodes or elements. + + const SMDS_MeshNode *FindNode(int idnode) const; + const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const; + const SMDS_MeshElement *FindElement(int IDelem) const; + static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3); + static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4); + + const SMDS_MeshFace *FindFace(std::vector nodes_ids) const; + static const SMDS_MeshFace* FindFace(std::vector nodes); + + int MaxNodeID() const; + int MinNodeID() const; + int MaxElementID() const; + int MinElementID() const; + + + int NbNodes() const; + int NbEdges() const; + int NbFaces() const; + int NbVolumes() const; + int NbSubMesh() const; + void DumpNodes() const; + void DumpEdges() const; + void DumpFaces() const; + void DumpVolumes() const; + void DebugStats() const; + SMDS_Mesh *boundaryFaces(); + SMDS_Mesh *boundaryEdges(); + virtual ~SMDS_Mesh(); + bool hasConstructionEdges(); + bool hasConstructionFaces(); + bool hasInverseElements(); + void setConstructionEdges(bool); + void setConstructionFaces(bool); + void setInverseElements(bool); + + /*! + * Checks if the element is present in mesh. + * Useful to determine dead pointers. + * Use this function for debug purpose only! Do not check in the code + * using it even in _DEBUG_ mode + */ + bool Contains (const SMDS_MeshElement* elem) const; + + typedef NCollection_Map SetOfNodes; + typedef NCollection_Map SetOfEdges; + typedef NCollection_Map SetOfFaces; + typedef NCollection_Map SetOfVolumes; + +private: + SMDS_Mesh(SMDS_Mesh * parent); + + SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3); + SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4); + SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3); + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4); + + bool registerElement(int ID, SMDS_MeshElement * element); + + void addChildrenWithNodes(std::set& setOfChildren, + const SMDS_MeshElement * element, + std::set& nodes); + + // Fields PRIVATE + + SetOfNodes myNodes; + SetOfEdges myEdges; + SetOfFaces myFaces; + SetOfVolumes myVolumes; + SMDS_Mesh *myParent; + std::list myChildren; + SMDS_MeshElementIDFactory *myNodeIDFactory; + SMDS_MeshElementIDFactory *myElementIDFactory; + + bool myHasConstructionEdges; + bool myHasConstructionFaces; + bool myHasInverseElements; +}; + + +#endif diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx new file mode 100644 index 000000000..73870b707 --- /dev/null +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -0,0 +1,87 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_MeshElement.hxx +// Module : SMESH + +#ifndef _SMDS_MeshElement_HeaderFile +#define _SMDS_MeshElement_HeaderFile + +#include "SMDSAbs_ElementType.hxx" +#include "SMDS_MeshObject.hxx" +#include "SMDS_ElemIterator.hxx" +#include "SMDS_MeshElementIDFactory.hxx" + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +#include +#include + +class SMDS_MeshNode; +class SMDS_MeshEdge; +class SMDS_MeshFace; + +/////////////////////////////////////////////////////////////////////////////// +/// Base class for elements +/////////////////////////////////////////////////////////////////////////////// +class SMDS_WNT_EXPORT SMDS_MeshElement:public SMDS_MeshObject +{ + + public: + SMDS_ElemIteratorPtr nodesIterator() const; + SMDS_ElemIteratorPtr edgesIterator() const; + SMDS_ElemIteratorPtr facesIterator() const; + virtual SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + int GetID() const; + + ///Return the type of the current element + virtual SMDSAbs_ElementType GetType() const = 0; + virtual bool IsPoly() const { return false; }; + + friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); + friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + + protected: + SMDS_MeshElement(int ID=-1); + virtual void Print(std::ostream & OS) const; + + private: + int myID; +}; + +#endif diff --git a/src/SMDS/SMDS_MeshGroup.hxx b/src/SMDS/SMDS_MeshGroup.hxx new file mode 100644 index 000000000..37893fab4 --- /dev/null +++ b/src/SMDS/SMDS_MeshGroup.hxx @@ -0,0 +1,87 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 OPEN CASCADE +// +// 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.opencascade.org or email : webmaster@opencascade.org +// +// +// +// File : SMDS_MeshGroup.hxx +// Module : SMESH + +#ifndef _SMDS_MeshGroup_HeaderFile +#define _SMDS_MeshGroup_HeaderFile + +#include "SMDS_Mesh.hxx" +#include + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_MeshGroup:public SMDS_MeshObject +{ + public: + SMDS_MeshGroup(const SMDS_Mesh * theMesh, + const SMDSAbs_ElementType theType = SMDSAbs_All); + const SMDS_MeshGroup * AddSubGroup + (const SMDSAbs_ElementType theType = SMDSAbs_All); + virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup); + virtual bool RemoveFromParent(); + + const SMDS_Mesh* GetMesh() const { return myMesh; } + + void SetType (const SMDSAbs_ElementType theType); + void Clear(); + void Add(const SMDS_MeshElement * theElem); + void Remove(const SMDS_MeshElement * theElem); + bool IsEmpty() const { return myElements.empty(); } + int Extent() const { return myElements.size(); } + + SMDSAbs_ElementType GetType() const { return myType; } + + bool Contains(const SMDS_MeshElement * theElem) const; + + void InitIterator() const + { const_cast(myIterator) = myElements.begin(); } + + bool More() const { return myIterator != myElements.end(); } + + const SMDS_MeshElement* Next() const + { return *(const_cast(myIterator))++; } + + private: + SMDS_MeshGroup(SMDS_MeshGroup* theParent, + const SMDSAbs_ElementType theType = SMDSAbs_All); + + typedef std::set::const_iterator TIterator; + const SMDS_Mesh * myMesh; + SMDSAbs_ElementType myType; + std::set myElements; + SMDS_MeshGroup * myParent; + std::list myChildren; + TIterator myIterator; +}; +#endif diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx new file mode 100644 index 000000000..042a1734a --- /dev/null +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -0,0 +1,77 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_MeshNode.hxx +// Module : SMESH + +#ifndef _SMDS_MeshNode_HeaderFile +#define _SMDS_MeshNode_HeaderFile + +#include "SMDS_MeshElement.hxx" +#include "SMDS_Position.hxx" +#include + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_MeshNode:public SMDS_MeshElement +{ + + public: + SMDS_MeshNode(double x, double y, double z); + void Print(std::ostream & OS) const; + double X() const; + double Y() const; + double Z() const; + void AddInverseElement(const SMDS_MeshElement * ME); + void RemoveInverseElement(const SMDS_MeshElement * parent); + void ClearInverseElements(); + bool emptyInverseElements(); + SMDS_ElemIteratorPtr GetInverseElementIterator() const; + void SetPosition(const SMDS_PositionPtr& aPos); + const SMDS_PositionPtr& GetPosition() const; + SMDSAbs_ElementType GetType() const; + int NbNodes() const; + void setXYZ(double x, double y, double z); + friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); + + protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + + private: + double myX, myY, myZ; + SMDS_PositionPtr myPosition; + NCollection_List myInverseElements; +}; + +#endif diff --git a/src/SMDS/SMDS_MeshObject.hxx b/src/SMDS/SMDS_MeshObject.hxx new file mode 100644 index 000000000..f734309cf --- /dev/null +++ b/src/SMDS/SMDS_MeshObject.hxx @@ -0,0 +1,48 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_MeshObject.hxx +// Module : SMESH + +#ifndef _SMDS_MeshObject_HeaderFile +#define _SMDS_MeshObject_HeaderFile + + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_MeshObject +{ + public: + virtual ~SMDS_MeshObject() {} +}; +#endif diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx new file mode 100644 index 000000000..84ce2134d --- /dev/null +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx @@ -0,0 +1,190 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//======================================================================= +//function : Constructor +//purpose : Create a volume of many faces +//======================================================================= +SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes + (std::vector nodes, + std::vector quantities) +: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL) +{ + ChangeNodes(nodes, quantities); +} + +//======================================================================= +//function : GetType +//purpose : +//======================================================================= +SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const +{ +// return SMDSAbs_PolyhedralVolume; + return SMDSAbs_Volume; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= +bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (std::vector nodes, + std::vector quantities) +{ + myNodesByFaces = nodes; + myQuantities = quantities; + + // Init fields of parent class + int aNbNodes = 0; + std::set aSet; + int nodes_len = nodes.size(); + for (int j = 0; j < nodes_len; j++) { + if (aSet.find(nodes[j]) == aSet.end()) { + aSet.insert(nodes[j]); + aNbNodes++; + } + } + + int k = 0; +#ifndef WNT + const SMDS_MeshNode* aNodes [aNbNodes]; +#else + const SMDS_MeshNode** aNodes = (const SMDS_MeshNode **)new SMDS_MeshNode*[aNbNodes]; +#endif + std::set::iterator anIter = aSet.begin(); + for (; anIter != aSet.end(); anIter++, k++) { + aNodes[k] = *anIter; + } + + //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes); + delete [] myNodes; + //myNbNodes = nodes.size(); + myNbNodes = aNbNodes; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + for (int i = 0; i < myNbNodes; i++) { + //myNodes[i] = nodes[i]; + myNodes[i] = aNodes[i]; + } + +#ifdef WNT + delete [] aNodes; +#endif + + return true; +} + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbEdges() const +{ + int nbEdges = 0; + + for (int ifa = 0; ifa < myQuantities.size(); ifa++) { + nbEdges += myQuantities[ifa]; + } + nbEdges /= 2; + + return nbEdges; +} + +//======================================================================= +//function : NbFaces +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbFaces() const +{ + return myQuantities.size(); +} + +//======================================================================= +//function : NbFaceNodes +//purpose : +//======================================================================= +int SMDS_PolyhedralVolumeOfNodes::NbFaceNodes (const int face_ind) const +{ + if (face_ind < 1 || myQuantities.size() < face_ind) + return 0; + return myQuantities[face_ind - 1]; +} + +//======================================================================= +//function : GetFaceNode +//purpose : +//======================================================================= +const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetFaceNode (const int face_ind, + const int node_ind) const +{ + if (node_ind < 1 || NbFaceNodes(face_ind) < node_ind) + return NULL; + + int i, first_node = 0; + for (i = 0; i < face_ind - 1; i++) { + first_node += myQuantities[i]; + } + + return myNodesByFaces[first_node + node_ind - 1]; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= +void SMDS_PolyhedralVolumeOfNodes::Print (ostream & OS) const +{ + OS << "polyhedral volume <" << GetID() << "> : "; + + int faces_len = myQuantities.size(); + //int nodes_len = myNodesByFaces.size(); + int cur_first_node = 0; + + int i, j; + for (i = 0; i < faces_len; i++) { + OS << "face_" << i << " ("; + for (j = 0; j < myQuantities[i] - 1; j++) { + OS << myNodesByFaces[cur_first_node + j] << ","; + } + OS << myNodesByFaces[cur_first_node + j] << ") "; + cur_first_node += myQuantities[i]; + } +} + +//======================================================================= +//function : ChangeNodes +//purpose : usage disabled +//======================================================================= +bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes) +{ + return false; +} diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx new file mode 100644 index 000000000..baecaf339 --- /dev/null +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx @@ -0,0 +1,77 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_PolyhedralVolumeOfNodes.hxx +// Module : SMESH + +#ifndef _SMDS_PolyhedralVolumeOfNodes_HeaderFile +#define _SMDS_PolyhedralVolumeOfNodes_HeaderFile + +#include "SMDS_VolumeOfNodes.hxx" + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif +class SMDS_WNT_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes +{ + public: + SMDS_PolyhedralVolumeOfNodes (std::vector nodes, + std::vector quantities); + + //virtual ~SMDS_PolyhedralVolumeOfNodes(); + + virtual SMDSAbs_ElementType GetType() const; + virtual bool IsPoly() const { return true; }; + + bool ChangeNodes (std::vector nodes, + std::vector quantities); + + //virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() + + const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; + // 1 <= face_ind <= NbFaces() + // 1 <= node_ind <= NbFaceNodes() + + virtual void Print (std::ostream & OS) const; + + protected: + //virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + private: + // usage disabled + bool ChangeNodes (const SMDS_MeshNode* nodes[], + const int nbNodes); + + private: + std::vector myNodesByFaces; + std::vector myQuantities; +}; + +#endif diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx new file mode 100644 index 000000000..9b11dc6f9 --- /dev/null +++ b/src/SMDS/SMDS_Position.hxx @@ -0,0 +1,68 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_Position.hxx +// Module : SMESH + +#ifndef _SMDS_Position_HeaderFile +#define _SMDS_Position_HeaderFile + +#include "SMDS_TypeOfPosition.hxx" +#include + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_Position; +typedef boost::shared_ptr SMDS_PositionPtr; + + +class SMDS_WNT_EXPORT SMDS_Position +{ + + public: + const virtual double * Coords() const = 0; + virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; + virtual int GetDim() const; + void SetShapeId(int aShapeId); + int GetShapeId() const; + virtual ~SMDS_Position() {} + + protected: + SMDS_Position(int aShapeId); + + private: + int myShapeId; +}; + + +#endif diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx new file mode 100644 index 000000000..f4c7bff1a --- /dev/null +++ b/src/SMDS/SMDS_SpacePosition.hxx @@ -0,0 +1,57 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_SpacePosition.hxx +// Module : SMESH + +#ifndef _SMDS_SpacePosition_HeaderFile +#define _SMDS_SpacePosition_HeaderFile + +#include "SMDS_Position.hxx" + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_SpacePosition:public SMDS_Position +{ + + public: + SMDS_SpacePosition(double x=0, double y=0, double z=0); + const virtual double * Coords() const; + virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; + inline void SetCoords(const double x, const double y, const double z); + static SMDS_PositionPtr originSpacePosition(); + private: + double myCoords[3]; +}; + +#endif diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx new file mode 100644 index 000000000..68c1e3a58 --- /dev/null +++ b/src/SMDS/SMDS_VertexPosition.hxx @@ -0,0 +1,53 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_VertexPosition.hxx +// Module : SMESH + +#ifndef _SMDS_VertexPosition_HeaderFile +#define _SMDS_VertexPosition_HeaderFile + +#include "SMDS_Position.hxx" + +//#ifdef WNT +//#include +//#else +//#define SALOME_WNT_EXPORT +//#endif + +#if defined WNT && defined WIN32 && defined SMDS_EXPORTS +#define SMDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMDS_WNT_EXPORT +#endif + +class SMDS_WNT_EXPORT SMDS_VertexPosition:public SMDS_Position +{ + + public: + SMDS_TypeOfPosition GetTypeOfPosition() const; + SMDS_VertexPosition(int aVertexId=0); + const double *Coords() const; +}; + +#endif diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx new file mode 100644 index 000000000..ff14016d8 --- /dev/null +++ b/src/SMESH/SMESH_HypoFilter.cxx @@ -0,0 +1,305 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_HypoFilter.cxx +// Module : SMESH +// $Header$ + +#include "SMESH_HypoFilter.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "SMESH_subMesh.hxx" + +using namespace std; + + +//======================================================================= +//function : NamePredicate::Value +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::NamePredicate::IsOk (const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& /*aShape*/ ) const +{ + return ( _name == aHyp->GetName() ); +} + +//======================================================================= +//function : TypePredicate::Value +//purpose : +//======================================================================= + +int SMESH_HypoFilter::TypePredicate::Value( const SMESH_Hypothesis* aHyp ) const +{ + return aHyp->GetType(); +}; + +//======================================================================= +//function : DimPredicate::Value +//purpose : +//======================================================================= + +int SMESH_HypoFilter::DimPredicate::Value( const SMESH_Hypothesis* aHyp ) const +{ + return aHyp->GetDim(); +} + +//======================================================================= +//function : ApplicablePredicate::IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& /*aShape*/) const +{ + return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType ); +}; + +//======================================================================= +//function : ApplicablePredicate::ApplicablePredicate +//purpose : +//======================================================================= + +SMESH_HypoFilter::ApplicablePredicate::ApplicablePredicate( const TopoDS_Shape& theShape ) +{ + _shapeType = ( theShape.IsNull() ? TopAbs_SHAPE : theShape.ShapeType()); +} + +//======================================================================= +//function : InstancePredicate::IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& /*aShape*/) const +{ + return _hypo == aHyp; +} + +//======================================================================= +//function : IsAssignedToPredicate::IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const +{ + return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape )); +} + +//======================================================================= +//function : SMESH_HypoFilter +//purpose : +//======================================================================= + +SMESH_HypoFilter::SMESH_HypoFilter() +{ +} + +//======================================================================= +//function : SMESH_HypoFilter +//purpose : +//======================================================================= + +SMESH_HypoFilter::SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNagate ) +{ + add( notNagate ? AND : AND_NOT, aPredicate ); +} + +//======================================================================= +//function : And +//purpose : +//======================================================================= + +SMESH_HypoFilter & SMESH_HypoFilter::And( SMESH_HypoPredicate* aPredicate ) +{ + add( AND, aPredicate ); + return *this; +} + +//======================================================================= +//function : AndNot +//purpose : +//======================================================================= + +SMESH_HypoFilter & SMESH_HypoFilter::AndNot( SMESH_HypoPredicate* aPredicate ) +{ + add( AND_NOT, aPredicate ); + return *this; +} + +//======================================================================= +//function : Or +//purpose : +//======================================================================= + +SMESH_HypoFilter & SMESH_HypoFilter::Or( SMESH_HypoPredicate* aPredicate ) +{ + add( OR, aPredicate ); + return *this; +} + +//======================================================================= +//function : OrNot +//purpose : Return predicates +//======================================================================= + +SMESH_HypoFilter & SMESH_HypoFilter::OrNot( SMESH_HypoPredicate* aPredicate ) +{ + add( OR_NOT, aPredicate ); + return *this; +} + +//======================================================================= +//function : Is +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::Is(const SMESH_Hypothesis* theHypo) +{ + return new InstancePredicate( theHypo ); +} + +//======================================================================= +//function : IsAlgo +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo() +{ + return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO ); +} + +//======================================================================= +//function : IsGlobal +//purpose : +//======================================================================= + + SMESH_HypoPredicate* SMESH_HypoFilter::IsGlobal(const TopoDS_Shape& theMainShape) +{ + return new IsAssignedToPredicate( theMainShape ); +} + +//======================================================================= +//function : IsAssignedTo +//purpose : +//======================================================================= + + SMESH_HypoPredicate* SMESH_HypoFilter::IsAssignedTo(const TopoDS_Shape& theShape) +{ + return new IsAssignedToPredicate( theShape ); +} + +//======================================================================= +//function : HasName +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::HasName(const string & theName) +{ + return new NamePredicate( theName ); +} + +//======================================================================= +//function : HasDim +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::HasDim(const int theDim) +{ + return new DimPredicate( EQUAL, theDim ); +} + +//======================================================================= +//function : IsApplicableTo +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theShape) +{ + return new ApplicablePredicate( theShape ); +} + +//======================================================================= +//function : HasType +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::HasType(const int theHypType) +{ + return new TypePredicate( EQUAL, theHypType ); +} + +//======================================================================= +//function : IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::IsOk (const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const +{ + if ( myPredicates.empty() ) + return true; + + bool ok = ( myPredicates.front()->_logical_op <= AND_NOT ); + list::const_iterator pred = myPredicates.begin(); + for ( ; pred != myPredicates.end(); ++pred ) + { + bool ok2 = (*pred)->IsOk( aHyp, aShape ); + switch ( (*pred)->_logical_op ) { + case AND: ok = ok && ok2; break; + case AND_NOT: ok = ok && !ok2; break; + case OR: ok = ok || ok2; break; + case OR_NOT: ok = ok || !ok2; break; + default:; + } + } + return ok; +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= + +SMESH_HypoFilter & SMESH_HypoFilter::Init ( SMESH_HypoPredicate* aPredicate, bool notNagate ) +{ + list::const_iterator pred = myPredicates.begin(); + for ( ; pred != myPredicates.end(); ++pred ) + delete *pred; + + add( notNagate ? AND : AND_NOT, aPredicate ); + return *this; +} + + +//======================================================================= +//function : IsOk +//purpose : +//======================================================================= + +SMESH_HypoFilter::~SMESH_HypoFilter() +{ + Init(0); +} + diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx new file mode 100644 index 000000000..6bc34bf53 --- /dev/null +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -0,0 +1,164 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_HypoFilter.hxx +// Module : SMESH +// $Header$ + + +#ifndef SMESH_HypoFilter_HeaderFile +#define SMESH_HypoFilter_HeaderFile + +// =========================== +// Filter of SMESH_Hypothesis +// =========================== + +#include +#include +#include + +class SMESH_HypoFilter; +class SMESH_Hypothesis; + +class SMESH_HypoPredicate { + public: + virtual bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const = 0; + // check aHyp or/and aShape it is assigned to + virtual ~SMESH_HypoPredicate() {} + private: + int _logical_op; + friend class SMESH_HypoFilter; +}; + +class SMESH_HypoFilter: public SMESH_HypoPredicate +{ + public: + // Create and add predicates. + // Added predicates will be destroyed by filter when it dies + SMESH_HypoFilter(); + SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNagate = true ); + // notNagate==false means !aPredicate->IsOk() + SMESH_HypoFilter & Init ( SMESH_HypoPredicate* aPredicate, bool notNagate = true ); + SMESH_HypoFilter & And ( SMESH_HypoPredicate* aPredicate ); + SMESH_HypoFilter & AndNot( SMESH_HypoPredicate* aPredicate ); + SMESH_HypoFilter & Or ( SMESH_HypoPredicate* aPredicate ); + SMESH_HypoFilter & OrNot ( SMESH_HypoPredicate* aPredicate ); + + // Create predicates + static SMESH_HypoPredicate* IsAlgo(); + static SMESH_HypoPredicate* IsApplicableTo(const TopoDS_Shape& theShape); + static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape); + static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo); + static SMESH_HypoPredicate* IsGlobal(const TopoDS_Shape& theMainShape); + static SMESH_HypoPredicate* HasName(const std::string & theName); + static SMESH_HypoPredicate* HasDim(const int theDim); + static SMESH_HypoPredicate* HasType(const int theHypType); + + bool IsOk (const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + // check aHyp or/and aShape it is assigned to + + ~SMESH_HypoFilter(); + + + protected: + // fields + + std::list myPredicates; + + // private methods + + enum Logical { AND, AND_NOT, OR, OR_NOT }; + enum Comparison { EQUAL, NOT_EQUAL, MORE, LESS }; + + SMESH_HypoFilter(const SMESH_HypoFilter& other){} + + void add( Logical bool_op, SMESH_HypoPredicate* pred ) + { + if ( pred ) { + pred->_logical_op = bool_op; + myPredicates.push_back( pred ); + } + } + + // predicates implementation + + template + struct templPredicate: public SMESH_HypoPredicate { + Comparison _comp; + TValue _val; + virtual TValue Value(const SMESH_Hypothesis* aHyp) const = 0; + virtual bool IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& ) const + { + if ( _comp == EQUAL ) return _val == Value( aHyp ); + else if ( _comp == NOT_EQUAL ) return _val != Value( aHyp ); + else if ( _comp == MORE ) return _val < Value( aHyp ); + else return _val > Value( aHyp ); + } + }; + + struct NamePredicate : public SMESH_HypoPredicate { + std::string _name; + NamePredicate( std::string name ): _name(name){} + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + + struct TypePredicate : public templPredicate< int > { + TypePredicate( Comparison comp, int hypType ) + { _comp = comp; _val = hypType; } + int Value( const SMESH_Hypothesis* aHyp ) const; + }; + + struct DimPredicate : public templPredicate< int > { + DimPredicate( Comparison comp, int dim ) + { _comp = comp; _val = dim; } + int Value( const SMESH_Hypothesis* aHyp ) const; + }; + + struct ApplicablePredicate : public SMESH_HypoPredicate { + int _shapeType; + ApplicablePredicate( const TopoDS_Shape& theShape ); + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + + struct InstancePredicate : public SMESH_HypoPredicate { + const SMESH_Hypothesis* _hypo; + InstancePredicate( const SMESH_Hypothesis* hypo ):_hypo(hypo){} + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + + struct IsAssignedToPredicate : public SMESH_HypoPredicate { + TopoDS_Shape _mainShape; + IsAssignedToPredicate( const TopoDS_Shape& mainShape ):_mainShape(mainShape){} + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + +}; + + +#endif diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx new file mode 100644 index 000000000..5f92232dd --- /dev/null +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -0,0 +1,1065 @@ +// SMESH SMESHDS : management of mesh data and SMESH document +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Mesh.cxx +// Author : Yves FRICAUD, OCC +// Module : SMESH +// $Header: + +#include "SMESHDS_Mesh.hxx" + +#include "SMESHDS_Group.hxx" +#include "SMDS_VertexPosition.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMESHDS_GroupOnGeom.hxx" +#include +#include +#include + +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : Create +//purpose : +//======================================================================= +SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID) +{ + myScript = new SMESHDS_Script(); +} + +//======================================================================= +//function : ShapeToMesh +//purpose : +//======================================================================= +void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) +{ + if ( !myShape.IsNull() && S.IsNull() ) + { + // removal of a shape to mesh, delete ... + // - hypotheses + myShapeToHypothesis.clear(); + // - shape indices in SMDS_Position of nodes + map::iterator i_sub = myShapeIndexToSubMesh.begin(); + for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) { + if ( !i_sub->second->IsComplexSubmesh() ) { + SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes(); + while ( nIt->more() ) + nIt->next()->GetPosition()->SetShapeId( 0 ); + } + } + // - sub-meshes + myIndexToShape.Clear(); + myShapeIndexToSubMesh.clear(); + // - groups on geometry + set::iterator gr = myGroups.begin(); + while ( gr != myGroups.end() ) { + if ( dynamic_cast( *gr )) + myGroups.erase( gr++ ); + else + gr++; + } + } + else { + myShape = S; + if ( !S.IsNull() ) + TopExp::MapShapes(myShape, myIndexToShape); + } +} + +//======================================================================= +//function : AddHypothesis +//purpose : +//======================================================================= + +bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS, + const SMESHDS_Hypothesis * H) +{ + list& alist=myShapeToHypothesis[SS]; + + //Check if the Hypothesis is still present + list::iterator ith=alist.begin(); + + for (; ith!=alist.end(); ith++) + if (H == *ith) return false; + + alist.push_back(H); + return true; +} + +//======================================================================= +//function : RemoveHypothesis +//purpose : +//======================================================================= + +bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, + const SMESHDS_Hypothesis * H) +{ + ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S); + if(its!=myShapeToHypothesis.end()) + { + list::iterator ith=(*its).second.begin(); + + for (; ith!=(*its).second.end(); ith++) + if (H == *ith) + { + (*its).second.erase(ith); + return true; + } + } + return false; +} + +//======================================================================= +//function : AddNode +//purpose : +//======================================================================= +SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){ + SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z); + if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); + return node; +} + +SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){ + SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID); + if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); + return node; +} + +//======================================================================= +//function : MoveNode +//purpose : +//======================================================================= +void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) +{ + SMDS_MeshNode * node=const_cast(n); + node->setXYZ(x,y,z); + myScript->MoveNode(n->GetID(), x, y, z); +} + +//======================================================================= +//function : ChangeElementNodes +//purpose : +//======================================================================= + +bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, + const SMDS_MeshNode * nodes[], + const int nbnodes) +{ + if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes )) + return false; + + vector IDs( nbnodes ); + for ( int i = 0; i < nbnodes; i++ ) + IDs [ i ] = nodes[ i ]->GetID(); + myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes); + + return true; +} + +//======================================================================= +//function : ChangePolygonNodes +//purpose : +//======================================================================= +bool SMESHDS_Mesh::ChangePolygonNodes + (const SMDS_MeshElement * elem, + vector nodes) +{ + ASSERT(nodes.size() > 3); + + return ChangeElementNodes(elem, &nodes[0], nodes.size()); +} + +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : +//======================================================================= +bool SMESHDS_Mesh::ChangePolyhedronNodes + (const SMDS_MeshElement * elem, + std::vector nodes, + std::vector quantities) +{ + ASSERT(nodes.size() > 3); + + if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities)) + return false; + + int i, len = nodes.size(); + std::vector nodes_ids (len); + for (i = 0; i < len; i++) { + nodes_ids[i] = nodes[i]->GetID(); + } + myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities); + + return true; +} + +//======================================================================= +//function : Renumber +//purpose : +//======================================================================= + +void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +{ + SMDS_Mesh::Renumber( isNodes, startID, deltaID ); + myScript->Renumber( isNodes, startID, deltaID ); +} + +//======================================================================= +//function :AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID); + if(anElem) myScript->AddEdge(ID,n1,n2); + return anElem; +} + +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID) +{ + return AddEdgeWithID(n1->GetID(), + n2->GetID(), + ID); +} + +SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2); + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), + n2->GetID()); + return anElem; +} + +//======================================================================= +//function :AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3); + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) +{ + return AddFaceWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + ID); +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID()); + return anElem; +} + +//======================================================================= +//function :AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID); + if(anElem) myScript->AddFace(ID, n1, n2, n3, n4); + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + return AddFaceWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); + return anElem; +} + +//======================================================================= +//function :AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); + return anElem; +} + +//======================================================================= +//function :AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID()); + return anElem; +} + +//======================================================================= +//function :AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID) +{ + SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID()); + return anElem; +} + +//======================================================================= +//function :AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID) +{ + SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID()); + return anElem; +} + +//======================================================================= +//function : AddPolygonalFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, + const int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID); + if (anElem) { + myScript->AddPolygonalFace(ID, nodes_ids); + } + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID + (std::vector nodes, + const int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); + if (anElem) { + int i, len = nodes.size(); + std::vector nodes_ids (len); + for (i = 0; i < len; i++) { + nodes_ids[i] = nodes[i]->GetID(); + } + myScript->AddPolygonalFace(ID, nodes_ids); + } + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace + (std::vector nodes) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes); + if (anElem) { + int i, len = nodes.size(); + std::vector nodes_ids (len); + for (i = 0; i < len; i++) { + nodes_ids[i] = nodes[i]->GetID(); + } + myScript->AddPolygonalFace(anElem->GetID(), nodes_ids); + } + return anElem; +} + +//======================================================================= +//function : AddPolyhedralVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector nodes_ids, + std::vector quantities, + const int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID); + if (anElem) { + myScript->AddPolyhedralVolume(ID, nodes_ids, quantities); + } + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID + (std::vector nodes, + std::vector quantities, + const int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); + if (anElem) { + int i, len = nodes.size(); + std::vector nodes_ids (len); + for (i = 0; i < len; i++) { + nodes_ids[i] = nodes[i]->GetID(); + } + myScript->AddPolyhedralVolume(ID, nodes_ids, quantities); + } + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume + (std::vector nodes, + std::vector quantities) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities); + if (anElem) { + int i, len = nodes.size(); + std::vector nodes_ids (len); + for (i = 0; i < len; i++) { + nodes_ids[i] = nodes[i]->GetID(); + } + myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities); + } + return anElem; +} + +//======================================================================= +//function : removeFromContainers +//purpose : +//======================================================================= + +static void removeFromContainers (map & theSubMeshes, + set& theGroups, + list & theElems, + const bool isNode) +{ + if ( theElems.empty() ) + return; + + // Rm from group + // Element can belong to several groups + if ( !theGroups.empty() ) + { + set::iterator GrIt = theGroups.begin(); + for ( ; GrIt != theGroups.end(); GrIt++ ) + { + SMESHDS_Group* group = dynamic_cast( *GrIt ); + if ( !group || group->IsEmpty() ) continue; + + list::iterator elIt = theElems.begin(); + for ( ; elIt != theElems.end(); elIt++ ) + { + group->SMDSGroup().Remove( *elIt ); + if ( group->IsEmpty() ) break; + } + } + } + + // Rm from sub-meshes + // Element should belong to only one sub-mesh + map::iterator SubIt = theSubMeshes.begin(); + for ( ; SubIt != theSubMeshes.end(); SubIt++ ) + { + int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements(); + if ( size == 0 ) continue; + + list::iterator elIt = theElems.begin(); + while ( elIt != theElems.end() ) + { + bool removed = false; + if ( isNode ) + removed = (*SubIt).second->RemoveNode( static_cast (*elIt) ); + else + removed = (*SubIt).second->RemoveElement( *elIt ); + + if (removed) + { + elIt = theElems.erase( elIt ); + if ( theElems.empty() ) + return; // all elements are found and removed + } + else + { + elIt++ ; + } + } + } +} + +//======================================================================= +//function : RemoveNode +//purpose : +//======================================================================= +void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) +{ + myScript->RemoveNode(n->GetID()); + + list removedElems; + list removedNodes; + + SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true ); + + removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false ); + removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true ); +} + +//======================================================================= +//function : RemoveElement +//purpose : +//======================================================================== +void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) +{ + if (elt->GetType() == SMDSAbs_Node) + { + RemoveNode( static_cast( elt )); + return; + } + + myScript->RemoveElement(elt->GetID()); + + list removedElems; + list removedNodes; + + SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false); + + removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false ); +} + +//======================================================================= +//function : SetNodeOnVolume +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, + const TopoDS_Shell & S) +{ + SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) ); +} +//======================================================================= +//function : SetNodeOnVolume +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, + const TopoDS_Solid & S) +{ + SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) ); +} + +//======================================================================= +//function : SetNodeOnFace +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode, + const TopoDS_Face & S, + double u, + double v) +{ + SetNodeOnFace( aNode, myIndexToShape.FindIndex(S), u, v ); +} + +//======================================================================= +//function : SetNodeOnEdge +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, + const TopoDS_Edge & S, + double u) +{ + SetNodeOnEdge( aNode, myIndexToShape.FindIndex(S), u ); +} + +//======================================================================= +//function : SetNodeOnVertex +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, + const TopoDS_Vertex & S) +{ + SetNodeOnVertex( aNode, myIndexToShape.FindIndex(S)); +} + +//======================================================================= +//function : UnSetNodeOnShape +//purpose : +//======================================================================= +void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) +{ + MESSAGE("not implemented"); +} + +//======================================================================= +//function : SetMeshElementOnShape +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement, + const TopoDS_Shape & S) +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + + int Index = myIndexToShape.FindIndex(S); + + if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) + myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh(); + + myShapeIndexToSubMesh[Index]->AddElement(anElement); +} + +//======================================================================= +//function : UnSetMeshElementOnShape +//purpose : +//======================================================================= +void SMESHDS_Mesh:: +UnSetMeshElementOnShape(const SMDS_MeshElement * anElement, + const TopoDS_Shape & S) +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + + int Index = myIndexToShape.FindIndex(S); + + if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) + myShapeIndexToSubMesh[Index]->RemoveElement(anElement); +} + +//======================================================================= +//function : ShapeToMesh +//purpose : +//======================================================================= +TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const +{ + return myShape; +} + +//======================================================================= +//function : IsGroupOfSubShapes +//purpose : return true if at least one subshape of theShape is a subshape +// of myShape or theShape == myShape +//======================================================================= + +bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const +{ + if ( myShape.IsSame( theShape )) + return true; + + for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) { + if (myIndexToShape.Contains( it.Value() ) || + IsGroupOfSubShapes( it.Value() )) + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given +/// TopoDS_Shape is unknown +/////////////////////////////////////////////////////////////////////////////// +SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + + int Index = ShapeToIndex(S); + TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index); + if (anIter != myShapeIndexToSubMesh.end()) + return anIter->second; + else + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the sub mesh by Id of shape it is linked to +/////////////////////////////////////////////////////////////////////////////// +SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + + if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) + return myShapeIndexToSubMesh[Index]; + else + return NULL; +} + +//======================================================================= +//function : SubMeshIndices +//purpose : +//======================================================================= +list SMESHDS_Mesh::SubMeshIndices() +{ + list anIndices; + std::map::iterator anIter = myShapeIndexToSubMesh.begin(); + for (; anIter != myShapeIndexToSubMesh.end(); anIter++) { + anIndices.push_back((*anIter).first); + } + return anIndices; +} + +//======================================================================= +//function : GetHypothesis +//purpose : +//======================================================================= + +const list& SMESHDS_Mesh::GetHypothesis( + const TopoDS_Shape & S) const +{ + if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end()) + return myShapeToHypothesis.find(S)->second; + + static list empty; + return empty; +} + +//======================================================================= +//function : GetScript +//purpose : +//======================================================================= +SMESHDS_Script* SMESHDS_Mesh::GetScript() +{ + return myScript; +} + +//======================================================================= +//function : ClearScript +//purpose : +//======================================================================= +void SMESHDS_Mesh::ClearScript() +{ + myScript->Clear(); +} + +//======================================================================= +//function : HasMeshElements +//purpose : +//======================================================================= +bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + int Index = myIndexToShape.FindIndex(S); + return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end(); +} + +//======================================================================= +//function : HasHypothesis +//purpose : +//======================================================================= +bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S) +{ + return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end(); +} + +//======================================================================= +//function : NewSubMesh +//purpose : +//======================================================================= +SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) +{ + SMESHDS_SubMesh* SM = 0; + TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index); + if (anIter == myShapeIndexToSubMesh.end()) + { + SM = new SMESHDS_SubMesh(); + myShapeIndexToSubMesh[Index]=SM; + } + else + SM = anIter->second; + return SM; +} + +//======================================================================= +//function : AddCompoundSubmesh +//purpose : +//======================================================================= + +int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, + TopAbs_ShapeEnum type) +{ + int aMainIndex = 0; + if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) ) + { + aMainIndex = myIndexToShape.Add( S ); + bool all = ( type == TopAbs_SHAPE ); + if ( all ) // corresponding simple submesh may exist + aMainIndex = -aMainIndex; + //MESSAGE("AddCompoundSubmesh index = " << aMainIndex ); + SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex ); + if ( !aNewSub->IsComplexSubmesh() ) // is empty + { + int shapeType = all ? myShape.ShapeType() : type; + int typeLimit = all ? TopAbs_VERTEX : type; + for ( ; shapeType <= typeLimit; shapeType++ ) + { + TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType )); + for ( ; exp.More(); exp.Next() ) + { + int index = myIndexToShape.FindIndex( exp.Current() ); + if ( index ) + aNewSub->AddSubMesh( NewSubMesh( index )); + } + } + } + } + return aMainIndex; +} + +//======================================================================= +//function : IndexToShape +//purpose : +//======================================================================= +TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex) +{ + return myIndexToShape.FindKey(ShapeIndex); +} + +//======================================================================= +//function : ShapeToIndex +//purpose : +//======================================================================= +int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const +{ + if (myShape.IsNull()) + MESSAGE("myShape is NULL"); + + int index = myIndexToShape.FindIndex(S); + + return index; +} + +//======================================================================= +//function : SetNodeOnVolume +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) +{ + addNodeToSubmesh( aNode, Index ); +} + +//======================================================================= +//function : SetNodeOnFace +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v) +{ + //Set Position on Node + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v))); + + addNodeToSubmesh( aNode, Index ); +} + +//======================================================================= +//function : SetNodeOnEdge +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, + int Index, + double u) +{ + //Set Position on Node + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u))); + + addNodeToSubmesh( aNode, Index ); +} + +//======================================================================= +//function : SetNodeOnVertex +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) +{ + //Set Position on Node + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); + + addNodeToSubmesh( aNode, Index ); +} + +//======================================================================= +//function : SetMeshElementOnShape +//purpose : +//======================================================================= +void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, + int Index) +{ + if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) + myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh(); + + myShapeIndexToSubMesh[Index]->AddElement(anElement); +} + +SMESHDS_Mesh::~SMESHDS_Mesh() +{ +} diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx new file mode 100644 index 000000000..5bdbfc6a4 --- /dev/null +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -0,0 +1,299 @@ +// SMESH SMESHDS : management of mesh data and SMESH document +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_SubMesh.cxx +// Author : Yves FRICAUD, OCC +// Module : SMESH +// $Header: + +#include "SMESHDS_SubMesh.hxx" + +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : AddElement +//purpose : +//======================================================================= +void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) +{ + if ( !IsComplexSubmesh() ) + myElements.insert(ME); +} + +//======================================================================= +//function : RemoveElement +//purpose : +//======================================================================= +bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME) +{ + if ( !IsComplexSubmesh() && NbElements() ) + return myElements.erase(ME); + + return false; +} + +//======================================================================= +//function : AddNode +//purpose : +//======================================================================= +void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) +{ + if ( !IsComplexSubmesh() ) + myNodes.insert(N); +} + +//======================================================================= +//function : RemoveNode +//purpose : +//======================================================================= + +bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) +{ + if ( !IsComplexSubmesh() && NbNodes() ) + return myNodes.erase(N); + + return false; +} + +//======================================================================= +//function : NbElements +//purpose : +//======================================================================= +int SMESHDS_SubMesh::NbElements() const +{ + if ( !IsComplexSubmesh() ) + return myElements.size(); + + int nbElems = 0; +#ifndef WNT + set::iterator it = mySubMeshes.begin(); +#else + set::const_iterator it = mySubMeshes.begin(); +#endif + for ( ; it != mySubMeshes.end(); it++ ) + nbElems += (*it)->NbElements(); + + return nbElems; +} + +//======================================================================= +//function : NbNodes +//purpose : +//======================================================================= + +int SMESHDS_SubMesh::NbNodes() const +{ + if ( !IsComplexSubmesh() ) + return myNodes.size(); + + int nbElems = 0; +#ifndef WNT + set::iterator it = mySubMeshes.begin(); +#else + set::const_iterator it = mySubMeshes.begin(); +#endif + for ( ; it != mySubMeshes.end(); it++ ) + nbElems += (*it)->NbNodes(); + + return nbElems; +} + +// ===================== +// class MySetIterator +// ===================== + +template class MySetIterator:public SMDS_Iterator +{ + typedef const set TSet; + typename TSet::const_iterator myIt; + TSet& mySet; + + public: + MySetIterator(const set& s):mySet(s), myIt(s.begin()) + { + } + + bool more() + { + return myIt!=mySet.end(); + } + const T* next() + { + const T* t=*myIt; + myIt++; + return t; + } +}; + +// ===================== +// class MyIterator +// ===================== + +template class MyIterator : public SMDS_Iterator +{ + public: + MyIterator (const set& theSubMeshes) + : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false) + {} + bool more() + { + while (( !myElemIt.get() || !myElemIt->more() ) && + mySubIt != mySubMeshes.end()) + { + myElemIt = getElements(*mySubIt); + mySubIt++; + } + myMore = myElemIt.get() && myElemIt->more(); + return myMore; + } + VALUE next() + { + VALUE elem = 0; + if ( myMore ) + elem = myElemIt->next(); + return elem; + } + protected: + virtual boost::shared_ptr< SMDS_Iterator > + getElements(const SMESHDS_SubMesh*) const = 0; + + private: + bool myMore; + const set& mySubMeshes; + set::const_iterator mySubIt; + boost::shared_ptr< SMDS_Iterator > myElemIt; +}; + +// ===================== +// class MyElemIterator +// ===================== + +class MyElemIterator: public MyIterator +{ + public: + MyElemIterator (const set& theSubMeshes) + :MyIterator( theSubMeshes ) {} + SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const + { return theSubMesh->GetElements(); } +}; + +// ===================== +// class MyNodeIterator +// ===================== + +class MyNodeIterator: public MyIterator +{ + public: + MyNodeIterator (const set& theSubMeshes) + :MyIterator( theSubMeshes ) {} + SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const + { return theSubMesh->GetNodes(); } +}; + +//======================================================================= +//function : GetElements +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const +{ + if ( IsComplexSubmesh() ) + return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); + + return SMDS_ElemIteratorPtr(new MySetIterator(myElements)); +} + +//======================================================================= +//function : GetNodes +//purpose : +//======================================================================= + +SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const +{ + if ( IsComplexSubmesh() ) + return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); + + return SMDS_NodeIteratorPtr(new MySetIterator(myNodes)); +} + +//======================================================================= +//function : Contains +//purpose : check if elem or node is in +//======================================================================= + +bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const +{ + // DO NOT TRY TO FIND A REMOVED ELEMENT !! + if ( !ME ) + return false; + + if ( IsComplexSubmesh() ) + { + set::const_iterator aSubIt = mySubMeshes.begin(); + for ( ; aSubIt != mySubMeshes.end(); aSubIt++ ) + if ( (*aSubIt)->Contains( ME )) + return true; + return false; + } + + if ( ME->GetType() == SMDSAbs_Node ) + { + const SMDS_MeshNode* n = static_cast( ME ); + return ( myNodes.find( n ) != myNodes.end() ); + } + + return ( myElements.find( ME ) != myElements.end() ); +} + +//======================================================================= +//function : AddSubMesh +//purpose : +//======================================================================= + +void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh ) +{ + ASSERT( theSubMesh ); + mySubMeshes.insert( theSubMesh ); +} + +//======================================================================= +//function : RemoveSubMesh +//purpose : +//======================================================================= + +bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh ) +{ + return mySubMeshes.erase( theSubMesh ); +} + +//======================================================================= +//function : ContainsSubMesh +//purpose : +//======================================================================= + +bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const +{ + return mySubMeshes.find( theSubMesh ) != mySubMeshes.end(); +} diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx new file mode 100644 index 000000000..ac3cd1c3f --- /dev/null +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -0,0 +1,69 @@ +// SMESH SMESHDS : management of mesh data and SMESH document +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHDS_SubMesh.hxx +// Module : SMESH + +#ifndef _SMESHDS_SubMesh_HeaderFile +#define _SMESHDS_SubMesh_HeaderFile + +#include "SMDS_Mesh.hxx" +#include + +#if defined WNT && defined WIN32 && defined SMESHDS_EXPORTS +#define SMESHDS_WNT_EXPORT __declspec( dllexport ) +#else +#define SMESHDS_WNT_EXPORT +#endif + +class SMESHDS_WNT_EXPORT SMESHDS_SubMesh +{ + public: + + bool IsComplexSubmesh() const { return !mySubMeshes.empty(); } + + // if !IsComplexSubmesh() + void AddElement(const SMDS_MeshElement * ME); + bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in + void AddNode(const SMDS_MeshNode * ME); + bool RemoveNode(const SMDS_MeshNode * ME); // ret true if ME was in + + // if IsComplexSubmesh() + void AddSubMesh( const SMESHDS_SubMesh* theSubMesh ); + bool RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh ); + bool ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const; + + // for both types + int NbElements() const; + SMDS_ElemIteratorPtr GetElements() const; + int NbNodes() const; + SMDS_NodeIteratorPtr GetNodes() const; + bool Contains(const SMDS_MeshElement * ME) const; // check if elem or node is in + + private: + //const SMDS_Mesh * myMesh; + std::set myElements; + std::set myNodes; + std::set mySubMeshes; +}; +#endif diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx new file mode 100644 index 000000000..349eb3ec4 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -0,0 +1,3059 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// File : SMESHGUI.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#include "SMESHGUI.h" + +#include "SMESHGUI_InitMeshDlg.h" +#include "SMESHGUI_AddSubMeshDlg.h" +#include "SMESHGUI_NodesDlg.h" +#include "SMESHGUI_TransparencyDlg.h" +#include "SMESHGUI_ClippingDlg.h" +#include "SMESHGUI_GroupDlg.h" +#include "SMESHGUI_RemoveNodesDlg.h" +#include "SMESHGUI_RemoveElementsDlg.h" +#include "SMESHGUI_MeshInfosDlg.h" +#include "SMESHGUI_StandardMeshInfosDlg.h" +#include "SMESHGUI_Preferences_ColorDlg.h" +#include "SMESHGUI_Preferences_ScalarBarDlg.h" +#include "SMESHGUI_Preferences_SelectionDlg.h" +#include "SMESHGUI_Hypotheses.h" +#include "SMESHGUI_MoveNodesDlg.h" +#include "SMESHGUI_AddMeshElementDlg.h" +#include "SMESHGUI_EditHypothesesDlg.h" +#include "SMESHGUI_CreateHypothesesDlg.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_FilterLibraryDlg.h" +#include "SMESHGUI_SingleEditDlg.h" +#include "SMESHGUI_MultiEditDlg.h" +#include "SMESHGUI_GroupOpDlg.h" +#include "SMESHGUI_DeleteGroupDlg.h" +#include "SMESHGUI_SmoothingDlg.h" +#include "SMESHGUI_RenumberingDlg.h" +#include "SMESHGUI_ExtrusionDlg.h" +#include "SMESHGUI_ExtrusionAlongPathDlg.h" +#include "SMESHGUI_RevolutionDlg.h" +#include "SMESHGUI_TranslationDlg.h" +#include "SMESHGUI_RotationDlg.h" +#include "SMESHGUI_SymmetryDlg.h" +#include "SMESHGUI_SewingDlg.h" +#include "SMESHGUI_MergeNodesDlg.h" +#include "SMESHGUI_EditMeshDlg.h" +#include "SMESHGUI_MeshPatternDlg.h" +#include "SMESHGUI_PrecisionDlg.h" +#include "SMESHGUI_Selection.h" +#include "SMESHGUI_CreatePolyhedralVolumeDlg.h" +#include "SMESHGUI_MeshOp.h" + +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GroupUtils.h" +#include "SMESHGUI_FilterUtils.h" +#include "SMESHGUI_PatternUtils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_HypothesesUtils.h" + +#include "SMESH_Actor.h" +#include "SMESH_Object.h" +#include "SMESH_TypeFilter.hxx" + +#include "SalomeApp_Tools.h" +#include "SalomeApp_Study.h" +#include "SalomeApp_NameDlg.h" +#include "SalomeApp_DataOwner.h" +#include "SalomeApp_Application.h" +#include "SalomeApp_Preferences.h" +#include "SalomeApp_VTKSelector.h" +#include "SalomeApp_Operation.h" +#include "SalomeApp_UpdateFlags.h" + +#include "SalomeApp_ImportOperation.h" + +#include +#include +#include +#include + +#include + +#include "OB_Browser.h" + +#include "SUIT_Tools.h" +#include "SUIT_MessageBox.h" +#include "SUIT_ResourceMgr.h" +#include "SUIT_FileDlg.h" +#include "SUIT_Desktop.h" +#include "SUIT_ResourceMgr.h" +#include "SUIT_OverrideCursor.h" +#include "SUIT_Study.h" +#include "SUIT_Session.h" + +#include "QtxPopupMgr.h" + +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" +#include "SALOME_InteractiveObject.hxx" +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" + +#include "SALOMEconfig.h" +#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) + +// QT Includes +#define INCLUDE_MENUITEM_DEF +#include +#include +#include +#include + +// BOOST Includes +#include + +// VTK Includes +#include +#include +#include +#include +#include + +#include "utilities.h" + +#include "SALOMEDS_Study.hxx" +#include "SALOMEDSClient_StudyBuilder.hxx" +#include "SALOMEDSClient_SComponent.hxx" + +using namespace std; + +namespace{ + // Decalarations + //============================================================= + void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh, + int theCommandID); + + void ExportMeshToFile(int theCommandID); + + void SetDisplayMode(int theCommandID); + + void SetDisplayEntity(int theCommandID); + + void Control( int theCommandID ); + + + // Definitions + //============================================================= + void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh, + int theCommandID) + { + QStringList filter; + string myExtension; + + if(theCommandID == 113){ + filter.append(QObject::tr("MED files (*.med)")); + filter.append(QObject::tr("All files (*)")); + }else if (theCommandID == 112){ + filter.append(QObject::tr("IDEAS files (*.unv)")); + }else if (theCommandID == 111){ + filter.append(QObject::tr("DAT files (*.dat)")); + } + QString filename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), + "", + filter, + QObject::tr("Import mesh"), + true); + if(!filename.isEmpty()) { + SUIT_OverrideCursor wc; + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + theComponentMesh->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() ); + + try { + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + switch ( theCommandID ) { + case 112: + { + aMeshes->length( 1 ); + aMeshes[0] = theComponentMesh->CreateMeshesFromUNV(filename.latin1()); + break; + } + case 113: + { + SMESH::DriverMED_ReadStatus res; + aMeshes = theComponentMesh->CreateMeshesFromMED(filename.latin1(),res); + if ( res != SMESH::DRS_OK ) { + wc.suspend(); + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr(QString("SMESH_DRS_%1").arg(res)), + QObject::tr("SMESH_BUT_OK")); + aMeshes->length( 0 ); + wc.resume(); + } + break; + } + } + + bool isEmpty = false; + for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) { + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] ); + if ( aMeshSO ) { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ); + aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_IMPORTED"); + if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import + SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() ); + } else + isEmpty = true; + } + + if ( isEmpty ) { + wc.suspend(); + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_DRS_EMPTY"), + QObject::tr("SMESH_BUT_OK")); + wc.resume(); + } + + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + } + catch (const SALOME::SALOME_Exception& S_ex){ + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + wc.resume(); + } + } + } + + + void ExportMeshToFile( int theCommandID ) + { + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if(selected.Extent()){ + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface(anIObject); + if ( !aMesh->_is_nil() ) { + QString aFilter, aTitle = QObject::tr("Export mesh"); + QMap aFilterMap; + switch ( theCommandID ) { + case 125: + case 122: + aFilterMap.insert( QObject::tr("MED 2.1 (*.med)"), SMESH::MED_V2_1 ); + aFilterMap.insert( QObject::tr("MED 2.2 (*.med)"), SMESH::MED_V2_2 ); + break; + case 124: + case 121: + aFilter = QObject::tr("DAT files (*.dat)"); + break; + case 126: + case 123: { + if(aMesh->NbPyramids()){ + int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), + 0,1,0); + if(aRet) + return; + } + aFilter = QObject::tr("IDEAS files (*.unv)"); + break; + default: + return; + }} + + QString aFilename; + SMESH::MED_VERSION aFormat; + + if ( theCommandID != 122 && theCommandID != 125 ) + aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), "", aFilter, aTitle, false); + else + { + QStringList filters; + for ( QMap::const_iterator it = aFilterMap.begin(); it != aFilterMap.end(); ++it ) + filters.push_back( it.key() ); + + SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); + fd->setCaption( aTitle ); + fd->setFilters( filters ); + bool is_ok = false; + while(!is_ok){ + fd->exec(); + aFilename = fd->selectedFile(); + aFormat = aFilterMap[fd->selectedFilter()]; + is_ok = true; + if( !aFilename.isEmpty() + && (aMesh->NbPolygons()>0 or aMesh->NbPolyhedrons()>0) + && aFormat==SMESH::MED_V2_1){ + int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), + 0,1,0); + if(aRet){ + is_ok = false; + } + } + } + delete fd; + } + if ( !aFilename.isEmpty() ) { + // Check whether the file already exists and delete it if yes + QFile aFile( aFilename ); + if ( aFile.exists() ) + aFile.remove(); + SUIT_OverrideCursor wc; + switch ( theCommandID ) { + case 125: + case 122: + aMesh->ExportToMED( aFilename.latin1(), false, aFormat ); // currently, automatic groups are never created + break; + case 124: + case 121: + aMesh->ExportDAT( aFilename.latin1() ); + break; + case 126: + case 123: + aMesh->ExportUNV( aFilename.latin1() ); + break; + default: + break; + } + } + } + } + } + + inline void InverseEntityMode(unsigned int& theOutputMode, + unsigned int theMode) + { + bool anIsNotPresent = ~theOutputMode & theMode; + if(anIsNotPresent) + theOutputMode |= theMode; + else + theOutputMode &= ~theMode; + } + + void SetDisplayEntity(int theCommandID){ + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if(selected.Extent() >= 1){ + SALOME_ListIteratorOfListIO It( selected ); + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + unsigned int aMode = anActor->GetEntityMode(); + switch(theCommandID){ + case 217: + InverseEntityMode(aMode,SMESH_Actor::eEdges); + break; + case 218: + InverseEntityMode(aMode,SMESH_Actor::eFaces); + break; + case 219: + InverseEntityMode(aMode,SMESH_Actor::eVolumes); + break; + case 220: + aMode = SMESH_Actor::eAllEntity; + break; + } + if(aMode) + anActor->SetEntityMode(aMode); + } + } + } + } + } + + void SetDisplayMode(int theCommandID){ + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if(selected.Extent() >= 1){ + switch(theCommandID){ + case 1134:{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI(), "", false ); + return; + } + case 1133:{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI(), "", false ); + return; + }} + SALOME_ListIteratorOfListIO It( selected ); + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + switch(theCommandID){ + case 211: + anActor->SetRepresentation(SMESH_Actor::eEdge); + break; + case 212: + anActor->SetRepresentation(SMESH_Actor::eSurface); + break; + case 213: + if(anActor->IsShrunk()) + anActor->UnShrink(); + else + anActor->SetShrink(); + break; + case 215: + anActor->SetRepresentation(SMESH_Actor::ePoint); + break; + case 1132:{ + float color[3]; + anActor->GetSufaceColor(color[0], color[1], color[2]); + int c0 = int (color[0] * 255); + int c1 = int (color[1] * 255); + int c2 = int (color[2] * 255); + QColor c(c0, c1, c2); + + float edgecolor[3]; + anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); + c0 = int (edgecolor[0] * 255); + c1 = int (edgecolor[1] * 255); + c2 = int (edgecolor[2] * 255); + QColor e(c0, c1, c2); + + float backfacecolor[3]; + anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]); + c0 = int (backfacecolor[0] * 255); + c1 = int (backfacecolor[1] * 255); + c2 = int (backfacecolor[2] * 255); + QColor b(c0, c1, c2); + + float nodecolor[3]; + anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); + c0 = int (nodecolor[0] * 255); + c1 = int (nodecolor[1] * 255); + c2 = int (nodecolor[2] * 255); + QColor n(c0, c1, c2); + + int Edgewidth = (int)anActor->GetLineWidth(); + if(Edgewidth == 0) + Edgewidth = 1; + int intValue = int(anActor->GetNodeSize()); + float Shrink = anActor->GetShrinkFactor(); + + SMESHGUI_Preferences_ColorDlg *aDlg = + new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI(), "" ); + aDlg->SetColor(1, c); + aDlg->SetColor(2, e); + aDlg->SetColor(3, n); + aDlg->SetColor(4, b); + aDlg->SetIntValue(1, Edgewidth); + aDlg->SetIntValue(2, intValue); + aDlg->SetIntValue(3, int(Shrink*100.)); + if(aDlg->exec()){ + QColor color = aDlg->GetColor(1); + QColor edgecolor = aDlg->GetColor(2); + QColor nodecolor = aDlg->GetColor(3); + QColor backfacecolor = aDlg->GetColor(4); + /* actor color and backface color */ + anActor->SetSufaceColor(float (color.red()) / 255., + float (color.green()) / 255., + float (color.blue()) / 255.); + anActor->SetBackSufaceColor(float (backfacecolor.red()) / 255., + float (backfacecolor.green()) / 255., + float (backfacecolor.blue()) / 255.); + + /* edge color */ + anActor->SetEdgeColor(float (edgecolor.red()) / 255., + float (edgecolor.green()) / 255., + float (edgecolor.blue()) / 255.); + + /* Shrink factor and size edges */ + anActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.); + anActor->SetLineWidth(aDlg->GetIntValue(1)); + + /* Nodes color and size */ + anActor->SetNodeColor(float (nodecolor.red()) / 255., + float (nodecolor.green()) / 255., + float (nodecolor.blue()) / 255.); + anActor->SetNodeSize(aDlg->GetIntValue(2)); + + delete aDlg; + } + break; + }} + } + } + } + SMESH::RepaintCurrentView(); + } + } + + void Control( int theCommandID ) + { + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if( !selected.IsEmpty() ){ + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if(!anIO.IsNull()){ + QString aTitle; + SMESH_Actor::eControl aControl = SMESH_Actor::eNone; + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){ + switch ( theCommandID ){ + case 6001: + aTitle = QObject::tr( "LENGTH_EDGES" ); + aControl = SMESH_Actor::eLength; + break; + case 6018: + aTitle = QObject::tr( "LENGTH2D_EDGES" ); + aControl = SMESH_Actor::eLength2D; + break; + case 6002: + aTitle = QObject::tr( "FREE_EDGES" ); + aControl = SMESH_Actor::eFreeEdges; + break; + case 6003: + aTitle = QObject::tr( "FREE_BORDERS" ); + aControl = SMESH_Actor::eFreeBorders; + break; + case 6004: + aTitle = QObject::tr( "MULTI_BORDERS" ); + aControl = SMESH_Actor::eMultiConnection; + break; + case 6019: + aTitle = QObject::tr( "MULTI2D_BORDERS" ); + aControl = SMESH_Actor::eMultiConnection2D; + break; + case 6011: + aTitle = QObject::tr( "AREA_ELEMENTS" ); + aControl = SMESH_Actor::eArea; + break; + case 6012: + aTitle = QObject::tr( "TAPER_ELEMENTS" ); + aControl = SMESH_Actor::eTaper; + break; + case 6013: + aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" ); + aControl = SMESH_Actor::eAspectRatio; + break; + case 6017: + aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" ); + aControl = SMESH_Actor::eAspectRatio3D; + break; + case 6014: + aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" ); + aControl = SMESH_Actor::eMinimumAngle; + break; + case 6015: + aTitle = QObject::tr( "WARP_ELEMENTS" ); + aControl = SMESH_Actor::eWarping; + break; + case 6016: + aTitle = QObject::tr( "SKEW_ELEMENTS" ); + aControl = SMESH_Actor::eSkew; + break; + } + anActor->SetControlMode(aControl); + anActor->GetScalarBarActor()->SetTitle(aTitle.latin1()); + SMESH::RepaintCurrentView(); + } + } + } + } + + + bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO, + MeshObjectType theType, + const QString theInTypeName, + QString & theOutTypeName) + { + SMESH_TypeFilter aTypeFilter( theType ); + QString entry; + if( !theIO.IsNull() ) + { + entry = theIO->getEntry(); + SalomeApp_DataOwner owner( entry ); + if ( aTypeFilter.isOk( &owner )) { + theOutTypeName = theInTypeName; + return true; + } + } + return false; + } + + + QString CheckTypeObject(const Handle(SALOME_InteractiveObject) & theIO) + { + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + _PTR(SObject) aSObj = aStudy->FindObjectID(theIO->getEntry()); + if (aSObj) { + _PTR(SComponent) aSComp = aSObj->GetFatherComponent(); + CORBA::String_var anID = aSComp->GetID().c_str(); + if (!strcmp(anID.in(),theIO->getEntry())) + return "Component"; + } + + QString aTypeName; + if ( + CheckOIType ( theIO, HYPOTHESIS, "Hypothesis", aTypeName ) || + CheckOIType ( theIO, ALGORITHM, "Algorithm", aTypeName ) || + CheckOIType ( theIO, MESH, "Mesh", aTypeName ) || + CheckOIType ( theIO, SUBMESH, "SubMesh", aTypeName ) || + CheckOIType ( theIO, GROUP, "Group", aTypeName ) + ) + return aTypeName; + + return "NoType"; + } + + + QString CheckHomogeneousSelection() + { + //SUIT_Study* aStudy = SMESH::GetActiveStudy(); + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + QString RefType = CheckTypeObject(selected.First()); + SALOME_ListIteratorOfListIO It(selected); + for (; It.More(); It.Next()) + { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + QString Type = CheckTypeObject(IObject); + if (Type.compare(RefType) != 0) + return "Heterogeneous Selection"; + } + + return RefType; + } + + + void SMESHGUI::OnEditDelete() + { + // VSR 17/11/04: check if all objects selected belong to SMESH component --> start + SalomeApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; aSel->selectedObjects( selected ); + + QString aParentComponent = QString::null; + for( SALOME_ListIteratorOfListIO anIt( selected ); anIt.More(); anIt.Next() ) + { + QString cur = anIt.Value()->getComponentDataType(); + if( aParentComponent.isNull() ) + aParentComponent = cur; + else if( !aParentComponent.isEmpty() && aParentComponent!=cur ) + aParentComponent = ""; + } + + if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() ) { + SUIT_MessageBox::warn1 ( SMESHGUI::desktop(), + QObject::tr("ERR_ERROR"), + QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ), + QObject::tr("BUT_OK") ); + return; + } + // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish + if (SUIT_MessageBox::warn2 + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_REALLY_DELETE"), + QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"), 1, 0, 0) != 1) + return; + + SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); + SUIT_ViewManager* vm = anApp->activeViewManager(); + int nbSf = vm->getViewsCount(); + + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder(); + _PTR(GenericAttribute) anAttr; + _PTR(AttributeIOR) anIOR; + + SALOME_ListIteratorOfListIO It(selected); + + aStudyBuilder->NewCommand(); // There is a transaction + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + _PTR(SObject) SO = aStudy->FindObjectID(IObject->getEntry()); + + // disable removal of "SMESH" component object + if(SO->FindAttribute(anAttr, "AttributeIOR")){ + anIOR = anAttr; + if ( !strcmp( (char*)anIOR->Value().c_str(), engineIOR().latin1() ) ) + continue; + } + + /* Erase child graphical objects */ + _PTR(ChildIterator) it = aStudy->NewChildIterator(SO); + for(it->InitEx(true); it->More(); it->Next()){ + _PTR(SObject) CSO = it->Value(); + if(CSO->FindAttribute(anAttr, "AttributeIOR")){ + anIOR = anAttr; + + QPtrVector aViews = vm->getViews(); + for(int i = 0; i < nbSf; i++){ + SUIT_ViewWindow *sf = aViews[i]; + CORBA::String_var anEntry = CSO->GetID().c_str(); + if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.in())){ + SMESH::RemoveActor(sf,anActor); + } + } + } + } + + /* Erase main graphical object */ + QPtrVector aViews = vm->getViews(); + for(int i = 0; i < nbSf; i++){ + SUIT_ViewWindow *sf = aViews[i]; + if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,IObject->getEntry())){ + SMESH::RemoveActor(sf,anActor); + } + } + + // Remove object(s) from data structures + _PTR(SObject) obj = aStudy->FindObjectID(IObject->getEntry()); + if(obj){ + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( obj ) ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( obj ) ); + QString objType = CheckTypeObject(IObject); + if ( !aGroup->_is_nil() ) { // DELETE GROUP + SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh(); + aMesh->RemoveGroup( aGroup ); + } + else if ( !aSubMesh->_is_nil() ) { // DELETE SUBMESH + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + aMesh->RemoveSubMesh( aSubMesh ); + } + else if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS + SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); + aStudyBuilder->RemoveObjectWithChildren( obj ); + } + else {// default action: remove SObject from the study + // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH + //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy); + //op->start(); + aStudyBuilder->RemoveObjectWithChildren( obj ); + //op->finish(); + } + } + + } /* IObject->hasEntry() */ + } /* more/next */ + aStudyBuilder->CommitCommand(); + + /* Clear any previous selection */ + SALOME_ListIO l1; + aSel->setSelectedObjects( l1 ); + + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + } +} + +extern "C" { + Standard_EXPORT CAM_Module* createModule() + { + return new SMESHGUI(); + } +} + +SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil(); + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESHGUI::SMESHGUI() : +SalomeApp_Module( "SMESH" ) +{ + if ( CORBA::is_nil( myComponentSMESH ) ) + { + SALOME_LifeCycleCORBA* ls = new SALOME_LifeCycleCORBA( getApp()->namingService() ); + Engines::Component_var comp = ls->FindOrLoad_Component( "FactoryServer", "SMESH" ); + myComponentSMESH = SMESH::SMESH_Gen::_narrow( comp ); + } + + myActiveDialogBox = 0 ; + myState = -1 ; + + SMESH::GetFilterManager(); + SMESH::GetPattern(); + + /* load resources for all available meshers */ + SMESH::InitAvailableHypotheses(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESHGUI::~SMESHGUI() +{ + SMESH::GetFilterManager()->Destroy(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SalomeApp_SelectionMgr* SMESHGUI::selectionMgr() +{ + SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( anApp ) + return dynamic_cast( anApp->selectionMgr() ); + else + return 0; +} + +bool SMESHGUI::automaticUpdate() +{ + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( !resMgr ) + return false; + + return resMgr->booleanValue( "SMESH", "auto_update", false ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SUIT_ResourceMgr* SMESHGUI::resourceMgr() +{ + return dynamic_cast( SUIT_Session::session()->resourceMgr() ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESHGUI* SMESHGUI::GetSMESHGUI() +{ + SMESHGUI* smeshMod = 0; + SalomeApp_Application* app = dynamic_cast(SUIT_Session::session()->activeApplication()); + if ( app ) + { + CAM_Module* module = app->module( "Mesh" ); + smeshMod = dynamic_cast( module ); + } + + if ( smeshMod && smeshMod->application() && smeshMod->application()->activeStudy() ) + { + SalomeApp_Study* study = dynamic_cast( smeshMod->application()->activeStudy() ); + if ( study ) + { + _PTR(Study) aStudy = study->studyDS(); + if ( aStudy ) + GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() ); + } + } + + return smeshMod; +} + +extern "C" +{ + Standard_EXPORT SMESHGUI* GetComponentGUI() + { + return SMESHGUI::GetSMESHGUI(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::SetState(int aState) +{ + myState = aState; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::ResetState() +{ + myState = -1; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::EmitSignalDeactivateDialog() +{ + emit SignalDeactivateActiveDialog(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::EmitSignalStudyFrameChanged() +{ + emit SignalStudyFrameChanged(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::EmitSignalCloseAllDialogs() +{ + emit SignalCloseAllDialogs(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +QDialog *SMESHGUI::GetActiveDialogBox() +{ + return myActiveDialogBox; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::SetActiveDialogBox(QDialog * aDlg) +{ + myActiveDialogBox = (QDialog *) aDlg; + return; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SUIT_Desktop* SMESHGUI::desktop() +{ + SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( app ) + return app->desktop(); + else + return 0; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SalomeApp_Study* SMESHGUI::activeStudy() +{ + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if( app ) + return dynamic_cast( app->activeStudy() ); + else + return NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y) +{ + /* Here the position is on the bottom right corner - 10 */ + // aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint())); + aDlg->adjustSize(); + SUIT_Desktop *PP = desktop(); + x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10); + y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +static int isStudyLocked(_PTR(Study) theStudy){ + return theStudy->GetProperties()->IsLocked(); +} + +static bool checkLock(_PTR(Study) theStudy) { + if (isStudyLocked(theStudy)) { + SUIT_MessageBox::warn1 ( SMESHGUI::desktop(), + QObject::tr("WRN_WARNING"), + QObject::tr("WRN_STUDY_LOCKED"), + QObject::tr("BUT_OK") ); + return true; + } + return false; +} + +//======================================================================= +//function : CheckActiveStudyLocked +//purpose : +//======================================================================= + +bool SMESHGUI::isActiveStudyLocked() +{ + _PTR(Study) aStudy = activeStudy()->studyDS(); + return checkLock( aStudy ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::OnGUIEvent( int theCommandID ) +{ + SalomeApp_Application* anApp = dynamic_cast( application() ); + if( !anApp ) + return false; + + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); //Document OCAF de l'etude active + SUIT_ResourceMgr* mgr = resourceMgr(); + if( !mgr ) + return false; + + SUIT_ViewWindow* view = application()->desktop()->activeWindow(); + SVTK_ViewWindow* vtkwnd = dynamic_cast( view ); + + //QAction* act = action( theCommandID ); + + switch (theCommandID) { + case 33: // DELETE + if(checkLock(aStudy)) break; + OnEditDelete(); + break; + + case 113: // IMPORT + case 112: + case 111: + { + if(checkLock(aStudy)) break; + ::ImportMeshesFromFile(GetSMESHGen(),theCommandID); + break; + } + + case 122: // EXPORT MED + case 121: + case 123: + case 124: + case 125: + case 126: + { + ::ExportMeshToFile(theCommandID); + break; + } + + case 200: // SCALAR BAR + { + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if( selected.Extent() ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if( anIO->hasEntry() ) { + if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) { + anActor->SetControlMode( SMESH_Actor::eNone ); + } + } + } + break; + } + case 201: + { + SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this ); + break; + } + + case 1134: // Clipping + case 1133: // Tranparency + case 1132: // Colors / Size + + // Display Mode + case 215: // Nodes + case 213: // Nodes + case 212: // Nodes + case 211: // Nodes + ::SetDisplayMode(theCommandID); + break; + + // Display Entity + case 217: // Edges + case 218: // Faces + case 219: // Volumes + case 220: // All Entity + ::SetDisplayEntity(theCommandID); + break; + + case 214: // UPDATE + { + if(checkLock(aStudy)) break; + SMESH::UpdateView(); + + SALOME_ListIO l; + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + aSel->setSelectedObjects( l ); + break; + } + + case 300: // ERASE + case 301: // DISPLAY + case 302: // DISPLAY ONLY + { + SMESH::EDisplaing anAction; + switch (theCommandID) { + case 300: anAction = SMESH::eErase; break; + case 301: anAction = SMESH::eDisplay; break; + case 302: anAction = SMESH::eDisplayOnly; break; + } + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if (aSel) + aSel->selectedObjects( selected ); + + if (vtkwnd) { + SALOME_ListIteratorOfListIO It (selected); + for (; It.More(); It.Next()) { + Handle(SALOME_InteractiveObject) IOS = It.Value(); + if (IOS->hasEntry()) { + SMESH::UpdateView(anAction, IOS->getEntry()); + if (anAction == SMESH::eDisplayOnly) + anAction = SMESH::eDisplay; + } + } + } + + if (anAction == SMESH::eErase) { + SALOME_ListIO l1; + aSel->setSelectedObjects( l1 ); + } + else + aSel->setSelectedObjects( selected ); + break; + } + + case 400: // NODES + { + if(checkLock(aStudy)) break; + + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + + new SMESHGUI_NodesDlg(this); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 2151: // FILTER + { + if ( vtkwnd ) + { + EmitSignalDeactivateDialog(); + new SMESHGUI_FilterDlg( this, SMESH::EDGE ); + } + break; + } + + case 406: // MOVE NODE + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if(checkLock(aStudy)) break; + new SMESHGUI_MoveNodesDlg(this); + break; + } + + case 701: // COMPUTE MESH + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + SalomeApp_SelectionMgr *Sel = selectionMgr(); + SALOME_ListIO selected; Sel->selectedObjects( selected ); + + int nbSel = selected.Extent(); + if (nbSel != 1){ + break; + } + + SMESH::SMESH_Mesh_var aMesh; + SMESH::SMESH_subMesh_var aSubMesh; + Handle(SALOME_InteractiveObject) IObject = selected.First(); + if (IObject->hasEntry()){ + _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry()); + GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj ); + if ( aShapeObject->_is_nil() ) { + // imported mesh + break; + } + if( aMeshSObj ) { + SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface(aMeshSObj); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface(aMeshSObj); + + if (!aMesh->_is_nil()){ + GEOM::GEOM_Object_var refShapeObject = SMESH::GetShapeOnMeshOrSubMesh(aMeshSObj); + if (!refShapeObject->_is_nil()) { + if(!GetSMESHGen()->IsReadyToCompute(aMesh,refShapeObject)){ + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_MISSING_PARAMETERS"), + tr("SMESH_BUT_OK")); + break; + } + try{ + if (GetSMESHGen()->Compute(aMesh,refShapeObject)) + SMESH::ModifiedMesh(aMeshSObj,true); + // TO Do : change icon of all submeshes + else + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_COMPUTE_FAILED"), + tr("SMESH_BUT_OK")); + } + catch(const SALOME::SALOME_Exception & S_ex){ + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + } + }else if(!aSubMesh->_is_nil()){ + aMesh = aSubMesh->GetFather(); + GEOM::GEOM_Object_var refShapeObject = SMESH::GetShapeOnMeshOrSubMesh(aMeshSObj); + if(!refShapeObject->_is_nil()){ + bool compute = GetSMESHGen()->IsReadyToCompute(aMesh,refShapeObject); + if(!compute){ + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_MISSING_PARAMETERS"), + tr("SMESH_BUT_OK")); + break; + } + try{ + if ( GetSMESHGen()->Compute(aMesh,refShapeObject) ) + SMESH::ModifiedMesh(aMeshSObj,true); + // TO Do : change icon of all submeshes + else + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_COMPUTE_FAILED"), + tr("SMESH_BUT_OK")); + }catch(const SALOME::SALOME_Exception & S_ex){ + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + } + } + } + } + CORBA::Long anId = aStudy->StudyId(); + TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,IObject->getEntry()); + if ( automaticUpdate() && aVisualObj){ + aVisualObj->Update(); + SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry()); + if(!anActor){ + anActor = SMESH::CreateActor(aStudy,IObject->getEntry()); + if(anActor){ + SMESH::DisplayActor(view,anActor); //apo + SMESH::FitAll(); + } + } + SMESH::RepaintCurrentView(); + } + }else{ + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + updateObjBrowser(); + break; + } + + case 702: // Create mesh + startOperation( 702 ); + break; + case 703: // Create sub-mesh + startOperation( 703 ); + break; + case 704: // Edit mesh/sub-mesh + startOperation( 704 ); + break; + case 407: // DIAGONAL INVERSION + case 408: // Delete diagonal + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if ( checkLock( aStudy ) ) + break; + + /*Standard_Boolean aRes; + SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface(IObject); + if ( aMesh->_is_nil() ) + { + SUIT_MessageBox::warn1(GetDesktop(), tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_BAD_SELECTION" ), tr( "SMESH_BUT_OK" ) ); + break; + } + */ + EmitSignalDeactivateDialog(); + if ( theCommandID == 407 ) + new SMESHGUI_TrianglesInversionDlg(this); + else + new SMESHGUI_UnionOfTwoTrianglesDlg(this); + break; + } + case 409: // Change orientation + case 410: // Union of triangles + case 411: // Cutting of quadrangles + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if ( checkLock( aStudy ) ) + break; + + EmitSignalDeactivateDialog(); + SMESHGUI_MultiEditDlg* aDlg = NULL; + if ( theCommandID == 409 ) + aDlg = new SMESHGUI_ChangeOrientationDlg(this); + else if ( theCommandID == 410 ) + aDlg = new SMESHGUI_UnionOfTrianglesDlg(this); + else + aDlg = new SMESHGUI_CuttingOfQuadsDlg(this); + + int x, y ; + DefineDlgPosition( aDlg, x, y ); + aDlg->move( x, y ); + aDlg->show(); + break; + } + case 412: // Smoothing + { + if(checkLock(aStudy)) break; + if( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_SmoothingDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 413: // Extrusion + { + if (checkLock(aStudy)) break; + if (vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_ExtrusionDlg ( this ); + } else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 414: // Revolution + { + if(checkLock(aStudy)) break; + if( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RevolutionDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 415: // Pattern mapping + { + if ( checkLock( aStudy ) ) + break; + if ( vtkwnd ) + { + EmitSignalDeactivateDialog(); + new SMESHGUI_MeshPatternDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 416: // Extrusion along a path + { + if (checkLock(aStudy)) break; + if (vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_ExtrusionAlongPathDlg( this ); + } else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 801: // CREATE GROUP + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if(checkLock(aStudy)) break; + EmitSignalDeactivateDialog(); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil(); + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + int nbSel = selected.Extent(); + if (nbSel == 1) { + // check if mesh is selected + aMesh = SMESH::GetMeshByIO( selected.First() ); + } + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", aMesh); + aDlg->show(); + break; + } + + case 802: // CONSTRUCT GROUP + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if(checkLock(aStudy)) break; + EmitSignalDeactivateDialog(); + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + int nbSel = selected.Extent(); + if (nbSel == 1) { + // check if submesh is selected + Handle(SALOME_InteractiveObject) IObject = selected.First(); + if (IObject->hasEntry()) { + _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry()); + if( aSObj ) { + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) ); + if (!aSubMesh->_is_nil()) { + try { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + // get submesh elements list by types + SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE); + SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE); + SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE); + SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME); + // create group for each type o elements + QString aName = IObject->getName(); + if (aNodes->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes"); + aGroup->Add(aNodes.inout()); + } + if (aEdges->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges"); + aGroup->Add(aEdges.inout()); + } + if (aFaces->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces"); + aGroup->Add(aFaces.inout()); + } + if (aVolumes->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes"); + aGroup->Add(aVolumes.inout()); + } + updateObjBrowser(); + + }catch(const SALOME::SALOME_Exception & S_ex){ + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + } + } + } + } + break; + } + + case 803: // EDIT GROUP + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if(checkLock(aStudy)) break; + EmitSignalDeactivateDialog(); + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + SALOME_ListIteratorOfListIO It (selected); + int nbSelectedGroups = 0; + for ( ; It.More(); It.Next() ) + { + SMESH::SMESH_Group_var aGroup = + SMESH::IObjectToInterface(It.Value()); + if (!aGroup->_is_nil()) { + nbSelectedGroups++; + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", aGroup); + aDlg->show(); + } + } + if (nbSelectedGroups == 0) + { + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", SMESH::SMESH_Group::_nil()); + aDlg->show(); + } + break; + } + + case 804: // Add elements to group + { + if(checkLock(aStudy)) break; + if (myState == 800) { + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; + if (aDlg) aDlg->onAdd(); + } + break; + } + + case 805: // Remove elements from group + { + if(checkLock(aStudy)) break; + if (myState == 800) { + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; + if (aDlg) aDlg->onRemove(); + } + break; + } + + case 810: // Union Groups + case 811: // Intersect groups + case 812: // Cut groups + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if ( checkLock( aStudy ) ) + break; + + EmitSignalDeactivateDialog(); + + int aMode; + if ( theCommandID == 810 ) aMode = SMESHGUI_GroupOpDlg::UNION; + else if ( theCommandID == 811 ) aMode = SMESHGUI_GroupOpDlg::INTERSECT; + else aMode = SMESHGUI_GroupOpDlg::CUT; + + ( new SMESHGUI_GroupOpDlg( this, aMode ) )->show(); + break; + } + + case 813: // Delete groups with their contents + { + if ( !vtkwnd ) + { + SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) ); + break; + } + + if ( checkLock( aStudy ) ) + break; + + EmitSignalDeactivateDialog(); + + new SMESHGUI_DeleteGroupDlg( this ); + break; + } + + case 900: // MESH INFOS + { + EmitSignalDeactivateDialog(); + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if ( selected.Extent() > 1 ) { // a dlg for each IO + SALOME_ListIO IOs; + SALOME_ListIteratorOfListIO It (selected); + for ( ; It.More(); It.Next() ) { + IOs.Clear(); IOs.Append( It.Value() ); + aSel->setSelectedObjects( IOs ); + new SMESHGUI_MeshInfosDlg(this, "", false); + } + // restore selection + aSel->setSelectedObjects( selected ); + } + else + new SMESHGUI_MeshInfosDlg(this, "", false); + break; + } + + case 902: // STANDARD MESH INFOS + { + EmitSignalDeactivateDialog(); + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + if ( selected.Extent() > 1 ) { // a dlg for each IO + SALOME_ListIO IOs; + SALOME_ListIteratorOfListIO It (selected); + for ( ; It.More(); It.Next() ) { + IOs.Clear(); + IOs.Append( It.Value() ); + aSel->setSelectedObjects( IOs ); + new SMESHGUI_StandardMeshInfosDlg( this, "", false); + } + // restore selection + aSel->setSelectedObjects( selected ); + } + else + new SMESHGUI_StandardMeshInfosDlg( this, "", false); + break; + } + + case 1100: // EDIT HYPOTHESIS + { + if(checkLock(aStudy)) break; + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + int nbSel = selected.Extent(); + + if (nbSel == 1) { + SMESH::SMESH_Hypothesis_var Hyp = SMESH::IObjectToInterface(selected.First()); + + /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */ + /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */ + /* Warning : however by internal mechanism all subMeshes icons are changed ! */ + if ( !Hyp->_is_nil() ) + { + char* sName = Hyp->GetName(); + SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(sName); + if (aCreator) + { + aCreator->EditHypothesis(Hyp); + } + else + { + // report error + } + } + } + updateObjBrowser( true ); + break; + } + + case 1101: // RENAME + { + if ( checkLock( aStudy ) ) + break; + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + SALOME_ListIteratorOfListIO It( selected ); + for ( ; It.More(); It.Next() ) + { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + _PTR(SObject) obj = aStudy->FindObjectID( IObject->getEntry() ); + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + if ( obj ) + { + if ( obj->FindAttribute(anAttr, "AttributeName") ) + { + aName = anAttr; + QString newName = QString(aName->Value().c_str()); + newName = SalomeApp_NameDlg::getName( desktop(), newName ); + if ( !newName.isEmpty() ) + { + //old source: aStudy->renameIObject( IObject, newName ); + aName->SetValue( newName.latin1() ); + + // if current object is group update group's name + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(IObject); + if (!aGroup->_is_nil() ) + aGroup->SetName( newName.latin1() ); + + updateObjBrowser(); + } + } + } + } + break; + } + + case 1102: // REMOVE HYPOTHESIS / ALGORITHMS + { + if(checkLock(aStudy)) break; + SUIT_OverrideCursor wc; + + SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if( aSel ) + aSel->selectedObjects( selected ); + + SALOME_ListIteratorOfListIO It(selected); + for (int i = 0; It.More(); It.Next(), i++) { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); + } + SALOME_ListIO l1; + aSel->setSelectedObjects( l1 ); + updateObjBrowser(); + break; + } + + case 401: // GEOM::EDGE + case 4021: // TRIANGLE + case 4022: // QUAD + case 4023: // POLYGON + case 4031: // TETRA + case 4032: // HEXA + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + SMDSAbs_ElementType type = SMDSAbs_Edge; + int nbNodes = 2; + switch (theCommandID) { + case 4021: // TRIANGLE + type = SMDSAbs_Face; nbNodes = 3; break; + case 4022: // QUAD + type = SMDSAbs_Face; nbNodes = 4; break; + case 4031: // TETRA + type = SMDSAbs_Volume; nbNodes = 4; break; + case 4023: // POLYGON + type = SMDSAbs_Face; nbNodes = 5; break; // 5 - identificator for POLYGON + case 4032: // HEXA + type = SMDSAbs_Volume; nbNodes = 8; break; + case 4033: // POLYHEDRE + type = SMDSAbs_Volume; nbNodes = 9; break; // 9 - identificator for POLYHEDRE + default:; + } + new SMESHGUI_AddMeshElementDlg( this, "", type, nbNodes); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4033: // POLYHEDRON + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_CreatePolyhedralVolumeDlg(this, "", FALSE ); + } + else { + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4041: // REMOVES NODES + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RemoveNodesDlg(this); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4042: // REMOVES ELEMENTS + { + if(checkLock(aStudy)) break; + if( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RemoveElementsDlg(this); + } + else + { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4051: // RENUMBERING NODES + { + if(checkLock(aStudy)) break; + if( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RenumberingDlg( this, "", 0); + } + else + { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4052: // RENUMBERING ELEMENTS + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RenumberingDlg( this, "", 1); + } + else + { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4061: // TRANSLATION + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_TranslationDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4062: // ROTATION + { + if(checkLock(aStudy)) break; + if( vtkwnd ) { + EmitSignalDeactivateDialog(); + new SMESHGUI_RotationDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4063: // SYMMETRY + { + if(checkLock(aStudy)) break; + if(vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_SymmetryDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4064: // SEWING + { + if(checkLock(aStudy)) break; + if(vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_SewingDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4065: // MERGE NODES + { + if(checkLock(aStudy)) break; + if(vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_MergeNodesDlg( this ); + } + else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4066: // MERGE EQUAL ELEMENTS + { + if (checkLock(aStudy)) break; + if (vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_EditMeshDlg(this, + "SMESH_MERGE_ELEMENTS_TITLE", + "ICON_DLG_MERGE_ELEMENTS", + 1); // MergeEqualElemets + } else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 5105: // Library of selection filters + { + static QValueList aTypes; + if ( aTypes.isEmpty() ) + { + aTypes.append( SMESH::NODE ); + aTypes.append( SMESH::EDGE ); + aTypes.append( SMESH::FACE ); + aTypes.append( SMESH::VOLUME ); + } + new SMESHGUI_FilterLibraryDlg( this, SMESH::GetDesktop( this ), aTypes, SMESHGUI_FilterLibraryDlg::EDIT ); + } + break; + + case 6017: // CONTROLS + case 6016: + case 6015: + case 6014: + case 6013: + case 6012: + case 6011: + case 6001: + case 6018: + case 6019: + case 6002: + case 6003: + case 6004: + if ( vtkwnd ) { + + SalomeApp_SelectionMgr* mgr = selectionMgr(); + SALOME_ListIO selected; mgr->selectedObjects( selected ); + + if ( selected.Extent() == 1 && selected.First()->hasEntry() ) { + _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() ); + if ( SO ) { + CORBA::Object_var aObject = SMESH::SObjectToObject( SO ); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( aObject ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( aObject ); + if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) { + ::Control( theCommandID ); + break; + } + } + } + SUIT_MessageBox::warn1(desktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_BAD_SELECTION" ), + tr( "SMESH_BUT_OK" ) ); + break; + } + else { + SUIT_MessageBox::warn1(desktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ), + tr( "SMESH_BUT_OK" ) ); + } + break; + case 9010: + { + SalomeApp_SelectionMgr* mgr = selectionMgr(); + SALOME_ListIO selected; mgr->selectedObjects( selected ); + + if (selected.Extent() == 1) { + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + if(anIObject->hasEntry()) + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetPointsLabeled( !anActor->GetPointsLabeled() ); + } + } + break; + } + case 9011: + { + SalomeApp_SelectionMgr* mgr = selectionMgr(); + SALOME_ListIO selected; mgr->selectedObjects( selected ); + + if (selected.Extent() == 1) { + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + if(anIObject->hasEntry()) + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetCellsLabeled( !anActor->GetCellsLabeled() ); + } + } + break; + } + } + + anApp->updateActions(); //SRN: To update a Save button in the toolbar + //updateObjBrowser(); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::OnMousePress( QMouseEvent * pe, SUIT_ViewWindow * wnd ) +{ + return false; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::OnMouseMove( QMouseEvent * pe, SUIT_ViewWindow * wnd ) +{ + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::OnKeyPress( QKeyEvent * pe, SUIT_ViewWindow * wnd ) +{ + return true; +} + +//============================================================================= +/*! Method: BuildPresentation(const Handle(SALOME_InteractiveObject)& theIO) + * Purpose: ensures that the actor for the given exists in the active VTK view + */ +//============================================================================= +void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO, + SUIT_ViewWindow* wnd ) +{ + if(theIO->hasEntry()){ + //SUIT_ViewWindow* wnd = SMESH::GetActiveWindow(); + SMESH::UpdateView(wnd,SMESH::eDisplay,theIO->getEntry()); + } +} + +//======================================================================= +// function : createSMESHAction +// purpose : +//======================================================================= +void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle ) +{ + QIconSet icon; + QWidget* parent = application()->desktop(); + SUIT_ResourceMgr* resMgr = resourceMgr(); + QPixmap pix; + if ( icon_id.length() ) + pix = resMgr->loadPixmap( "SMESH", tr( icon_id ) ); + else + pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICO_" )+po_id ), false ); + if ( !pix.isNull() ) + icon = QIconSet( pix ); + + QString tooltip = tr( QString( "TOP_" )+po_id ), + menu = tr( QString( "MEN_" )+po_id ), + status_bar = tr( QString( "STB_" )+po_id ); + + createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() ) ); +} + +//======================================================================= +// function : createPopupItem +// purpose : +//======================================================================= +void SMESHGUI::createPopupItem( const int id, + const QString& clients, + const QString& types, + const QString& theRule, + const int pId ) +{ + int parentId = pId; + if( pId!=-1 ) + parentId = popupMgr()->actionId( action( pId ) ); + + if( !popupMgr()->contains( popupMgr()->actionId( action( id ) ) ) ) + popupMgr()->insert( action( id ), parentId, 0 ); + + QChar lc = QtxPopupMgr::Selection::defEquality(); + QString rule = "(%1) and (%2) and (%3)"; + rule = rule.arg( QString( "%1>0" ).arg( QtxPopupMgr::Selection::defSelCountParam() ) ); + rule = rule.arg( QString( "%1client in {%2}" ).arg( lc ).arg( clients ) ); + rule = rule.arg( QString( "%1type in {%2}" ).arg( lc ).arg( types ) ); + rule += theRule; + + bool cont = myRules.contains( id ); + if( cont ) + rule = QString( "%1 or (%2)" ).arg( myRules[ id ] ).arg( rule ); + + popupMgr()->setRule( action( id ), rule, true ); + myRules[ id ] = QString( cont ? "%1" : "(%1)" ).arg( rule ); +} + +//======================================================================= +// function : initialize +// purpose : +//======================================================================= +void SMESHGUI::initialize( CAM_Application* app ) +{ + SalomeApp_Module::initialize( app ); + +// SUIT_ResourceMgr* mgr = app->resourceMgr(); +// if ( mgr ) + /* Automatic Update flag */ +// myAutomaticUpdate = mgr->booleanValue( "SMESH", "AutomaticUpdate", myAutomaticUpdate ); + + // ----- create actions -------------- + + createSMESHAction( 111, "DAT", "", (CTRL+Key_B) ); + createSMESHAction( 112, "UNV", "", (CTRL+Key_U) ); + createSMESHAction( 113, "MED", "", (CTRL+Key_M) ); + createSMESHAction( 114, "NUM" ); + createSMESHAction( 121, "DAT" ); + createSMESHAction( 122, "MED" ); + createSMESHAction( 123, "UNV" ); + createSMESHAction( 124, "EXPORT_DAT" ); + createSMESHAction( 125, "EXPORT_MED" ); + createSMESHAction( 126, "EXPORT_UNV" ); + createSMESHAction( 33, "DELETE", "ICON_DELETE" ); + createSMESHAction( 5105, "SEL_FILTER_LIB" ); + createSMESHAction( 701, "COMPUTE", "ICON_COMPUTE" ); + createSMESHAction( 702, "CREATE_MESH", "ICON_DLG_INIT_MESH" ); + createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" ); + createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" ); + createSMESHAction( 801, "CREATE_GROUP", "ICON_SMESH_TREE_GROUP" ); + createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" ); + createSMESHAction( 803, "EDIT_GROUP", "ICON_EDIT_GROUP" ); + createSMESHAction( 804, "ADD" ); + createSMESHAction( 805, "REMOVE" ); + createSMESHAction( 810, "UN_GROUP", "ICON_UNION" ); + createSMESHAction( 811, "INT_GROUP", "ICON_INTERSECT" ); + createSMESHAction( 812, "CUT_GROUP", "ICON_CUT" ); + createSMESHAction( 813, "DEL_GROUP", "ICON_DEL_GROUP" ); + createSMESHAction( 900, "ADV_INFO", "ICON_ADV_INFO" ); + createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" ); + createSMESHAction( 6001, "LENGTH", "ICON_LENGTH" , 0, true ); + createSMESHAction( 6002, "FREE_EDGE", "ICON_FREE_EDGE" , 0, true ); + createSMESHAction( 6003, "FREE_BORDER", "ICON_FREE_EDGE_2D" , 0, true ); + createSMESHAction( 6004, "CONNECTION", "ICON_CONNECTION" , 0, true ); + createSMESHAction( 6011, "AREA", "ICON_AREA" , 0, true ); + createSMESHAction( 6012, "TAPER", "ICON_TAPER" , 0, true ); + createSMESHAction( 6013, "ASPECT", "ICON_ASPECT" , 0, true ); + createSMESHAction( 6014, "MIN_ANG", "ICON_ANGLE" , 0, true ); + createSMESHAction( 6015, "WARP", "ICON_WARP" , 0, true ); + createSMESHAction( 6016, "SKEW", "ICON_SKEW", 0, true ); + createSMESHAction( 6017, "ASPECT_3D", "ICON_ASPECT_3D", 0, true ); + createSMESHAction( 6018, "LENGTH_2D", "ICON_LENGTH_2D", 0, true ); + createSMESHAction( 6019, "CONNECTION_2D", "ICON_CONNECTION_2D", 0, true ); + createSMESHAction( 400, "NODE", "ICON_DLG_NODE" ); + createSMESHAction( 401, "EDGE", "ICON_DLG_EDGE" ); + createSMESHAction( 4021, "TRIANGLE", "ICON_DLG_TRIANGLE" ); + createSMESHAction( 4022, "QUAD", "ICON_DLG_QUADRANGLE" ); + createSMESHAction( 4023, "POLYGON", "ICON_DLG_POLYGON" ); + createSMESHAction( 4031, "TETRA", "ICON_DLG_TETRAS" ); + createSMESHAction( 4032, "HEXA", "ICON_DLG_HEXAS" ); + createSMESHAction( 4041, "REMOVE_NODES", "ICON_DLG_REM_NODE" ); + createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" ); + createSMESHAction( 4051, "RENUM_NODES", "ICON_DLG_RENUMBERING_NODES" ); + createSMESHAction( 4052, "RENUM_ELEMENTS", "ICON_DLG_RENUMBERING_ELEMENTS" ); + createSMESHAction( 4061, "TRANS", "ICON_SMESH_TRANSLATION_VECTOR" ); + createSMESHAction( 4062, "ROT", "ICON_DLG_ROTATION" ); + createSMESHAction( 4063, "SYM", "ICON_SMESH_SYMMETRY_PLANE" ); + createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" ); + createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" ); + createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" ); + createSMESHAction( 406, "MOVE", "ICON_DLG_MOVE_NODE" ); + createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" ); + createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" ); + createSMESHAction( 409, "ORIENT", "ICON_DLG_MESH_ORIENTATION" ); + createSMESHAction( 410, "UNION", "ICON_UNIONTRI" ); + createSMESHAction( 411, "CUT", "ICON_CUTQUAD" ); + createSMESHAction( 412, "SMOOTH", "ICON_DLG_SMOOTHING" ); + createSMESHAction( 413, "EXTRUSION", "ICON_EXTRUSION" ); + createSMESHAction( 414, "REVOLUTION", "ICON_REVOLUTION" ); + createSMESHAction( 415, "MAP", "ICON_MAP" ); + createSMESHAction( 416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" ); + createSMESHAction( 200, "RESET" ); + createSMESHAction( 201, "SCALAR_BAR_PROP" ); + createSMESHAction( 211, "WIRE", "ICON_WIRE", 0, true ); + createSMESHAction( 212, "SHADE", "ICON_SHADE", 0, true ); + createSMESHAction( 213, "SHRINK", "ICON_SHRINK", 0, true ); + createSMESHAction( 214, "UPDATE", "ICON_UPDATE" ); + createSMESHAction( 215, "NODES", "ICON_POINTS", 0, true ); + createSMESHAction( 217, "EDGES", "ICON_DLG_EDGE", 0, true ); + createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true ); + createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true ); + createSMESHAction( 220, "ALL" ); + createSMESHAction( 1100, "EDIT_HYPO" ); + createSMESHAction( 1101, "RENAME" ); + createSMESHAction( 1102, "UNASSIGN" ); + createSMESHAction( 9010, "NUM_NODES", "", 0, true ); + createSMESHAction( 9011, "NUM_ELEMENTS", "", 0, true ); + createSMESHAction( 1131, "DISPMODE" ); + createSMESHAction( 1132, "COLORS" ); + createSMESHAction( 1133, "TRANSP" ); + createSMESHAction( 1134, "CLIP" ); + createSMESHAction( 1135, "DISP_ENT" ); + createSMESHAction( 2000, "CTRL" ); + + createSMESHAction( 300, "ERASE" ); + createSMESHAction( 301, "DISPLAY" ); + createSMESHAction( 302, "DISPLAY_ONLY" ); + createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" ); + + // ----- create menu -------------- + int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), + editId = createMenu( tr( "MEN_EDIT" ), -1, 3 ), + toolsId = createMenu( tr( "MEN_TOOLS" ), -1, 5, 50 ), + meshId = createMenu( tr( "MEN_MESH" ), -1, 70, 10 ), + ctrlId = createMenu( tr( "MEN_CTRL" ), -1, 60, 10 ), + modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ), + viewId = createMenu( tr( "MEN_VIEW" ), -1, 2 ); + + createMenu( separator(), fileId ); + + int importId = createMenu( tr( "MEN_IMPORT" ), fileId, 11, 10 ), + exportId = createMenu( tr( "MEN_EXPORT" ), fileId, 12, 10 ), + addId = createMenu( tr( "MEN_ADD" ), modifyId, 402 ), + removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ), + renumId = createMenu( tr( "MEN_RENUM" ), modifyId, 404 ), + transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 ); + + createMenu( 111, importId, -1 ); + createMenu( 112, importId, -1 ); + createMenu( 113, importId, -1 ); + + createMenu( 121, exportId, -1 ); + createMenu( 122, exportId, -1 ); + createMenu( 123, exportId, -1 ); + + createMenu( separator(), fileId, 10 ); + + createMenu( 33, editId, -1 ); + + createMenu( 5105, toolsId, -1 ); + + createMenu( 702, meshId, -1 ); + createMenu( 703, meshId, -1 ); + createMenu( 704, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + createMenu( 701, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + createMenu( 801, meshId, -1 ); + createMenu( 802, meshId, -1 ); + createMenu( 803, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + createMenu( 810, meshId, -1 ); + createMenu( 811, meshId, -1 ); + createMenu( 812, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + createMenu( 813, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + createMenu( 900, meshId, -1 ); + createMenu( 902, meshId, -1 ); + createMenu( separator(), meshId, -1 ); + + createMenu( 6003, ctrlId, -1 ); + createMenu( 6001, ctrlId, -1 ); + createMenu( 6004, ctrlId, -1 ); + createMenu( separator(), ctrlId, -1 ); + createMenu( 6002, ctrlId, -1 ); + createMenu( 6018, ctrlId, -1 ); + createMenu( 6019, ctrlId, -1 ); + createMenu( 6011, ctrlId, -1 ); + createMenu( 6012, ctrlId, -1 ); + createMenu( 6013, ctrlId, -1 ); + createMenu( 6014, ctrlId, -1 ); + createMenu( 6015, ctrlId, -1 ); + createMenu( 6016, ctrlId, -1 ); + createMenu( separator(), ctrlId, -1 ); + createMenu( 6017, ctrlId, -1 ); + createMenu( separator(), ctrlId, -1 ); + + createMenu( 400, addId, -1 ); + createMenu( 401, addId, -1 ); + createMenu( 4021, addId, -1 ); + createMenu( 4022, addId, -1 ); + createMenu( 4023, addId, -1 ); + createMenu( 4031, addId, -1 ); + createMenu( 4032, addId, -1 ); + createMenu( 4033, addId, -1 ); + + createMenu( 4041, removeId, -1 ); + createMenu( 4042, removeId, -1 ); + + createMenu( 4051, renumId, -1 ); + createMenu( 4052, renumId, -1 ); + + createMenu( 4061, transfId, -1 ); + createMenu( 4062, transfId, -1 ); + createMenu( 4063, transfId, -1 ); + createMenu( 4064, transfId, -1 ); + createMenu( 4065, transfId, -1 ); + createMenu( 4066, transfId, -1 ); + + createMenu( 406, modifyId, -1 ); + createMenu( 407, modifyId, -1 ); + createMenu( 408, modifyId, -1 ); + createMenu( 409, modifyId, -1 ); + createMenu( 410, modifyId, -1 ); + createMenu( 411, modifyId, -1 ); + createMenu( 412, modifyId, -1 ); + createMenu( 413, modifyId, -1 ); + createMenu( 416, modifyId, -1 ); + createMenu( 414, modifyId, -1 ); + createMenu( 415, modifyId, -1 ); + + createMenu( 214, viewId, -1 ); + + // ----- create toolbars -------------- + int meshTb = createTool( tr( "TB_MESH" ) ), + ctrlTb = createTool( tr( "TB_CTRL" ) ), + addRemTb = createTool( tr( "TB_ADD_REMOVE" ) ), + modifyTb = createTool( tr( "TB_MODIFY" ) ), + dispModeTb = createTool( tr( "TB_DISP_MODE" ) ); + + createTool( 702, meshTb ); + createTool( 703, meshTb ); + createTool( 704, meshTb ); + createTool( separator(), meshTb ); + createTool( 701, meshTb ); + createTool( separator(), meshTb ); + createTool( 801, meshTb ); + createTool( 802, meshTb ); + createTool( 803, meshTb ); + createTool( separator(), meshTb ); + createTool( 900, meshTb ); + createTool( 902, meshTb ); + createTool( separator(), meshTb ); + + createTool( 6001, ctrlTb ); + createTool( 6003, ctrlTb ); + createTool( 6004, ctrlTb ); + createTool( separator(), ctrlTb ); + createTool( 6002, ctrlTb ); + createTool( 6018, ctrlTb ); + createTool( 6019, ctrlTb ); + createTool( 6011, ctrlTb ); + createTool( 6012, ctrlTb ); + createTool( 6013, ctrlTb ); + createTool( 6014, ctrlTb ); + createTool( 6015, ctrlTb ); + createTool( 6016, ctrlTb ); + createTool( separator(), ctrlTb ); + createTool( 6017, ctrlTb ); + createTool( separator(), ctrlTb ); + + createTool( 400, addRemTb ); + createTool( 401, addRemTb ); + createTool( 4021, addRemTb ); + createTool( 4022, addRemTb ); + createTool( 4023, addRemTb ); + createTool( 4031, addRemTb ); + createTool( 4032, addRemTb ); + createTool( 4033, addRemTb ); + createTool( separator(), addRemTb ); + createTool( 4041, addRemTb ); + createTool( 4042, addRemTb ); + createTool( separator(), addRemTb ); + createTool( 4051, addRemTb ); + createTool( 4052, addRemTb ); + createTool( separator(), addRemTb ); + createTool( 4061, addRemTb ); + createTool( 4062, addRemTb ); + createTool( 4063, addRemTb ); + createTool( 4064, addRemTb ); + createTool( 4065, addRemTb ); + createTool( 4066, addRemTb ); + createTool( separator(), addRemTb ); + + createTool( 406, modifyTb ); + createTool( 407, modifyTb ); + createTool( 408, modifyTb ); + createTool( 409, modifyTb ); + createTool( 410, modifyTb ); + createTool( 411, modifyTb ); + createTool( 412, modifyTb ); + createTool( 413, modifyTb ); + createTool( 416, modifyTb ); + createTool( 414, modifyTb ); + createTool( 415, modifyTb ); + + createTool( 214, dispModeTb ); + + + myRules.clear(); + QString OB = "'ObjectBrowser'", + View = "'" + SVTK_Viewer::Type() + "'", + pat = "'%1'", + mesh = pat.arg( SMESHGUI_Selection::typeName( MESH ) ), + group = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ), + hypo = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ), + algo = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ), + elems = QString( "'%1' '%2' '%3' '%4' '%5'" ). + arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ), + subMesh = elems, + mesh_group = mesh + " " + subMesh + " " + group, + hyp_alg = hypo + " " + algo; + + // popup for object browser + + createPopupItem( 704, OB, mesh, "&& isComputable"); // EDIT_MESHSUBMESH + createPopupItem( 704, OB, subMesh, "&& isComputable" ); // EDIT_MESHSUBMESH + createPopupItem( 803, OB, group ); // EDIT_GROUP + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE + createPopupItem( 214, OB, mesh_group ); // UPDATE + createPopupItem( 900, OB, mesh_group ); // ADV_INFO + createPopupItem( 902, OB, mesh ); // STD_INFO + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 801, OB, mesh ); // CREATE_GROUP + createPopupItem( 802, OB, subMesh ); // CONSTRUCT_GROUP + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 1100, OB, hypo, "&& $hasReference={false}" ); // EDIT HYPOTHESIS + createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS + createPopupItem( 1101, OB, mesh_group + " " + hyp_alg, "&& $hasReference={false}" ); // RENAME + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 125, OB, mesh ); // EXPORT_MED + createPopupItem( 126, OB, mesh ); // EXPORT_UNV + createPopupItem( 33, OB, subMesh + " " + group ); // DELETE + popupMgr()->insert( separator(), -1, 0 ); + + // popup for viewer + createPopupItem( 803, View, group ); // EDIT_GROUP + createPopupItem( 804, View, elems ); // ADD + createPopupItem( 805, View, elems ); // REMOVE + popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 214, View, mesh_group ); // UPDATE + createPopupItem( 900, View, mesh_group ); // ADV_INFO + createPopupItem( 902, View, mesh ); // STD_INFO + popupMgr()->insert( separator(), -1, 0 ); + + int anId; + QString + isInvisible("not( isVisible )"), + isEmpty("numberOfNodes = 0"), + isNotEmpty("numberOfNodes <> 0"), + + // has nodes, edges, etc in VISIBLE! actor + hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"), + hasElems("(count( elemTypes ) > 0)"), + hasDifferentElems("(count( elemTypes ) > 1)"), + hasEdges("({'Edge'} in elemTypes)"), + hasFaces("({'Face'} in elemTypes)"), + hasVolumes("({'Volume'} in elemTypes)"); + + QString lc = QtxPopupMgr::Selection::defEquality(); + QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" ); + QString aType = QString( "%1type in {%2}" ).arg( QtxPopupMgr::Selection::defEquality() ).arg( mesh_group ); + QString aMeshInVTK = aClient + "&&" + aType; + + //------------------------------------------------- + // Numbering + //------------------------------------------------- + anId = popupMgr()->insert( tr( "MEN_NUM" ), -1, -1 ); + + popupMgr()->insert( action( 9010 ), anId, -1 ); + popupMgr()->setRule( action( 9010 ), aMeshInVTK + "&& isVisible &&" + hasNodes, true ); + popupMgr()->setRule( action( 9010 ), "{'Point'} in labeledTypes", false ); + + popupMgr()->insert( action( 9011 ), anId, -1 ); + popupMgr()->setRule( action( 9011 ), aMeshInVTK + "&& isVisible &&" + hasElems, true ); + popupMgr()->setRule( action( 9011 ), "{'Cell'} in labeledTypes", false ); + + popupMgr()->insert( separator(), -1, -1 ); + + //------------------------------------------------- + // Display Mode + //------------------------------------------------- + anId = popupMgr()->insert( tr( "MEN_DISPMODE" ), -1, -1 ); + + popupMgr()->insert( action( 211 ), anId, -1 ); // WIRE + popupMgr()->setRule( action( 211 ), aMeshInVTK + "&&" + hasElems, true ); + popupMgr()->setRule( action( 211 ), "displayMode = 'eEdge'", false ); + + popupMgr()->insert( action( 212 ), anId, -1 ); // SHADE + popupMgr()->setRule( action( 212 ),aMeshInVTK+ "&& (" + hasFaces + "||" + hasVolumes + ")",true); + popupMgr()->setRule( action( 212 ), "displayMode = 'eSurface'", false ); + + popupMgr()->insert( action( 215 ), anId, -1 ); // POINTS + popupMgr()->setRule( action( 215 ), aMeshInVTK + "&&" + hasNodes, true ); + popupMgr()->setRule( action( 215 ), "displayMode = 'ePoint'", false ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 213 ), anId, -1 ); // SHRINK + popupMgr()->setRule( action( 213 ), aMeshInVTK + "&& shrinkMode <> 'IsNotShrinkable' && displayMode <> 'ePoint'",true); + popupMgr()->setRule( action( 213 ), "shrinkMode = 'IsShrunk'", false ); + + //------------------------------------------------- + // Display Entity + //------------------------------------------------- + QString aDiffElemsInVTK = aMeshInVTK + "&&" + hasDifferentElems; + + anId = popupMgr()->insert( tr( "MEN_DISP_ENT" ), -1, -1 ); + + popupMgr()->insert( action( 217 ), anId, -1 ); // EDGES + popupMgr()->setRule( action( 217 ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, true ); + popupMgr()->setRule( action( 217 ), "{'Edge'} in entityMode", false ); + + popupMgr()->insert( action( 218 ), anId, -1 ); // FACES + popupMgr()->setRule( action( 218 ), aDiffElemsInVTK + "&& isVisible &&" + hasFaces, true ); + popupMgr()->setRule( action( 218 ), "{'Face'} in entityMode", false ); + + popupMgr()->insert( action( 219 ), anId, -1 ); // VOLUMES + popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, true ); + popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", false ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 220 ), anId, -1 ); // ALL + popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", true ); + + //------------------------------------------------- + // Color / Size + //------------------------------------------------- + popupMgr()->insert( action( 1132 ), -1, -1 ); + popupMgr()->setRule( action( 1132 ), aMeshInVTK + "&& isVisible", true ); + + //------------------------------------------------- + // Transparency + //------------------------------------------------- + popupMgr()->insert( action( 1133 ), -1, -1 ); + popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", true ); + + //------------------------------------------------- + // Clipping + //------------------------------------------------- + popupMgr()->insert( action( 1134 ), -1, -1 ); + popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& isVisible", true ); + + popupMgr()->insert( separator(), -1, -1 ); + + //------------------------------------------------- + // Controls + //------------------------------------------------- + QString + aMeshInVtkHasEdges = aMeshInVTK + "&&" + hasEdges, + aMeshInVtkHasFaces = aMeshInVTK + "&&" + hasFaces, + aMeshInVtkHasVolumes = aMeshInVTK + "&&" + hasVolumes; + + anId = popupMgr()->insert( tr( "MEN_CTRL" ), -1, -1 ); + + popupMgr()->insert( action( 200 ), anId, -1 ); // RESET + popupMgr()->setRule( action( 200 ), aMeshInVTK + "&& controlMode <> 'eNone'", true ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER + popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, true ); + popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeEdges'", false ); + + popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH + popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, true ); + popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", false ); + + popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION + popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, true ); + popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", false ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE + popupMgr()->setRule( action( 6002 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeBorders'", false ); + + popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D + popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", false ); + + popupMgr()->insert( action( 6019 ), anId, -1 ); // CONNECTION_2D + popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", false ); + + popupMgr()->insert( action( 6011 ), anId, -1 ); // AREA + popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", false ); + + popupMgr()->insert( action( 6012 ), anId, -1 ); // TAPER + popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", false ); + + popupMgr()->insert( action( 6013 ), anId, -1 ); // ASPECT + popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", false ); + + popupMgr()->insert( action( 6014 ), anId, -1 ); // MIN_ANG + popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", false ); + + popupMgr()->insert( action( 6015 ), anId, -1 ); // WARP + popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", false ); + + popupMgr()->insert( action( 6016 ), anId, -1 ); // SKEW + popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, true ); + popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", false ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 6017 ), anId, -1 ); // ASPECT_3D + popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, true ); + popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", false ); + + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP + popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", true ); + + popupMgr()->insert( separator(), -1, -1 ); + + //------------------------------------------------- + // Display / Erase + //------------------------------------------------- + aClient = "($client in {'VTKViewer' 'ObjectBrowser'})"; + QString anActiveVTK = QString("activeView = '%1'").arg(VTKViewer_Viewer::Type()); + QString aSelCount = QString( "%1 > 0" ).arg( QtxPopupMgr::Selection::defSelCountParam() ); + QString aRule = aClient + " and " + aType + " and " + aSelCount + " and " + anActiveVTK; + popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY + popupMgr()->setRule( action( 301 ), aRule + "&&" + isNotEmpty + "&&" + isInvisible, true); + + popupMgr()->insert( action( 300 ), -1, -1 ); // ERASE + popupMgr()->setRule( action( 300 ), aRule + "&&" + isNotEmpty + "&& isVisible", true ); + + popupMgr()->insert( action( 302 ), -1, -1 ); // DISPLAY_ONLY + popupMgr()->setRule( action( 302 ), aRule + "&&" + isNotEmpty, true ); + + popupMgr()->insert( separator(), -1, -1 ); + + connect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ), + this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) ); +} + +bool SMESHGUI::activateModule( SUIT_Study* study ) +{ + bool res = SalomeApp_Module::activateModule( study ); + + setMenuShown( true ); + setToolShown( true ); + + return res; +} + +bool SMESHGUI::deactivateModule( SUIT_Study* study ) +{ + setMenuShown( false ); + setToolShown( false ); + + EmitSignalCloseAllDialogs(); + + return SalomeApp_Module::deactivateModule( study ); +} + +void SMESHGUI::OnGUIEvent() +{ + const QObject* obj = sender(); + if ( !obj || !obj->inherits( "QAction" ) ) + return; + int id = actionId((QAction*)obj); + if ( id != -1 ) + OnGUIEvent( id ); +} + +SMESH::SMESH_Gen_var SMESHGUI::GetSMESHGen() +{ + if ( CORBA::is_nil( myComponentSMESH ) ) + { + SMESHGUI aGUI; //SRN BugID: IPAL9186: Create an instance of SMESHGUI to initialize myComponentSMESH + return aGUI.myComponentSMESH; + } + return myComponentSMESH; +} + +QString SMESHGUI::engineIOR() const +{ + CORBA::ORB_var anORB = getApp()->orb(); + CORBA::String_var anIOR = anORB->object_to_string(GetSMESHGen()); + return anIOR.in(); +} + +void SMESHGUI::contextMenuPopup( const QString& client, QPopupMenu* menu, QString& /*title*/ ) +{ + SMESHGUI_Selection sel; + sel.init( client, selectionMgr() ); + popupMgr()->updatePopup( menu, &sel ); +} + +void SMESHGUI::windows( QMap& aMap ) const +{ + aMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft ); + aMap.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom ); +} + +void SMESHGUI::viewManagers( QStringList& list ) const +{ + list.append( SVTK_Viewer::Type() ); +} + +void SMESHGUI::onViewManagerAdded( SUIT_ViewManager* mgr ) +{ + if ( dynamic_cast( mgr ) ) + SMESH::UpdateSelectionProp( this ); +} + +void SMESHGUI::createPreferences() +{ + int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) ); + + int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab ); + addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, SalomeApp_Preferences::Bool, "SMESH", "auto_update" ); + + int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab ); + addPreference( tr( "PREF_DISPLAY_ENTITY" ), qaGroup, SalomeApp_Preferences::Bool, "SMESH", "display_entity" ); + addPreference( tr( "PREF_PRECISION_USE" ), qaGroup, SalomeApp_Preferences::Bool, "SMESH", "use_precision" ); + + int precGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), genTab ); + setPreferenceProperty( precGroup, "columns", 1 ); + + int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), precGroup, SalomeApp_Preferences::IntSpin, "SMESH", "controls_precision" ); + + setPreferenceProperty( prec, "min", 0 ); + setPreferenceProperty( prec, "max", 16 ); + + int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE" ), genTab ); + int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, SalomeApp_Preferences::Selector, "SMESH", "display_mode" ); + QStringList modes; + modes.append( "Wireframe" ); + modes.append( "Shading" ); + modes.append( "Nodes" ); + modes.append( "Shrink" ); + QValueList indices; + indices.append( 0 ); + indices.append( 1 ); + indices.append( 2 ); + indices.append( 3 ); + setPreferenceProperty( dispmode, "strings", modes ); + setPreferenceProperty( dispmode, "indexes", indices ); + + int meshTab = addPreference( tr( "PREF_TAB_MESH" ) ); + int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab ); + + addPreference( tr( "PREF_COLOR" ), nodeGroup, SalomeApp_Preferences::Color, "SMESH", "node_color" ); + int nodeSz = addPreference( tr( "PREF_SIZE" ), nodeGroup, SalomeApp_Preferences::IntSpin, "SMESH", "node_size" ); + + setPreferenceProperty( nodeSz, "min", 1 ); + setPreferenceProperty( nodeSz, "max", 5 ); + + int elemGroup = addPreference( tr( "PREF_GROUP_ELEMENTS" ), meshTab ); + + addPreference( tr( "PREF_FILL" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "fill_color" ); + addPreference( tr( "PREF_OUTLINE" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "outline_color" ); + addPreference( tr( "PREF_BACKFACE" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "backface_color" ); + addPreference( "", elemGroup, SalomeApp_Preferences::Space ); + + int elemW = addPreference( tr( "PREF_WIDTH" ), elemGroup, SalomeApp_Preferences::IntSpin, "SMESH", "element_width" ); + int shrink = addPreference( tr( "PREF_SHRINK_COEFF" ), elemGroup, SalomeApp_Preferences::IntSpin, "SMESH", "shrink_coeff" ); + + setPreferenceProperty( elemW, "min", 1 ); + setPreferenceProperty( elemW, "max", 5 ); + + setPreferenceProperty( shrink, "min", 0 ); + setPreferenceProperty( shrink, "max", 100 ); + + int selTab = addPreference( tr( "PREF_TAB_SELECTION" ) ); + + int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab ); + + addPreference( tr( "PREF_OBJECT_COLOR" ), selGroup, SalomeApp_Preferences::Color, "SMESH", "selection_object_color" ); + addPreference( tr( "PREF_ELEMENT_COLOR" ), selGroup, SalomeApp_Preferences::Color, "SMESH", "selection_element_color" ); + int selW = addPreference( tr( "PREF_WIDTH" ), selGroup, SalomeApp_Preferences::IntSpin, "SMESH", "selection_width" ); + + setPreferenceProperty( selW, "min", 1 ); + setPreferenceProperty( selW, "max", 5 ); + + int preGroup = addPreference( tr( "PREF_GROUP_PRESELECTION" ), selTab ); + + addPreference( tr( "PREF_HIGHLIGHT_COLOR" ), preGroup, SalomeApp_Preferences::Color, "SMESH", "highlight_color" ); + int preW = addPreference( tr( "PREF_WIDTH" ), preGroup, SalomeApp_Preferences::IntSpin, "SMESH", "highlight_width" ); + + setPreferenceProperty( preW, "min", 1 ); + setPreferenceProperty( preW, "max", 5 ); + + int precSelGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), selTab ); + + addPreference( tr( "PREF_NODES" ), precSelGroup, SalomeApp_Preferences::Double, "SMESH", "selection_precision_node" ); + addPreference( tr( "PREF_ELEMENTS" ), precSelGroup, SalomeApp_Preferences::Double, "SMESH", "selection_precision_element" ); + + int sbarTab = addPreference( tr( "SMESH_SCALARBAR" ) ); + int fontGr = addPreference( tr( "SMESH_FONT_SCALARBAR" ), sbarTab ); + + int tfont = addPreference( tr( "SMESH_TITLE" ), fontGr, SalomeApp_Preferences::Font, "SMESH", "scalar_bar_title_font" ); + addPreference( tr( "SMESH_TITLE" ), fontGr, SalomeApp_Preferences::Color, "SMESH", "scalar_bar_title_color" ); + int lfont = addPreference( tr( "SMESH_LABELS" ), fontGr, SalomeApp_Preferences::Font, "SMESH", "scalar_bar_label_font" ); + addPreference( tr( "SMESH_LABELS" ), fontGr, SalomeApp_Preferences::Color, "SMESH", "scalar_bar_label_color" ); + + QStringList fam; + fam.append( tr( "SMESH_FONT_ARIAL" ) ); + fam.append( tr( "SMESH_FONT_COURIER" ) ); + fam.append( tr( "SMESH_FONT_TIMES" ) ); + int wflag = ( QtxListResourceEdit::FontItem::All & ( ~( QtxListResourceEdit::FontItem::Size | QtxListResourceEdit::FontItem::UserSize ) ) ); + + setPreferenceProperty( tfont, "families", fam ); + setPreferenceProperty( tfont, "system", false ); + setPreferenceProperty( tfont, "widget_flags", wflag ); + setPreferenceProperty( lfont, "families", fam ); + setPreferenceProperty( lfont, "system", false ); + setPreferenceProperty( lfont, "widget_flags", wflag ); + + int colorsLabelsGr = addPreference( tr( "SMESH_LABELS_COLORS_SCALARBAR" ), sbarTab ); + + int numcol = addPreference( tr( "SMESH_NUMBEROFCOLORS" ), colorsLabelsGr, SalomeApp_Preferences::IntSpin, "SMESH", "scalar_bar_num_colors" ); + setPreferenceProperty( numcol, "min", 2 ); + setPreferenceProperty( numcol, "max", 256 ); + + int numlab = addPreference( tr( "SMESH_NUMBEROFLABELS" ), colorsLabelsGr, SalomeApp_Preferences::IntSpin, "SMESH", "scalar_bar_num_labels" ); + setPreferenceProperty( numlab, "min", 2 ); + setPreferenceProperty( numlab, "max", 65 ); + + int orientGr = addPreference( tr( "SMESH_ORIENTATION" ), sbarTab ); + int orient = addPreference( tr( "SMESH_ORIENTATION" ), orientGr, SalomeApp_Preferences::Selector, "SMESH", "scalar_bar_orientation" ); + QStringList orients; + orients.append( tr( "SMESH_VERTICAL" ) ); + orients.append( tr( "SMESH_HORIZONTAL" ) ); + indices.clear(); indices.append( 0 ); indices.append( 1 ); + setPreferenceProperty( orient, "strings", orients ); + setPreferenceProperty( orient, "indexes", indices ); + + int posVSizeGr = addPreference( tr( "SMESH_POSITION_SIZE_SCALARBAR" ) + " " + tr( "SMESH_VERTICAL" ), sbarTab ); + int xv = addPreference( tr( "SMESH_X_SCALARBAR" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_x" ); + int yv = addPreference( tr( "SMESH_Y_SCALARBAR" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_y" ); + int wv = addPreference( tr( "SMESH_WIDTH" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_width" ); + int hv = addPreference( tr( "SMESH_HEIGHT" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_height" ); + setPreferenceProperty( xv, "step", 0.1 ); + setPreferenceProperty( xv, "min", 0.0 ); + setPreferenceProperty( xv, "max", 1.0 ); + setPreferenceProperty( yv, "step", 0.1 ); + setPreferenceProperty( yv, "min", 0.0 ); + setPreferenceProperty( yv, "max", 1.0 ); + setPreferenceProperty( wv, "step", 0.1 ); + setPreferenceProperty( wv, "min", 0.0 ); + setPreferenceProperty( wv, "max", 1.0 ); + setPreferenceProperty( hv, "min", 0.0 ); + setPreferenceProperty( hv, "max", 1.0 ); + setPreferenceProperty( hv, "step", 0.1 ); + + int posHSizeGr = addPreference( tr( "SMESH_POSITION_SIZE_SCALARBAR" ) + " " + tr( "SMESH_HORIZONTAL" ), sbarTab ); + int xh = addPreference( tr( "SMESH_X_SCALARBAR" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_x" ); + int yh = addPreference( tr( "SMESH_Y_SCALARBAR" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_y" ); + int wh = addPreference( tr( "SMESH_WIDTH" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_width" ); + int hh = addPreference( tr( "SMESH_HEIGHT" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_height" ); + setPreferenceProperty( xv, "min", 0.0 ); + setPreferenceProperty( xv, "max", 1.0 ); + setPreferenceProperty( xv, "step", 0.1 ); + setPreferenceProperty( xh, "min", 0.0 ); + setPreferenceProperty( xh, "max", 1.0 ); + setPreferenceProperty( xh, "step", 0.1 ); + setPreferenceProperty( yh, "min", 0.0 ); + setPreferenceProperty( yh, "max", 1.0 ); + setPreferenceProperty( yh, "step", 0.1 ); + setPreferenceProperty( wh, "min", 0.0 ); + setPreferenceProperty( wh, "max", 1.0 ); + setPreferenceProperty( wh, "step", 0.1 ); + setPreferenceProperty( hh, "min", 0.0 ); + setPreferenceProperty( hh, "max", 1.0 ); + setPreferenceProperty( hh, "step", 0.1 ); +} + +void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) +{ +} + +//================================================================================ +/*! + * \brief Update something in accordance with update flags + * \param theFlags - update flags +* +* Update viewer or/and object browser etc. in accordance with update flags ( see +* SalomeApp_UpdateFlags enumeration ). +*/ +//================================================================================ +void SMESHGUI::update( const int flags ) +{ + if ( flags & UF_Viewer | flags & UF_Forced ) + SMESH::UpdateView(); + else + SalomeApp_Module::update( flags ); +} + +//================================================================================ +/*! + * \brief Set default selection mode +* +* SLOT called when operation commited. Sets default selection mode +*/ +//================================================================================ +void SMESHGUI::onOperationCommited( SUIT_Operation* ) +{ + SVTK_ViewWindow* vtkWnd = + dynamic_cast( application()->desktop()->activeWindow() ); + if ( vtkWnd ) + vtkWnd->SetSelectionMode( ActorSelection ); +} + +//================================================================================ +/*! + * \brief Set default selection mode +* +* SLOT called when operation aborted. Sets default selection mode +*/ +//================================================================================ +void SMESHGUI::onOperationAborted( SUIT_Operation* ) +{ + SVTK_ViewWindow* vtkWnd = + dynamic_cast( application()->desktop()->activeWindow() ); + if ( vtkWnd ) + vtkWnd->SetSelectionMode( ActorSelection ); +} + +//================================================================================ +/*! + * \brief Creates operation with given identifier + * \param id - identifier of operation to be started + * \return Pointer on created operation or NULL if operation is not created +* +* Virtual method redefined from the base class creates operation with given id. +* It is called called automatically from startOperation method of base class. +*/ +//================================================================================ +SalomeApp_Operation* SMESHGUI::createOperation( const int id ) const +{ + SalomeApp_Operation* op = 0; + // to do : create operation here + switch( id ) + { + case 702: // Create mesh + op = new SMESHGUI_MeshOp( true, true ); + break; + case 703: // Create sub-mesh + op = new SMESHGUI_MeshOp( true, false ); + break; + case 704: // Edit mesh/sub-mesh + op = new SMESHGUI_MeshOp( false ); + break; + default: + break; + } + + return op; +} + + + + + + + + diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx new file mode 100644 index 000000000..c2d0185b6 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx @@ -0,0 +1,963 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_EditHypothesesDlg.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#include "SMESHGUI_EditHypothesesDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_HypothesesUtils.h" + +#include "SMESH_TypeFilter.hxx" +#include "SMESH_NumberFilter.hxx" + +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "SALOMEDSClient_Study.hxx" +#include "SALOMEDSClient_AttributeIOR.hxx" +#include "SALOMEDSClient_AttributeName.hxx" + +#include "SUIT_Session.h" +#include "SUIT_OverrideCursor.h" +#include "SUIT_Operation.h" +#include "SUIT_Desktop.h" + +#include "utilities.h" + +#include "SVTK_ViewModel.h" + +// QT Includes +#include +#include +#include +#include +#include +#include + +using namespace std; + +//VRV: porting on Qt 3.0.5 +#if QT_VERSION >= 0x030005 +#include +#endif +//VRV: porting on Qt 3.0.5 + +class ListBoxIOR : public QListBoxText +{ +public: + enum { RTTI_IOR = 1000 }; + +public: + ListBoxIOR (QListBox* listbox, + const char* ior, + const QString& text = QString::null) + : QListBoxText(listbox, text), myIOR(ior) {} + virtual ~ListBoxIOR() {}; + virtual int rtti() const { return RTTI_IOR; } + const char* GetIOR() { return myIOR.c_str(); } + +private: + string myIOR; +}; + +#define ALLOW_CHANGE_SHAPE 0 + +int findItem (QListBox* listBox, const string& ior) +{ + for (int i = 0; i < listBox->count(); i++) { + if (listBox->item(i)->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* anItem = (ListBoxIOR*)(listBox->item(i)); + if (anItem && ior == string(anItem->GetIOR())) + return i; + } + } + return -1; +} + +//================================================================================= +// function : SMESHGUI_EditHypothesesDlg() +// purpose : Constructs a SMESHGUI_EditHypothesesDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +SMESHGUI_EditHypothesesDlg::SMESHGUI_EditHypothesesDlg (SMESHGUI* theModule, const char* name, + bool modal, WFlags fl) + : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | + WStyle_Title | WStyle_SysMenu | WDestructiveClose), + myImportedMesh(false), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + if (!name) + setName("SMESHGUI_EditHypothesesDlg"); + setCaption(tr("SMESH_EDIT_HYPOTHESES")); + setSizeGripEnabled(TRUE); + QGridLayout* SMESHGUI_EditHypothesesDlgLayout = new QGridLayout(this); + SMESHGUI_EditHypothesesDlgLayout->setSpacing(6); + SMESHGUI_EditHypothesesDlgLayout->setMargin(11); + + /***************************************************************/ + GroupC1 = new QGroupBox(tr("SMESH_ARGUMENTS"), this, "GroupC1"); + GroupC1->setColumnLayout(0, Qt::Vertical); + GroupC1->layout()->setSpacing(0); + GroupC1->layout()->setMargin(0); + QGridLayout* GroupC1Layout = new QGridLayout(GroupC1->layout()); + GroupC1Layout->setAlignment(Qt::AlignTop); + GroupC1Layout->setSpacing(6); + GroupC1Layout->setMargin(11); + + TextLabelC1A1 = new QLabel(tr("SMESH_OBJECT_MESHorSUBMESH"), GroupC1, "TextLabelC1A1"); + GroupC1Layout->addWidget(TextLabelC1A1, 0, 0); + SelectButtonC1A1 = new QPushButton(GroupC1, "SelectButtonC1A1"); + SelectButtonC1A1->setPixmap(image0); + GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1); + LineEditC1A1 = new QLineEdit(GroupC1, "LineEditC1A1"); + LineEditC1A1->setReadOnly(true); + GroupC1Layout->addWidget(LineEditC1A1, 0, 2); + + TextLabelC1A2 = new QLabel(tr("SMESH_OBJECT_GEOM"), GroupC1, "TextLabelC1A2"); + GroupC1Layout->addWidget(TextLabelC1A2, 1, 0); + SelectButtonC1A2 = new QPushButton(GroupC1, "SelectButtonC1A2"); + SelectButtonC1A2->setPixmap(image0); + SelectButtonC1A2->setToggleButton(FALSE); + GroupC1Layout->addWidget(SelectButtonC1A2, 1, 1); + LineEditC1A2 = new QLineEdit(GroupC1, "LineEditC1A2"); + LineEditC1A2->setReadOnly(true); + GroupC1Layout->addWidget(LineEditC1A2, 1, 2); + + SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupC1, 0, 0); + + /***************************************************************/ + GroupHypotheses = new QGroupBox(tr("SMESH_HYPOTHESES"), this, "GroupHypotheses"); + GroupHypotheses->setColumnLayout(0, Qt::Vertical); + GroupHypotheses->layout()->setSpacing(0); + GroupHypotheses->layout()->setMargin(0); + QGridLayout* grid_3 = new QGridLayout(GroupHypotheses->layout()); + grid_3->setAlignment(Qt::AlignTop); + grid_3->setSpacing(6); + grid_3->setMargin(11); + + TextHypDefinition = new QLabel(tr("SMESH_AVAILABLE"), GroupHypotheses, "TextHypDefinition"); + grid_3->addWidget(TextHypDefinition, 0, 0); + + ListHypDefinition = new QListBox(GroupHypotheses, "ListHypDefinition"); + ListHypDefinition->setMinimumSize(100, 100); + grid_3->addWidget(ListHypDefinition, 1, 0); + + TextHypAssignation = new QLabel(tr("SMESH_EDIT_USED"), GroupHypotheses, "TextHypAssignation"); + grid_3->addWidget(TextHypAssignation, 0, 1); + + ListHypAssignation = new QListBox(GroupHypotheses, "ListHypAssignation"); + ListHypAssignation->setMinimumSize(100, 100); + grid_3->addWidget(ListHypAssignation, 1, 1); + + SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupHypotheses, 1, 0); + + /***************************************************************/ + GroupAlgorithms = new QGroupBox(tr("SMESH_ADD_ALGORITHM"), this, "GroupAlgorithms"); + GroupAlgorithms->setColumnLayout(0, Qt::Vertical); + GroupAlgorithms->layout()->setSpacing(0); + GroupAlgorithms->layout()->setMargin(0); + QGridLayout* grid_4 = new QGridLayout(GroupAlgorithms->layout()); + grid_4->setAlignment(Qt::AlignTop); + grid_4->setSpacing(6); + grid_4->setMargin(11); + + TextAlgoDefinition = new QLabel(tr("SMESH_AVAILABLE"), GroupAlgorithms, "TextAlgoDefinition"); + grid_4->addWidget(TextAlgoDefinition, 0, 0); + + ListAlgoDefinition = new QListBox(GroupAlgorithms, "ListAlgoDefinition"); + ListAlgoDefinition->setMinimumSize(100, 100); + grid_4->addWidget(ListAlgoDefinition, 1, 0); + + TextAlgoAssignation = new QLabel(tr("SMESH_EDIT_USED"), GroupAlgorithms, "TextAlgoAssignation"); + grid_4->addWidget(TextAlgoAssignation, 0, 1); + + ListAlgoAssignation = new QListBox(GroupAlgorithms, "ListAlgoAssignation"); + ListAlgoAssignation ->setMinimumSize(100, 100); + grid_4->addWidget(ListAlgoAssignation, 1, 1); + + SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupAlgorithms, 2, 0); + + /***************************************************************/ + GroupButtons = new QGroupBox(this, "GroupButtons"); + GroupButtons->setColumnLayout(0, Qt::Vertical); + GroupButtons->layout()->setSpacing(0); + GroupButtons->layout()->setMargin(0); + QGridLayout* GroupButtonsLayout = new QGridLayout(GroupButtons->layout()); + GroupButtonsLayout->setAlignment(Qt::AlignTop); + GroupButtonsLayout->setSpacing(6); + GroupButtonsLayout->setMargin(11); + + buttonOk = new QPushButton(tr("SMESH_BUT_OK"), GroupButtons, "buttonOk"); + buttonOk->setAutoDefault(TRUE); + buttonOk->setDefault(FALSE); + GroupButtonsLayout->addWidget(buttonOk, 0, 0); + + buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons, "buttonApply"); + buttonApply->setAutoDefault(TRUE); + buttonApply->setDefault(FALSE); + GroupButtonsLayout->addWidget(buttonApply, 0, 1); + + GroupButtonsLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2); + + buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons, "buttonCancel"); + buttonCancel->setAutoDefault(TRUE); + buttonCancel->setDefault(TRUE); + buttonCancel->setEnabled(TRUE); + GroupButtonsLayout->addWidget(buttonCancel, 0, 3); + + SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupButtons, 4, 0); + + /***************************************************************/ + Init(); +} + +//================================================================================= +// function : ~SMESHGUI_EditHypothesesDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_EditHypothesesDlg::~SMESHGUI_EditHypothesesDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::Init() +{ + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + InitHypDefinition(); + InitAlgoDefinition(); + + //myGeomFilter = new SALOME_TypeFilter ("GEOM"); + TColStd_MapOfInteger allTypesMap; + for (int i = 0; i < 10; i++) + allTypesMap.Add(i); + myGeomFilter = new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, 0, allTypesMap); + myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); + + myGeomShape = GEOM::GEOM_Object::_nil(); + myMesh = SMESH::SMESH_Mesh::_nil(); + mySubMesh = SMESH::SMESH_subMesh::_nil(); + + /* signals and slots connections */ + connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel())); + + connect(SelectButtonC1A1, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + connect(SelectButtonC1A2, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); + + connect(ListHypAssignation, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(removeItem(QListBoxItem*))); + connect(ListAlgoAssignation, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(removeItem(QListBoxItem*))); + + connect(ListHypDefinition, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*))); + connect(ListAlgoDefinition, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*))); + + int x, y; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); + this->show(); + + LineEditC1A1->setFocus(); + myEditCurrentArgument = LineEditC1A1; + mySelectionMgr->clearFilters(); + mySelectionMgr->installFilter(myMeshOrSubMeshFilter); + + SelectionIntoArgument(); + + UpdateControlState(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::ClickOnOk() +{ + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::ClickOnApply() +{ + if (mySMESHGUI->isActiveStudyLocked()) + return false; + + bool aRes = false; + + SUIT_OverrideCursor wc; + + SUIT_Operation* op = new SUIT_Operation + (SUIT_Session::session()->activeApplication()); + + // start transaction + op->start(); + + if (!myMesh->_is_nil()) + aRes = StoreMesh(); + else if (!mySubMesh->_is_nil()) + aRes = StoreSubMesh(); + + if (true/*aRes*/) { // abort desynchronizes contents of a Study and a mesh on server + // commit transaction + op->commit(); + InitHypAssignation(); + InitAlgoAssignation(); + } else { + // abort transaction + op->abort(); + } + + UpdateControlState(); + mySMESHGUI->updateObjBrowser(); + + return aRes; +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::ClickOnCancel() +{ + close(); +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void SMESHGUI_EditHypothesesDlg::SelectionIntoArgument() +{ + QString aString = ""; + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); + + int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); + + if (myEditCurrentArgument == LineEditC1A1) { + if (nbSel != 1) { + myMesh = SMESH::SMESH_Mesh::_nil(); + mySubMesh = SMESH::SMESH_subMesh::_nil(); + aString = ""; + } else { + Handle(SALOME_InteractiveObject) IO = aList.First(); + myMesh = SMESH::IObjectToInterface(IO); + if (myMesh->_is_nil()) { + mySubMesh = SMESH::IObjectToInterface(IO); + if (mySubMesh->_is_nil()) { + aString = ""; + } + } + } + myEditCurrentArgument->setText(aString); + + // InitGeom() will try to retrieve a shape from myMesh or mySubMesh + myGeomShape = GEOM::GEOM_Object::_nil(); + InitGeom(); + + myImportedMesh = myGeomShape->_is_nil(); + + InitHypAssignation(); + InitAlgoAssignation(); + + } else if (myEditCurrentArgument == LineEditC1A2) { + if (nbSel != 1) { + myGeomShape = GEOM::GEOM_Object::_nil(); + } else { + Handle(SALOME_InteractiveObject) IO = aList.First(); + myGeomShape = SMESH::IObjectToInterface(IO); + } + InitGeom(); + } + + UpdateControlState(); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + if(send == SelectButtonC1A1) { + LineEditC1A1->setFocus(); + myEditCurrentArgument = LineEditC1A1; + mySelectionMgr->clearFilters(); + mySelectionMgr->installFilter(myMeshOrSubMeshFilter); + } else if (send == SelectButtonC1A2) { + LineEditC1A2->setFocus(); + myEditCurrentArgument = LineEditC1A2; + mySelectionMgr->clearFilters(); + mySelectionMgr->installFilter(myGeomFilter); + } + SelectionIntoArgument(); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::DeactivateActiveDialog() +{ + if (GroupC1->isEnabled()) { + disconnect(mySelectionMgr, 0, this, 0); + GroupC1->setEnabled(false); + GroupButtons->setEnabled(false); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog(); + GroupC1->setEnabled(true); + GroupButtons->setEnabled(true); + connect (mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::enterEvent (QEvent*) +{ + if (!GroupC1->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::closeEvent (QCloseEvent* e) +{ + disconnect(mySelectionMgr, 0, this, 0); + mySMESHGUI->ResetState(); + mySelectionMgr->clearFilters(); + QDialog::closeEvent(e); +} + +//======================================================================= +// function : IsOld() +// purpose : +//======================================================================= +bool SMESHGUI_EditHypothesesDlg::IsOld (QListBoxItem* hypItem) +{ + if (hypItem->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* hyp = (ListBoxIOR*) hypItem; + return (myMapOldHypos.find(hyp->GetIOR()) != myMapOldHypos.end() || + myMapOldAlgos.find(hyp->GetIOR()) != myMapOldAlgos.end()); + } + + return false; +} + +//================================================================================= +// function : removeItem() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::removeItem (QListBoxItem* item) +{ + const QObject* aSender = sender(); + + if (!item) return; + + if (aSender == ListHypAssignation) { + myNbModification += IsOld(item) ? 1 : -1; + ListHypAssignation->removeItem(ListHypAssignation->index(item)); + } + else if (aSender == ListAlgoAssignation) { + myNbModification += IsOld(item) ? 1 : -1; + ListAlgoAssignation->removeItem(ListAlgoAssignation->index(item)); + } + + UpdateControlState(); +} + +//================================================================================= +// function : addItem() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::addItem (QListBoxItem* item) +{ + const QObject* aSender = sender(); + + if (!item) return; + + ListBoxIOR* i = 0; + if (item->rtti() == ListBoxIOR::RTTI_IOR) + i = (ListBoxIOR*)item; + if (!i) return; + + bool isFound = false; + + ListBoxIOR* anItem; + if (aSender == ListHypDefinition) { + for (int j = 0, n = ListHypAssignation->count(); !isFound && j < n; j++) { + if (ListHypAssignation->item(j)->rtti() == ListBoxIOR::RTTI_IOR) { + anItem = (ListBoxIOR*)ListHypAssignation->item(j); + isFound = !strcmp(anItem->GetIOR(), i->GetIOR()); + } + } + if (!isFound) + anItem = new ListBoxIOR (ListHypAssignation, + CORBA::string_dup(i->GetIOR()), + CORBA::string_dup(i->text().latin1())); + + } else if (aSender == ListAlgoDefinition) { + for (int j = 0, n = ListAlgoAssignation->count(); !isFound && j < n; j++) { + if (ListAlgoAssignation->item(j)->rtti() == ListBoxIOR::RTTI_IOR) { + anItem = (ListBoxIOR*)ListAlgoAssignation->item(j); + isFound = !strcmp(anItem->GetIOR(), i->GetIOR()); + } + } + if (!isFound) + anItem = new ListBoxIOR (ListAlgoAssignation, + CORBA::string_dup(i->GetIOR()), + CORBA::string_dup(i->text().latin1())); + } else { + } + + if (!isFound) + myNbModification += IsOld(item) ? -1 : 1; + + UpdateControlState(); +} + +//================================================================================= +// function : InitHypDefinition() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::InitHypDefinition() +{ + ListHypDefinition->clear(); + + _PTR(SComponent) father = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); + if (!father) + return; + + _PTR(SObject) HypothesisRoot; + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + _PTR(AttributeIOR) anIOR; + + //int Tag_HypothesisRoot = 1; + if (father->FindSubObject(1, HypothesisRoot)) { + _PTR(ChildIterator) it = + SMESH::GetActiveStudyDocument()->NewChildIterator(HypothesisRoot); + ListBoxIOR* anItem; + for (; it->More();it->Next()) { + _PTR(SObject) Obj = it->Value(); + if (Obj->FindAttribute(anAttr, "AttributeName")) { + aName = anAttr; + if (Obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = anAttr; + anItem = new ListBoxIOR (ListHypDefinition, + anIOR->Value().c_str(), + aName->Value().c_str()); + } + } + } + } +} + +//================================================================================= +// function : InitHypAssignation() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::InitHypAssignation() +{ + myNbModification = 0; + + myMapOldHypos.clear(); + ListHypAssignation->clear(); + if (myImportedMesh) + return; + + _PTR(SObject) aMorSM, AHR, aRef; + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + _PTR(AttributeIOR) anIOR; + + if (!myMesh->_is_nil()) + aMorSM = SMESH::FindSObject(myMesh); + else if (!mySubMesh->_is_nil()) + aMorSM = SMESH::FindSObject(mySubMesh); + + if (aMorSM && aMorSM->FindSubObject(2, AHR)) { + _PTR(ChildIterator) it = + SMESH::GetActiveStudyDocument()->NewChildIterator(AHR); + for (; it->More();it->Next()) { + _PTR(SObject) Obj = it->Value(); + if (Obj->ReferencedObject(aRef)) { + if (aRef->FindAttribute(anAttr, "AttributeName")) { + aName = anAttr; + if (aRef->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = anAttr; + ListBoxIOR* anItem = new ListBoxIOR (ListHypAssignation, + anIOR->Value().c_str(), + aName->Value().c_str()); + myMapOldHypos[ anIOR->Value() ] = ListHypAssignation->index(anItem); + } + } + } + } + } +} + +//================================================================================= +// function : InitAlgoDefinition() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::InitAlgoDefinition() +{ + ListAlgoDefinition->clear(); + + _PTR(SComponent) father = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); + if (!father) + return; + + _PTR(SObject) AlgorithmsRoot; + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + _PTR(AttributeIOR) anIOR; + + if (father->FindSubObject (2, AlgorithmsRoot)) { + _PTR(ChildIterator) it = + SMESH::GetActiveStudyDocument()->NewChildIterator(AlgorithmsRoot); + ListBoxIOR* anItem; + for (; it->More();it->Next()) { + _PTR(SObject) Obj = it->Value(); + if (Obj->FindAttribute(anAttr, "AttributeName")) { + aName = anAttr; + if (Obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = anAttr; + anItem = new ListBoxIOR (ListAlgoDefinition, + anIOR->Value().c_str(), + aName->Value().c_str()); + } + } + } + } +} + +//================================================================================= +// function : InitAlgoAssignation() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::InitAlgoAssignation() +{ + myMapOldAlgos.clear(); + ListAlgoAssignation->clear(); + if (myImportedMesh) + return; + + _PTR(SObject) aMorSM, AHR, aRef; + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + _PTR(AttributeIOR) anIOR; + + if (!myMesh->_is_nil()) + aMorSM = SMESH::FindSObject(myMesh); + else if (!mySubMesh->_is_nil()) + aMorSM = SMESH::FindSObject(mySubMesh); + + if (aMorSM && aMorSM->FindSubObject(3, AHR)) { + _PTR(ChildIterator) it = + SMESH::GetActiveStudyDocument()->NewChildIterator(AHR); + for (; it->More();it->Next()) { + _PTR(SObject) Obj = it->Value(); + if (Obj->ReferencedObject(aRef)) { + if (aRef->FindAttribute(anAttr, "AttributeName")) { + aName = anAttr; + if (aRef->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = anAttr; + ListBoxIOR* anItem = new ListBoxIOR (ListAlgoAssignation, + anIOR->Value().c_str(), + aName->Value().c_str()); + myMapOldAlgos[ anIOR->Value() ] = ListAlgoAssignation->index(anItem); + } + } + } + } + } +} + +//================================================================================= +// function : InitGeom() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::InitGeom() +{ + LineEditC1A2->setText(""); + + if (myGeomShape->_is_nil() && !myMesh->_is_nil()) { + _PTR(SObject) aMesh = SMESH::FindSObject(myMesh); + if (aMesh) + myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMesh); + } + if (myGeomShape->_is_nil() && !mySubMesh->_is_nil()) { + _PTR(SObject) aSubMesh = SMESH::FindSObject(mySubMesh); + if (aSubMesh) + myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aSubMesh); + } + + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + if (!myGeomShape->_is_nil() && (!myMesh->_is_nil() || !mySubMesh->_is_nil())) { + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + //_PTR(SObject) aSO = aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(myGeomShape)); + _PTR(SObject) aSO = aStudy->FindObjectID(myGeomShape->GetStudyEntry()); + if (aSO) { + if (aSO->FindAttribute(anAttr, "AttributeName")) { + aName = anAttr; + LineEditC1A2->setText(QString(aName->Value().c_str())); + } + } + } +} + +//================================================================================= +// function : UpdateControlState() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::UpdateControlState() +{ + // asl the check of "count" is commented because of PAL9787 + bool isEnabled = (!myMesh->_is_nil() && !myGeomShape->_is_nil() /*&& + ListHypAssignation->count() && ListAlgoAssignation->count()*/ ) + || + (!mySubMesh->_is_nil() && !myGeomShape->_is_nil() /*&& + (ListHypAssignation->count() || ListAlgoAssignation->count())*/); + + buttonOk ->setEnabled(myNbModification && isEnabled && !myImportedMesh); + buttonApply->setEnabled(myNbModification && isEnabled && !myImportedMesh); + + SelectButtonC1A2 ->setEnabled(ALLOW_CHANGE_SHAPE && !myImportedMesh); + LineEditC1A2 ->setEnabled(ALLOW_CHANGE_SHAPE && !myImportedMesh); + ListHypDefinition ->setEnabled(!myImportedMesh); + ListHypAssignation ->setEnabled(!myImportedMesh); + ListAlgoDefinition ->setEnabled(!myImportedMesh); + ListAlgoAssignation->setEnabled(!myImportedMesh); +} + +//================================================================================= +// function : StoreMesh() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::StoreMesh() +{ + MapIOR anOldHypos, aNewHypos; + if (myGeomShape->_is_nil()) + return false; + + // 1. Check whether the geometric shape has changed + _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh); + GEOM::GEOM_Object_var aIniGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO); + bool bShapeChanged = aIniGeomShape->_is_nil() || + !aIniGeomShape->_is_equivalent(myGeomShape); + if (bShapeChanged) { + // VSR : TODO : Set new shape - not supported yet by SMESH engine + // 1. remove all old hypotheses and algorithms and also submeshes + // 2. set new shape + } + + int nbFail = 0; + MapIOR::iterator it; + + // 2. remove not used hypotheses from the mesh + for (it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it) { + string ior = it->first; + int index = findItem(ListHypAssignation, ior); + if (index < 0) { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()) { + if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aMeshSO, aHyp)) + nbFail++; + } + } + } + + // 3. remove not used algorithms from the mesh + for (it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it) { + string ior = it->first; + int index = findItem(ListAlgoAssignation, ior); + if (index < 0) { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()) { + if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aMeshSO, aHyp)) + nbFail++; + } + } + } + + // 4. Add new algorithms + for (int i = 0; i < ListAlgoAssignation->count(); i++) { + if (ListAlgoAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* anItem = (ListBoxIOR*)(ListAlgoAssignation->item(i)); + if (anItem) { + string ior = anItem->GetIOR(); + if (myMapOldAlgos.find(ior) == myMapOldAlgos.end()) { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()) { + if (!SMESH::AddHypothesisOnMesh(myMesh, aHyp)) + nbFail++; + } + } + } + } + } + + // 5. Add new hypotheses + for (int i = 0; i < ListHypAssignation->count(); i++) { + if (ListHypAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* anItem = (ListBoxIOR*)(ListHypAssignation->item(i)); + if (anItem) { + string ior = anItem->GetIOR(); + if (myMapOldHypos.find(ior) == myMapOldHypos.end()) { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()) { + if (!SMESH::AddHypothesisOnMesh(myMesh, aHyp)) + nbFail++; + } + } + } + } + } + return (nbFail == 0); +} + +//================================================================================= +// function : StoreSubMesh() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::StoreSubMesh() +{ + MapIOR anOldHypos, aNewHypos; + if (myGeomShape->_is_nil()) + return false; + + // 1. Check whether the geometric shape has changed + _PTR(SObject) aSubMeshSO = SMESH::FindSObject(mySubMesh); + GEOM::GEOM_Object_var aIniGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aSubMeshSO); + bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent(myGeomShape); + if (bShapeChanged) { + // VSR : TODO : Set new shape - not supported yet by engine + // 1. remove all old hypotheses and algorithms + // 2. set new shape + } + int nbFail = 0; + MapIOR::iterator it; + + // 2. remove not used hypotheses from the submesh + for (it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it) { + string ior = it->first; + int index = findItem(ListHypAssignation, ior); + if (index < 0) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()) { + if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aSubMeshSO, aHyp)) + nbFail++; + } + } + } + + // 3. remove not used algorithms from the submesh + for (it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it) { + string ior = it->first; + int index = findItem(ListAlgoAssignation, ior); + if (index < 0) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()){ + if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aSubMeshSO, aHyp)) + nbFail++; + } + } + } + + // 4. Add new algorithms + for (int i = 0; i < ListAlgoAssignation->count(); i++) { + if (ListAlgoAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* anItem = (ListBoxIOR*)(ListAlgoAssignation->item(i)); + if (anItem) { + string ior = anItem->GetIOR(); + if (myMapOldAlgos.find(ior) == myMapOldAlgos.end()) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()){ + if (!SMESH::AddHypothesisOnSubMesh(mySubMesh, aHyp)) + nbFail++; + } + } + } + } + } + + // 5. Add new hypotheses + for (int i = 0; i < ListHypAssignation->count(); i++) { + if (ListHypAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) { + ListBoxIOR* anItem = (ListBoxIOR*)(ListHypAssignation->item(i)); + if (anItem) { + string ior = anItem->GetIOR(); + if (myMapOldHypos.find(ior) == myMapOldHypos.end()) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface(ior.c_str()); + if (!aHyp->_is_nil()){ + if (!SMESH::AddHypothesisOnSubMesh(mySubMesh, aHyp)) + nbFail++; + } + } + } + } + } + return (nbFail == 0); +} diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx new file mode 100644 index 000000000..9bf9e43f5 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -0,0 +1,1448 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 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.org +// +// +// +// File : SMESHGUI_GroupDlg.cxx +// Author : Natalia KOPNOVA +// Module : SMESH +// $Header$ + +#include "SMESHGUI_GroupDlg.h" +#include "SMESHGUI_FilterDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GroupUtils.h" +#include "SMESHGUI_FilterUtils.h" +#include "SMESHGUI_GEOMGenUtils.h" + +#include "SMESH_TypeFilter.hxx" +#include "SMESH_Actor.h" +#include "GEOMBase.h" + +#include "SUIT_Desktop.h" +#include "SUIT_ResourceMgr.h" + +#include "SalomeApp_Tools.h" +#include "SALOMEDSClient_Study.hxx" +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "SVTK_ViewWindow.h" +#include "SVTK_Selector.h" + +#include "utilities.h" + +// OCCT Includes +#include + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// STL includes +#include +#include + +using namespace std; + +//================================================================================= +// function : SMESHGUI_GroupDlg() +// purpose : +//================================================================================= +SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, + SMESH::SMESH_Mesh_ptr theMesh, bool modal, WFlags fl) + : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | + WStyle_Title | WStyle_SysMenu | WDestructiveClose), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myIsBusy( false ), + myActor( 0 ) +{ + if (!name) setName("SMESHGUI_GroupDlg"); + initDialog(true); + if (!theMesh->_is_nil()) + init(theMesh); + else { + mySelectSubMesh->setEnabled(false); + mySelectGroup->setEnabled(false); + myGeomGroupBtn->setEnabled(false); + myGeomGroupLine->setEnabled(false); + } + + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); +} + +//================================================================================= +// function : SMESHGUI_GroupDlg() +// purpose : +//================================================================================= +SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, + SMESH::SMESH_Group_ptr theGroup, bool modal, WFlags fl) + : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | + WStyle_Title | WStyle_SysMenu | WDestructiveClose), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myIsBusy( false ) +{ + if (!name) setName("SMESHGUI_GroupDlg"); + + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + initDialog(false); + if (!theGroup->_is_nil()) + init(theGroup); + else { + mySelectSubMesh->setEnabled(false); + mySelectGroup->setEnabled(false); + + myCurrentLineEdit = myMeshGroupLine; + setSelectionMode(5); + } + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); +} + +//================================================================================= +// function : SMESHGUI_GroupDlg() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::initDialog(bool create) +{ + myFilterDlg = 0; + myCreate = create; + myCurrentLineEdit = 0; + + QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + + if (create) + setCaption(tr("SMESH_CREATE_GROUP_TITLE")); + else + setCaption(tr("SMESH_EDIT_GROUP_TITLE")); + + setSizeGripEnabled(TRUE); + + QGridLayout* aMainLayout = new QGridLayout(this, 7, 3, 11, 6); + + /***************************************************************/ + QLabel* meshGroupLab = new QLabel(this, "mesh/group label"); + if (create) + meshGroupLab->setText(tr("SMESH_MESH")); + else + meshGroupLab->setText(tr("SMESH_GROUP")); + myMeshGroupBtn = new QPushButton(this, "mesh/group button"); + myMeshGroupBtn->setPixmap(image0); + myMeshGroupLine = new QLineEdit(this, "mesh/group line"); + myMeshGroupLine->setReadOnly(true); + + /***************************************************************/ + myTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Group types"); + myTypeGroup->setTitle(tr("SMESH_ELEMENTS_TYPE")); + myTypeGroup->setExclusive(true); + + QStringList types; + types.append(tr("MESH_NODE")); + types.append(tr("SMESH_EDGE")); + types.append(tr("SMESH_FACE")); + types.append(tr("SMESH_VOLUME")); + QRadioButton* rb; + for (int i = 0; i < types.count(); i++) { + rb = new QRadioButton(types[i], myTypeGroup); + } + myTypeGroup->setEnabled(create); + myTypeId = -1; + + /***************************************************************/ + QLabel* aName = new QLabel(this, "name label"); + aName->setText(tr("SMESH_NAME")); + aName->setMinimumSize(50,0); + myName = new QLineEdit(this, "name"); + + /***************************************************************/ + myGrpTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Type of group"); + myGrpTypeGroup->setTitle(tr("SMESH_GROUP_TYPE")); + myGrpTypeGroup->setExclusive(true); + QRadioButton* rb1 = new QRadioButton( tr("SMESH_GROUP_STANDALONE"), myGrpTypeGroup); + QRadioButton* rb2 = new QRadioButton( tr("SMESH_GROUP_GEOMETRY"), myGrpTypeGroup); + myGrpTypeGroup->setEnabled(create); + myGrpTypeId = -1; + + /***************************************************************/ + myWGStack = new QWidgetStack( this, "widget stack"); + QWidget* wg1 = new QFrame( myWGStack, "first widget" ); + QWidget* wg2 = new QFrame( myWGStack, "second widget" ); + + /***************************************************************/ + QGroupBox* aContentBox = new QGroupBox(1, Qt::Horizontal, wg1, "content box"); + aContentBox->setTitle(tr("SMESH_CONTENT")); + QFrame* aContent = new QFrame(aContentBox, "content"); + QGridLayout* aLayout = new QGridLayout(aContent, 7, 4); + aLayout->setSpacing(6); + aLayout->setAutoAdd(false); + + QLabel* aLabel = new QLabel(aContent, "elements label"); + aLabel->setText(tr("SMESH_ID_ELEMENTS")); + myElements = new QListBox(aContent, "elements list"); + myElements->setSelectionMode(QListBox::Extended); + + myFilter = new QPushButton(aContent, "filter"); + myFilter->setText(tr("SMESH_BUT_FILTER")); + QPushButton* aAddBtn = new QPushButton(aContent, "add"); + aAddBtn->setText(tr("SMESH_BUT_ADD")); + QPushButton* aRemoveBtn = new QPushButton(aContent, "remove"); + aRemoveBtn->setText(tr("SMESH_BUT_REMOVE")); + QPushButton* aSortBtn = new QPushButton(aContent, "sort"); + aSortBtn->setText(tr("SMESH_BUT_SORT")); + + aLayout->addWidget(aLabel, 0, 0); + aLayout->addMultiCellWidget(myElements, 1, 6, 0, 0); + aLayout->addWidget(myFilter, 1, 2); + aLayout->addWidget(aAddBtn, 3, 2); + aLayout->addWidget(aRemoveBtn, 4, 2); + aLayout->addWidget(aSortBtn, 6, 2); + + aLayout->setColStretch(0, 1); + aLayout->addColSpacing(1, 20); + aLayout->addColSpacing(3, 20); + aLayout->setRowStretch(2, 1); + aLayout->setRowStretch(5, 1); + + /***************************************************************/ + QGroupBox* aSelectBox = new QGroupBox(3, Qt::Horizontal, wg1, "select box"); + aSelectBox->setTitle(tr("SMESH_SELECT_FROM")); + + mySelectSubMesh = new QCheckBox(aSelectBox, "submesh checkbox"); + mySelectSubMesh->setText(tr("SMESH_SUBMESH")); + mySelectSubMesh->setMinimumSize(50, 0); + mySubMeshBtn = new QPushButton(aSelectBox, "submesh button"); + mySubMeshBtn->setText(""); + mySubMeshBtn->setPixmap(image0); + mySubMeshLine = new QLineEdit(aSelectBox, "submesh line"); + mySubMeshLine->setReadOnly(true); + onSelectSubMesh(false); + + mySelectGroup = new QCheckBox(aSelectBox, "group checkbox"); + mySelectGroup->setText(tr("SMESH_GROUP")); + mySelectGroup->setMinimumSize(50, 0); + myGroupBtn = new QPushButton(aSelectBox, "group button"); + myGroupBtn->setText(""); + myGroupBtn->setPixmap(image0); + myGroupLine = new QLineEdit(aSelectBox, "group line"); + myGroupLine->setReadOnly(true); + onSelectGroup(false); + + /***************************************************************/ + QGridLayout* wg1Layout = new QGridLayout( wg1, 3, 1, 0, 6 ); + wg1Layout->addWidget(aContentBox, 0, 0); + wg1Layout->addWidget(aSelectBox, 1, 0); + wg1Layout->setRowStretch(2, 5); + + /***************************************************************/ + QLabel* geomObject = new QLabel(wg2, "geometry object label"); + geomObject->setText(tr("SMESH_OBJECT_GEOM")); + myGeomGroupBtn = new QPushButton(wg2, "geometry group button"); + myGeomGroupBtn->setText(""); + myGeomGroupBtn->setPixmap(image0); + myGeomGroupLine = new QLineEdit(wg2, "geometry group line"); + myGeomGroupLine->setReadOnly(true); //VSR ??? + onSelectGeomGroup(false); + + /***************************************************************/ + QGridLayout* wg2Layout = new QGridLayout( wg2, 2, 3, 0, 6 ); + wg2Layout->addWidget(geomObject, 0, 0); + wg2Layout->addWidget(myGeomGroupBtn, 0, 1); + wg2Layout->addWidget(myGeomGroupLine,0, 2); + wg2Layout->setRowStretch(1, 5); + + /***************************************************************/ + QVBoxLayout* dumb = new QVBoxLayout(myWGStack); + dumb->addWidget(wg1); + dumb->addWidget(wg2); + myWGStack->addWidget( wg1, myGrpTypeGroup->id(rb1) ); + myWGStack->addWidget( wg2, myGrpTypeGroup->id(rb2) ); + + /***************************************************************/ + QFrame* aButtons = new QFrame(this, "button box"); + aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken); + QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6); + aBtnLayout->setAutoAdd(false); + + QPushButton* aOKBtn = new QPushButton(aButtons, "ok"); + aOKBtn->setText(tr("SMESH_BUT_OK")); + aOKBtn->setAutoDefault(true); + aOKBtn->setDefault(true); + QPushButton* aApplyBtn = new QPushButton(aButtons, "apply"); + aApplyBtn->setText(tr("SMESH_BUT_APPLY")); + aApplyBtn->setAutoDefault(true); + QPushButton* aCloseBtn = new QPushButton(aButtons, "close"); + aCloseBtn->setText(tr("SMESH_BUT_CLOSE")); + aCloseBtn->setAutoDefault(true); + + aBtnLayout->addWidget(aOKBtn); + aBtnLayout->addWidget(aApplyBtn); + aBtnLayout->addStretch(); + aBtnLayout->addWidget(aCloseBtn); + + /***************************************************************/ + aMainLayout->addWidget(meshGroupLab, 0, 0); + aMainLayout->addWidget(myMeshGroupBtn, 0, 1); + aMainLayout->addWidget(myMeshGroupLine, 0, 2); + aMainLayout->addMultiCellWidget(myTypeGroup, 1, 1, 0, 2); + aMainLayout->addWidget(aName, 2, 0); + aMainLayout->addWidget(myName, 2, 2); + aMainLayout->addMultiCellWidget(myGrpTypeGroup, 3, 3, 0, 2); + aMainLayout->addMultiCellWidget(myWGStack, 4, 4, 0, 2); + aMainLayout->setRowStretch( 5, 5 ); + aMainLayout->addMultiCellWidget(aButtons, 6, 6, 0, 2); + + /* signals and slots connections */ + connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + + connect(myGrpTypeGroup, SIGNAL(clicked(int)), this, SLOT(onGrpTypeChanged(int))); + + connect(myTypeGroup, SIGNAL(clicked(int)), this, SLOT(onTypeChanged(int))); + + connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); + connect(myElements, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged())); + + connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters())); + connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); + connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); + connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort())); + + connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool))); + connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool))); + connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGeomGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + + connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); + connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); + connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); + + /* Init selection */ + mySMESHGUI->SetActiveDialogBox(this); + mySMESHGUI->SetState(800); + + mySelectionMode = -1; + myMeshFilter = new SMESH_TypeFilter(MESH); + mySubMeshFilter = new SMESH_TypeFilter(SUBMESH); + myGroupFilter = new SMESH_TypeFilter(GROUP); + + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose())); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged())); + + myGrpTypeGroup->setButton(myGrpTypeGroup->id(rb1)); // VSR !!! + onGrpTypeChanged(myGrpTypeGroup->id(rb1)); // VSR!!! + + if (myMesh->_is_nil() ) + myTypeGroup->setButton(0); + + updateButtons(); +} + +//================================================================================= +// function : ~SMESHGUI_GroupDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg() +{ + // no need to delete child widgets, Qt does it all for us + if ( myFilterDlg != 0 ) + { + myFilterDlg->reparent( 0, QPoint() ); + delete myFilterDlg; + } +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh) +{ + mySelectionMgr->installFilter(myMeshFilter); + + /* init data from current selection */ + myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh); + myGroup = SMESH::SMESH_Group::_nil(); + + myActor = SMESH::FindActorByObject(myMesh); + SMESH::SetPickable(myActor); + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + if( !aList.IsEmpty() ) + { + QString aName = aList.First()->getName(); + myMeshGroupLine->setText(aName) ; + myMeshGroupLine->home( false ); + } + + myCurrentLineEdit = 0; + + myTypeGroup->setButton(0); + onTypeChanged(0); +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::init (SMESH::SMESH_Group_ptr theGroup) +{ + myMesh = theGroup->GetMesh(); + myGroup = SMESH::SMESH_Group::_duplicate(theGroup); + + myActor = SMESH::FindActorByObject(myMesh); + if ( !myActor ) + myActor = SMESH::FindActorByObject(myGroup); + SMESH::SetPickable(myActor); + + int aType = 0; + switch(theGroup->GetType()) { + case SMESH::NODE: aType= 0; break; + case SMESH::EDGE: aType = 1; break; + case SMESH::FACE: aType = 2; break; + case SMESH::VOLUME: aType = 3; break; + } + + myName->setText(myGroup->GetName()); + myName->home(false); + myMeshGroupLine->setText(myGroup->GetName()); + + myCurrentLineEdit = 0; + myTypeGroup->setButton(aType); + myElements->clear(); + setSelectionMode(aType); + myTypeId = aType; + + myIdList.clear(); + if (!theGroup->IsEmpty()) { + SMESH::long_array_var anElements = myGroup->GetListOfID(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + myIdList.append(anElements[i]); + myElements->insertItem(QString::number(anElements[i])); + } + myElements->selectAll(true); + } +} + +//================================================================================= +// function : updateButtons() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::updateButtons() +{ + bool enable; + + if (myGrpTypeId == 0) + enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0; + else if (myGrpTypeId == 1) + enable = !myName->text().stripWhiteSpace().isEmpty() && !CORBA::is_nil( myGeomGroup ); + QPushButton* aBtn; + aBtn = (QPushButton*) child("ok", "QPushButton"); + if (aBtn) aBtn->setEnabled(enable); + aBtn = (QPushButton*) child("apply", "QPushButton"); + if (aBtn) aBtn->setEnabled(enable); +} + +//================================================================================= +// function : onNameChanged() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onNameChanged (const QString& text) +{ + updateButtons(); +} + +//================================================================================= +// function : onTypeChanged() +// purpose : Group elements type radio button management +//================================================================================= +void SMESHGUI_GroupDlg::onTypeChanged (int id) +{ + if (myTypeId != id) { + myElements->clear(); + if (myCurrentLineEdit == 0) + setSelectionMode(id); + } + myTypeId = id; +} + +//================================================================================= +// function : onGrpTypeChanged() +// purpose : Group type radio button management +//================================================================================= +void SMESHGUI_GroupDlg::onGrpTypeChanged (int id) +{ + if (myGrpTypeId != id) { + myWGStack->raiseWidget( id ); + onSelectGeomGroup(id == 1); + } + myGrpTypeId = id; +} + +//================================================================================= +// function : setSelectionMode() +// purpose : Radio button management +//================================================================================= +void SMESHGUI_GroupDlg::setSelectionMode (int theMode) +{ + // PAL7314 + if (myMesh->_is_nil()) + return; + + if (mySelectionMode != theMode) { + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + SMESH::SetPointRepresentation(false); + if (theMode < 4) { + switch (theMode) { + case 0: + if (myActor) + myActor->SetPointRepresentation(true); + else + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + break; + case 1: + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + break; + case 2: + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + break; + default: + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(VolumeSelection); + } + } else { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + if (theMode == 4) + mySelectionMgr->installFilter(mySubMeshFilter); + else if (theMode == 5) + mySelectionMgr->installFilter(myGroupFilter); + else if (theMode == 6) + mySelectionMgr->installFilter(myMeshFilter); + } + mySelectionMode = theMode; + } +} + +//================================================================================= +// function : onApply() +// purpose : +//================================================================================= +bool SMESHGUI_GroupDlg::onApply() +{ + if (mySMESHGUI->isActiveStudyLocked()) + return false; + + if (myGrpTypeId == 0 && + !myName->text().stripWhiteSpace().isEmpty() && + myElements->count() > 0) { + mySelectionMgr->clearSelected(); + if (myGroup->_is_nil()) { + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + SMESH::long_array_var anIdList = new SMESH::long_array; + int i, k = myElements->count(); + anIdList->length(k); + QListBoxItem* anItem; + for (i = 0, anItem = myElements->firstItem(); anItem != 0; i++, anItem = anItem->next()) { + anIdList[i] = anItem->text().toInt(); + } + + myGroup = SMESH::AddGroup(myMesh, aType, myName->text()); + myGroup->Add(anIdList.inout()); + + /* init for next operation */ + myName->setText(""); + myElements->clear(); + myGroup = SMESH::SMESH_Group::_nil(); + + } else { + myGroup->SetName(myName->text()); + + QValueList aAddList; + QValueList::iterator anIt; + QListBoxItem* anItem; + + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) { + int anId = anItem->text().toInt(); + if ((anIt = myIdList.find(anId)) == myIdList.end()) + aAddList.append(anId); + else + myIdList.remove(anIt); + } + if (!aAddList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length(aAddList.count()); + int i; + for (i = 0, anIt = aAddList.begin(); anIt != aAddList.end(); anIt++, i++) + anIdList[i] = *anIt; + myGroup->Add(anIdList.inout()); + } + if (!myIdList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length(myIdList.count()); + int i; + for (i = 0, anIt = myIdList.begin(); anIt != myIdList.end(); anIt++, i++) + anIdList[i] = *anIt; + myGroup->Remove(anIdList.inout()); + } + /* init for next operation */ + myIdList.clear(); + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) + myIdList.append(anItem->text().toInt()); + } + + mySMESHGUI->updateObjBrowser(true); + SMESH::UpdateView(); // asv: fix of BUG PAL5515 + mySelectionMgr->clearSelected(); + return true; + } else if (myGrpTypeId == 1 && + !myName->text().stripWhiteSpace().isEmpty() && + !CORBA::is_nil(myGeomGroup)) + { + SMESH::ElementType aType = SMESH::ALL; + switch (myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_IGroupOperations_var aGroupOp = + SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); + + SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = + myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomGroup); + + mySMESHGUI->updateObjBrowser(true); + mySelectionMgr->clearSelected(); + /* init for next operation */ + myName->setText(""); + return true; + } + + return false; +} + +//================================================================================= +// function : onOK() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onOK() +{ + if ( onApply() ) + onClose(); +} + +//================================================================================= +// function : onListSelectionChanged() +// purpose : Called when selection in element list is changed +//================================================================================= +void SMESHGUI_GroupDlg::onListSelectionChanged() +{ + // MESSAGE("SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor); + if( myIsBusy || !myActor) return; + myIsBusy = true; + + if (myCurrentLineEdit == 0) { + mySelectionMgr->clearSelected(); + TColStd_MapOfInteger aIndexes; + QListBoxItem* anItem; + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) { + if (anItem->isSelected()) { + int anId = anItem->text().toInt(); + aIndexes.Add(anId); + } + } + mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false); + SALOME_ListIO aList; + aList.Append(myActor->getIO()); + mySelectionMgr->setSelectedObjects(aList,false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( myActor->getIO(), true, true ); + } + myIsBusy = false; +} + +//================================================================================= +// function : onObjectSelectionChanged() +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onObjectSelectionChanged() +{ + if ( myIsBusy || !isEnabled()) return; + myIsBusy = true; + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + int aNbSel = aList.Extent(); + myElements->clearSelection(); + + if (myCurrentLineEdit) { + myCurrentLineEdit->setText(""); + QString aString = ""; + + if (myCurrentLineEdit == myMeshGroupLine) { + mySelectSubMesh->setEnabled(false); + mySelectGroup->setEnabled(false); + myGroupLine->setText(""); + mySubMeshLine->setText(""); + + myGeomGroupBtn->setEnabled(false); + myGeomGroupLine->setEnabled(false); + myGeomGroupLine->setText(""); + if (!myCreate) + myName->setText(""); + + myElements->clear(); + + if (aNbSel != 1 ) { + myGroup = SMESH::SMESH_Group::_nil(); + myMesh = SMESH::SMESH_Mesh::_nil(); + myIsBusy = false; + return; + } + Handle(SALOME_InteractiveObject) IO = aList.First(); + + if (myCreate) { + myMesh = SMESH::IObjectToInterface(IO); + if (myMesh->_is_nil()) + { + myIsBusy = false; + return; + } + myGroup = SMESH::SMESH_Group::_nil(); + + myActor = SMESH::FindActorByObject(myMesh); + SMESH::SetPickable(myActor); + + aString = aList.First()->getName(); + myMeshGroupLine->setText(aString) ; + myMeshGroupLine->home( false ); + + mySelectSubMesh->setEnabled(true); + mySelectGroup->setEnabled(true); + myGeomGroupBtn->setEnabled(true); + myGeomGroupLine->setEnabled(true); + updateButtons(); + } else { + SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface(IO); + if (aGroup->_is_nil()) + { + myIsBusy = false; + return; + } + myIsBusy = false; + myCurrentLineEdit = 0; + init(aGroup); + myIsBusy = true; + mySelectSubMesh->setEnabled(true); + mySelectGroup->setEnabled(true); + myGeomGroupBtn->setEnabled(true); + myGeomGroupLine->setEnabled(true); + } + myCurrentLineEdit = 0; + myIsBusy = false; + if (!myCreate) + return; + + if (myTypeId == -1) + onTypeChanged(0); + else { + myElements->clear(); + setSelectionMode(myTypeId); + } + + myIsBusy = false; + return; + + } else if (myCurrentLineEdit == myGeomGroupLine) { + if (aNbSel != 1) { + myGeomGroup = GEOM::GEOM_Object::_nil(); + myIsBusy = false; + return; + } + + Standard_Boolean testResult = Standard_False; + myGeomGroup = GEOMBase::ConvertIOinGEOMObject(aList.First(), testResult); + + // Check if the object is a geometry group + if (!testResult || CORBA::is_nil(myGeomGroup)) { + myGeomGroup = GEOM::GEOM_Object::_nil(); + myIsBusy = false; + return; + } + // Check if group constructed on the same shape as a mesh or on its child + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_IGroupOperations_var anOp = + SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); + + // The main shape of the group + GEOM::GEOM_Object_var aGroupMainShape; + if (myGeomGroup->GetType() == 37) + aGroupMainShape = anOp->GetMainShape(myGeomGroup); + else + aGroupMainShape = GEOM::GEOM_Object::_duplicate(myGeomGroup); + _PTR(SObject) aGroupMainShapeSO = + //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape)); + aStudy->FindObjectIOR(aGroupMainShape->GetStudyEntry()); + + // The mesh SObject + _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh); + if (!aMeshSO) { + myGeomGroup = GEOM::GEOM_Object::_nil(); + myIsBusy = false; + return; + } + _PTR(SObject) anObj, aRef; + bool isRefOrSubShape = false; + if (aMeshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(aRef)) { + //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) { + if (aRef->GetID() == aGroupMainShapeSO->GetID()) { + isRefOrSubShape = true; + } else { + _PTR(SObject) aFather = aGroupMainShapeSO->GetFather(); + _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent(); + //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) { + while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) { + //if (strcmp(aRef->GetID(), aFather->GetID()) == 0) + if (aRef->GetID() == aFather->GetID()) + isRefOrSubShape = true; + else + aFather = aFather->GetFather(); + } + } + } + if (!isRefOrSubShape) { + myGeomGroup = GEOM::GEOM_Object::_nil(); + myIsBusy = false; + return; + } + } + + if(aNbSel >= 1) { + if(aNbSel > 1) { + if(myCurrentLineEdit == mySubMeshLine) + aString = tr("SMESH_SUBMESH_SELECTED").arg(aNbSel); + else if(myCurrentLineEdit == myGroupLine || myCurrentLineEdit == myGeomGroupLine) + aString = tr("SMESH_GROUP_SELECTED").arg(aNbSel); + } else { + aString = aList.First()->getName(); + } + } + + myCurrentLineEdit->setText(aString); + myCurrentLineEdit->home(false); + + updateButtons(); + + } else { + if (aNbSel == 1 && myActor ) { + QString aListStr = ""; + int aNbItems = 0; + if (myTypeId == 0) { + aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + } else { + aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr); + } + if (aNbItems > 0) { + QStringList anElements = QStringList::split(" ", aListStr); + QListBoxItem* anItem = 0; + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (anItem) myElements->setSelected(anItem, true); + } + } + } + } + + if (!myActor) { + if (!myGroup->_is_nil()) + myActor = SMESH::FindActorByObject(myGroup); + else + myActor = SMESH::FindActorByObject(myMesh); + } + + myIsBusy = false; +} + +//================================================================================= +// function : onSelectSubMesh() +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectSubMesh(bool on) +{ + if (on) { + if (mySelectGroup->isChecked()) { + mySelectGroup->setChecked(false); + } + //VSR: else if (mySelectGeomGroup->isChecked()) { + //VSR: mySelectGeomGroup->setChecked(false); + //VSR: } + myCurrentLineEdit = mySubMeshLine; + setSelectionMode(4); + } + else { + mySubMeshLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } + mySubMeshBtn->setEnabled(on); + mySubMeshLine->setEnabled(on); +} + + +//================================================================================= +// function : (onSelectGroup) +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectGroup(bool on) +{ + if (on) { + if (mySelectSubMesh->isChecked()) { + mySelectSubMesh->setChecked(false); + } + myCurrentLineEdit = myGroupLine; + setSelectionMode(5); + } + else { + myGroupLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } + myGroupBtn->setEnabled(on); + myGroupLine->setEnabled(on); +} + + +//================================================================================= +// function : (onSelectGeomGroup) +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) +{ + if (on) { + if (mySelectSubMesh->isChecked()) { + mySelectSubMesh->setChecked(false); + } + else if (mySelectGroup->isChecked()) { + mySelectGroup->setChecked(false); + } + myCurrentLineEdit = myGeomGroupLine; + setSelectionMode(7); + } + else { + myGeomGroupLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } +} + + +//================================================================================= +// function : setCurrentSelection() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::setCurrentSelection() +{ + QPushButton* send = (QPushButton*)sender(); + myCurrentLineEdit = 0; + if (send == myMeshGroupBtn) { + myCurrentLineEdit = myMeshGroupLine; + if (myCreate) + setSelectionMode(6); + else + setSelectionMode(5); + onObjectSelectionChanged(); + } + else if (send == mySubMeshBtn) { + myCurrentLineEdit = mySubMeshLine; + onObjectSelectionChanged(); + } + else if (send == myGroupBtn) { + myCurrentLineEdit = myGroupLine; + onObjectSelectionChanged(); + } + else if (send == myGeomGroupBtn) { + myCurrentLineEdit = myGeomGroupLine; + setSelectionMode(7); + onObjectSelectionChanged(); + } +} + + +//================================================================================= +// function : setFilters() +// purpose : SLOT. Called when "Filter" button pressed. +//================================================================================= +void SMESHGUI_GroupDlg::setFilters() +{ + SMESH::ElementType aType = SMESH::ALL; + switch ( myTypeId ) + { + case 0 : aType = SMESH::NODE; break; + case 1 : aType = SMESH::EDGE; break; + case 2 : aType = SMESH::FACE; break; + case 3 : aType = SMESH::VOLUME; break; + default: return; + } + + if ( myFilterDlg == 0 ) + { + myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, aType ); + connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) ); + } + else + myFilterDlg->Init( aType ); + + myFilterDlg->SetSelection(); + myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetSourceWg( myElements ); + + myFilterDlg->show(); +} + +//================================================================================= +// function : onFilterAccepted() +// purpose : SLOT. Called when Filter dlg closed with OK button. +// Uncheck "Select submesh" and "Select group" checkboxes +//================================================================================= +void SMESHGUI_GroupDlg::onFilterAccepted() +{ + if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() ) + { + mySelectionMode = myTypeId; + mySelectSubMesh->setChecked( false ); + mySelectGroup->setChecked( false ); + } +} + +//================================================================================= +// function : onAdd() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onAdd() +{ + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + int aNbSel = aList.Extent(); + + if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return; + + myIsBusy = true; + + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + if (myCurrentLineEdit == 0) { + //if (aNbSel != 1) { myIsBusy = false; return; } + QString aListStr = ""; + int aNbItems = 0; + if (myTypeId == 0) { + aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + } + else { + aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr); + } + if (aNbItems > 0) { + QStringList anElements = QStringList::split(" ", aListStr); + QListBoxItem* anItem = 0; + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(*it); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + } else if (myCurrentLineEdit == mySubMeshLine) { + //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects()); + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + SALOME_ListIteratorOfListIO anIt (aList); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_subMesh_var aSubMesh = + SMESH::IObjectToInterface(anIt.Value()); + if (!aSubMesh->_is_nil()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + try { + SMESH::long_array_var anElements = aSubMesh->GetElementsByType(aType); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + catch (const SALOME::SALOME_Exception& ex) { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + } + } + } + mySelectSubMesh->setChecked(false); + myIsBusy = false; + onListSelectionChanged(); + + } else if (myCurrentLineEdit == myGroupLine) { + //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects()); + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + SALOME_ListIteratorOfListIO anIt (aList); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_Group_var aGroup = + SMESH::IObjectToInterface(anIt.Value()); + if (!aGroup->_is_nil()) { + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + } + } + mySelectGroup->setChecked(false); + myIsBusy = false; + onListSelectionChanged(); + + } else if (myCurrentLineEdit == myGeomGroupLine && !CORBA::is_nil(myGeomGroup)) { + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_IGroupOperations_var aGroupOp = + SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); + + SMESH::ElementType aGroupType = SMESH::ALL; + switch(aGroupOp->GetType(myGeomGroup)) { + case 7: aGroupType = SMESH::NODE; break; + case 6: aGroupType = SMESH::EDGE; break; + case 4: aGroupType = SMESH::FACE; break; + case 2: aGroupType = SMESH::VOLUME; break; + default: myIsBusy = false; return; + } + + if (aGroupType == aType) { + _PTR(SObject) aGroupSO = + //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(myGeomGroup)); + aStudy->FindObjectIOR(myGeomGroup->GetStudyEntry()); + // Construct filter + SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); + SMESH::Filter_var aFilter = aFilterMgr->CreateFilter(); + SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();; + aBelongToGeom->SetGeom(myGeomGroup); + aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str()); + aBelongToGeom->SetElementType(aType); + aFilter->SetPredicate(aBelongToGeom); + + SMESH::long_array_var anElements = aFilter->GetElementsId(myMesh); + + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + + //VSR: mySelectGeomGroup->setChecked(false); + myIsBusy = false; + onListSelectionChanged(); + } + myIsBusy = false; + // mySelectionMgr->clearSelected(); + updateButtons(); +} + +//================================================================================= +// function : onRemove() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onRemove() +{ + myIsBusy = true; + if (myCurrentLineEdit == 0) { + for (int i = myElements->count(); i > 0; i--) { + if (myElements->isSelected(i-1)) { + myElements->removeItem(i-1); + } + } + } else { + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + int aNbSel = aList.Extent(); + + if (aNbSel == 0) { myIsBusy = false; return; } + + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + if (myCurrentLineEdit == mySubMeshLine) { + //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects()); + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + SALOME_ListIteratorOfListIO anIt (aList); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(anIt.Value()); + if (!aSubMesh->_is_nil()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + if (aType == SMESH::NODE) { + try { + SMESH::long_array_var anElements = aSubMesh->GetNodesId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + } + else { + try { + SMESH::long_array_var anElements = aSubMesh->GetElementsId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + } + } + } + } + } + else if (myCurrentLineEdit == myGroupLine) { + Standard_Boolean aRes; + //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects()); + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + + SALOME_ListIteratorOfListIO anIt (aList); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface(anIt.Value()); + if (aRes && !aGroup->_is_nil()) { + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + } + } + } + } + myIsBusy = false; + updateButtons(); +} + +//================================================================================= +// function : onSort() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onSort() +{ + // PAL5412: sorts items in ascending by "string" value + // myElements->sort(true); + // myElements->update(); + int i, k = myElements->count(); + if (k > 0) { + myIsBusy = true; + QStringList aSelected; + std::vector anArray(k); + // QMemArray anArray(k); + QListBoxItem* anItem; + // fill the array + for (anItem = myElements->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) { + anArray[i] = anItem->text().toInt(); + if (anItem->isSelected()) + aSelected.append(anItem->text()); + } + // sort & update list + std::sort(anArray.begin(), anArray.end()); + // anArray.sort(); + myElements->clear(); + for (i = 0; i < k; i++) { + myElements->insertItem(QString::number(anArray[i])); + } + for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (anItem) myElements->setSelected(anItem, true); + } + myIsBusy = false; + } +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::closeEvent (QCloseEvent*) +{ + onClose(); +} + +//================================================================================= +// function : SMESHGUI_GroupDlg::onClose +// purpose : SLOT called when "Close" button pressed. Close dialog +//================================================================================= +void SMESHGUI_GroupDlg::onClose() +{ + if (SMESH::GetCurrentVtkView()) { + SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters + SMESH::SetPointRepresentation(false); + SMESH::SetPickable(); + } + + mySelectionMgr->clearSelected(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->clearFilters(); + mySMESHGUI->ResetState(); + + reject(); +} + +//================================================================================= +// function : SMESHGUI_GroupDlg::onDeactivate +// purpose : SLOT called when dialog must be deativated +//================================================================================= +void SMESHGUI_GroupDlg::onDeactivate() +{ + mySMESHGUI->ResetState(); + setEnabled(false); +} + +//================================================================================= +// function : SMESHGUI_GroupDlg::enterEvent +// purpose : Event filter +//================================================================================= +void SMESHGUI_GroupDlg::enterEvent (QEvent*) +{ + if (!isEnabled()) { + mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + mySelectionMode = -1; + setSelectionMode(myTypeId); + //mySMESHGUI->SetActiveDialogBox((QDialog*)this); + mySMESHGUI->SetActiveDialogBox(this); + mySMESHGUI->SetState(800); + } +} + +//================================================================================= +// function : hideEvent +// purpose : caused by ESC key +//================================================================================= +void SMESHGUI_GroupDlg::hideEvent (QHideEvent*) +{ + if (!isMinimized()) + onClose(); +} diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx new file mode 100755 index 000000000..2887e3c59 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -0,0 +1,1298 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_MultiEditDlg.cxx +// Author : Sergey LITONIN +// Module : SMESH + +#include "SMESHGUI_MultiEditDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Filter.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_FilterUtils.h" +#include "SMESHGUI_SpinBox.h" + +#include "SMESH_Actor.h" +#include "SMESH_TypeFilter.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshElement.hxx" + +#include "SUIT_ResourceMgr.h" +#include "SUIT_Desktop.h" + +#include "SalomeApp_SelectionMgr.h" +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "SVTK_Selector.h" +#include "SVTK_ViewModel.h" +#include "SVTK_ViewWindow.h" +#include "SVTK_InteractorStyle.h" + +// OCCT Includes +#include +#include +#include +#include + +// VTK Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// IDL Headers +#include "SALOMEconfig.h" +#include CORBA_SERVER_HEADER(SMESH_Group) + +#define SPACING 5 +#define MARGIN 10 + +/*! + * Class : SMESHGUI_MultiEditDlg + * Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by + * 2 neighboring triangles with 1 common edge + */ + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg +// Purpose : Constructor +//======================================================================= +SMESHGUI_MultiEditDlg +::SMESHGUI_MultiEditDlg(SMESHGUI* theModule, + const int theMode, + const bool the3d2d, + const char* theName): + QDialog(SMESH::GetDesktop(theModule), + theName, + false, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), + mySelector(SMESH::GetViewWindow(theModule)->GetSelector()), + mySelectionMgr(SMESH::GetSelectionMgr(theModule)), + mySMESHGUI(theModule) +{ + myFilterDlg = 0; + myEntityType = 0; + + myFilterType = theMode; + QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING); + + QFrame* aMainFrame = createMainFrame (this, the3d2d); + QFrame* aBtnFrame = createButtonFrame(this); + + aDlgLay->addWidget(aMainFrame); + aDlgLay->addWidget(aBtnFrame); + + aDlgLay->setStretchFactor(aMainFrame, 1); + aDlgLay->setStretchFactor(aBtnFrame, 0); + Init(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::createMainFrame +// Purpose : Create frame containing dialog's input fields +//======================================================================= +QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d) +{ + QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent); + aMainGrp->setFrameStyle(QFrame::NoFrame); + aMainGrp->setInsideMargin(0); + + QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + + // "Selected cells" group + mySelGrp = new QGroupBox(1, Qt::Horizontal, aMainGrp); + + myEntityTypeGrp = 0; + if (the3d2d) { + myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp); + (new QRadioButton(tr("SMESH_FACE"), myEntityTypeGrp))->setChecked(true); + (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp)); + myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected()); + } + + QFrame* aFrame = new QFrame(mySelGrp); + + myListBox = new QListBox(aFrame); + myListBox->setSelectionMode(QListBox::Extended); + myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); + myListBox->installEventFilter(this); + + myFilterBtn = new QPushButton(tr("FILTER") , aFrame); + myAddBtn = new QPushButton(tr("ADD") , aFrame); + myRemoveBtn = new QPushButton(tr("REMOVE") , aFrame); + mySortBtn = new QPushButton(tr("SORT_LIST"), aFrame); + + QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5); + aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0); + aLay->addWidget(myFilterBtn, 0, 1); + aLay->addWidget(myAddBtn, 1, 1); + aLay->addWidget(myRemoveBtn, 2, 1); + aLay->addWidget(mySortBtn, 3, 1); + + QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); + aLay->addItem(aSpacer, 4, 1); + + myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp); + + // Split/Join criterion group + myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp); + + myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp); + myGroupChoice->setInsideMargin(0); + myGroupChoice->setFrameStyle(QFrame::NoFrame); + (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true); + (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice)); + (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice)); + + myComboBoxFunctor = new QComboBox(myCriterionGrp); + myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS")); + myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS")); + myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS")); + myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS")); + //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only + //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only + myComboBoxFunctor->setCurrentItem(0); + + myCriterionGrp->hide(); + myGroupChoice->hide(); + myComboBoxFunctor->setEnabled(false); + + // "Select from" group + QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp); + + mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp); + mySubmeshBtn = new QPushButton(aGrp); + mySubmesh = new QLineEdit(aGrp); + mySubmesh->setReadOnly(true); + mySubmeshBtn->setPixmap(aPix); + + myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp); + myGroupBtn = new QPushButton(aGrp); + myGroup = new QLineEdit(aGrp); + myGroup->setReadOnly(true); + myGroupBtn->setPixmap(aPix); + + return aMainGrp; +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::createButtonFrame +// Purpose : Create frame containing buttons +//======================================================================= +QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent) +{ + QFrame* aFrame = new QFrame (theParent); + aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken); + + myOkBtn = new QPushButton (tr("SMESH_BUT_OK" ), aFrame); + myApplyBtn = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame); + myCloseBtn = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame); + + QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + + QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING); + + aLay->addWidget(myOkBtn); + aLay->addWidget(myApplyBtn); + aLay->addItem(aSpacer); + aLay->addWidget(myCloseBtn); + + return aFrame; +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::isValid +// Purpose : Verify validity of input data +//======================================================================= +bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const +{ + return (!myMesh->_is_nil() && + (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor))); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg +// Purpose : Destructor +//======================================================================= +SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg() +{ + if (myFilterDlg != 0) + { + myFilterDlg->reparent(0, QPoint()); + delete myFilterDlg; + } +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::eventFilter +// Purpose : event filter +//======================================================================= +bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event) +{ + if (object == myListBox && event->type() == QEvent::KeyPress) { + QKeyEvent* ke = (QKeyEvent*)event; + if (ke->key() == Key_Delete) + onRemoveBtn(); + } + return QDialog::eventFilter(object, event); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::getNumericalFunctor +// Purpose : +//======================================================================= +SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor() +{ + SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil(); + + SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); + if (aFilterMgr->_is_nil()) + return aNF._retn(); + + if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS")) + aNF = aFilterMgr->CreateAspectRatio(); + else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS")) + aNF = aFilterMgr->CreateWarping(); + else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS")) + aNF = aFilterMgr->CreateMinimumAngle(); + else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS")) + aNF = aFilterMgr->CreateTaper(); + else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS")) + aNF = aFilterMgr->CreateSkew(); + else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS")) + aNF = aFilterMgr->CreateArea(); + else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES")) + aNF = aFilterMgr->CreateLength2D(); + else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS")) + aNF = aFilterMgr->CreateMultiConnection2D(); + else ; + + return aNF._retn(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::Init +// Purpose : Init dialog fields, connect signals and slots, show dialog +//======================================================================= +void SMESHGUI_MultiEditDlg::Init() +{ + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + myListBox->clear(); + myIds.Clear(); + myBusy = false; + myActor = 0; + emit ListContensChanged(); + + // main buttons + connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk())); + connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose())); + connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply())); + + // selection and SMESHGUI + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone())); + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose())); + + // dialog controls + connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn() )); + connect(myAddBtn , SIGNAL(clicked()), SLOT(onAddBtn() )); + connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn() )); + connect(mySortBtn , SIGNAL(clicked()), SLOT(onSortListBtn())); + + connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk())); + connect(myGroupChk , SIGNAL(stateChanged(int)), SLOT(onGroupChk() )); + connect(myToAllChk , SIGNAL(stateChanged(int)), SLOT(onToAllChk() )); + + if (myEntityTypeGrp) + connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int))); + + connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged())); + + onSelectionDone(); + + // set selection mode + setSelectionMode(); + updateButtons(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onOk +// Purpose : SLOT called when "Ok" button pressed. +// Assign filters VTK viewer and close dialog +//======================================================================= +void SMESHGUI_MultiEditDlg::onOk() +{ + if (onApply()) + onClose(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::getIds +// Purpose : Retrive identifiers from list box +//======================================================================= +SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() +{ + SMESH::long_array_var anIds = new SMESH::long_array; + + if (myToAllChk->isChecked()) + { + myIds.Clear(); + SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh); + if (!anActor) + anActor = myActor; + if (anActor != 0) + { + TVisualObjPtr aVisualObj = anActor->GetObject(); + vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid(); + if (aGrid != 0) { + for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) { + vtkCell* aCell = aGrid->GetCell(i); + if (aCell != 0) { + vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell); + vtkQuad* aQua = vtkQuad::SafeDownCast(aCell); + vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell); + + vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell); + vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell); + + if (aTri && myFilterType == SMESHGUI_TriaFilter || + aQua && myFilterType == SMESHGUI_QuadFilter || + (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter || + (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) { + int anObjId = aVisualObj->GetElemObjId(i); + myIds.Add(anObjId); + } + } + } + } + } + } + + anIds->length(myIds.Extent()); + TColStd_MapIteratorOfMapOfInteger anIter(myIds); + for (int i = 0; anIter.More(); anIter.Next() ) + { + anIds[ i++ ] = anIter.Key(); + } + return anIds._retn(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onClose +// Purpose : SLOT called when "Close" button pressed. Close dialog +//======================================================================= +void SMESHGUI_MultiEditDlg::onClose() +{ + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + + SMESH::RemoveFilters(); + SMESH::SetPickable(); + + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + + reject(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onSelectionDone +// Purpose : SLOT called when selection changed +//======================================================================= +void SMESHGUI_MultiEditDlg::onSelectionDone() +{ + if (myBusy || !isEnabled()) return; + myBusy = true; + + const SALOME_ListIO& aList = mySelector->StoredIObjects(); + + int nbSel = aList.Extent(); + myListBox->clearSelection(); + + if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) { + QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup; + if (nbSel == 1) { + Handle(SALOME_InteractiveObject) anIO = aList.First(); + QString aName = ""; + SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName); + anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName); + + if (mySubmeshChk->isChecked()) { + SMESH::SMESH_subMesh_var aSubMesh = + SMESH::IObjectToInterface(anIO); + if (!aSubMesh->_is_nil()) + myMesh = aSubMesh->GetFather(); + } else { + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(anIO); + if (!aGroup->_is_nil()) + myMesh = aGroup->GetMesh(); + } + } else if (nbSel > 1) { + QString aStr = mySubmeshChk->isChecked() ? + tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED"); + aNameEdit->setText(aStr.arg(nbSel)); + } else { + aNameEdit->clear(); + } + } else if (nbSel == 1) { + QString aListStr = ""; + Handle(SALOME_InteractiveObject) anIO = aList.First(); + int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr); + if (aNbItems > 0) { + QStringList anElements = QStringList::split(" ", aListStr); + QListBoxItem* anItem = 0; + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + anItem = myListBox->findItem(*it, Qt::ExactMatch); + if (anItem) myListBox->setSelected(anItem, true); + } + } + + myMesh = SMESH::GetMeshByIO(anIO); + } + + if (nbSel == 1) { + myActor = SMESH::FindActorByEntry(aList.First()->getEntry()); + if (!myActor) + myActor = SMESH::FindActorByObject(myMesh); + SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle(); + Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter(myFilterType); + if (!aFilter.IsNull()) + aFilter->SetActor(myActor); + } + myBusy = false; + + updateButtons(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onDeactivate +// Purpose : SLOT called when dialog must be deativated +//======================================================================= +void SMESHGUI_MultiEditDlg::onDeactivate() +{ + setEnabled(false); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::enterEvent +// Purpose : Event filter +//======================================================================= +void SMESHGUI_MultiEditDlg::enterEvent (QEvent*) +{ + if (!isEnabled()) { + mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + setSelectionMode(); + } +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::closeEvent +// Purpose : +//======================================================================= +void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*) +{ + onClose(); +} +//======================================================================= +// name : SMESHGUI_MultiEditDlg::hideEvent +// Purpose : caused by ESC key +//======================================================================= +void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*) +{ + if (!isMinimized()) + onClose(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onFilterBtn +// Purpose : SLOT. Called when "Filter" button pressed. +// Start "Selection filters" dialog +//======================================================================= +void SMESHGUI_MultiEditDlg::onFilterBtn() +{ + if (myFilterDlg == 0) { + myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE); + connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted())); + } else { + myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE); + } + + myFilterDlg->SetSelection(); + myFilterDlg->SetMesh(myMesh); + myFilterDlg->SetSourceWg(myListBox); + + myFilterDlg->show(); +} + +//======================================================================= +// name : onFilterAccepted() +// Purpose : SLOT. Called when Filter dlg closed with OK button. +// Uncheck "Select submesh" and "Select group" checkboxes +//======================================================================= +void SMESHGUI_MultiEditDlg::onFilterAccepted() +{ + myIds.Clear(); + for (int i = 0, n = myListBox->count(); i < n; i++) + myIds.Add(myListBox->text(i).toInt()); + + emit ListContensChanged(); + + if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) { + mySubmeshChk->blockSignals(true); + myGroupChk->blockSignals(true); + mySubmeshChk->setChecked(false); + myGroupChk->setChecked(false); + mySubmeshChk->blockSignals(false); + myGroupChk->blockSignals(false); + } + updateButtons(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::isIdValid +// Purpose : Verify whether Id of element satisfies to filters from viewer +//======================================================================= +bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const +{ + SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle(); + Handle(SMESHGUI_Filter) aFilter = + Handle(SMESHGUI_Filter)::DownCast(aStyle->GetFilter(myFilterType)); + + return (!aFilter.IsNull() && aFilter->IsObjValid(theId)); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onAddBtn +// Purpose : SLOT. Called when "Add" button pressed. +// Add selected in viewer entities in list box +//======================================================================= +void SMESHGUI_MultiEditDlg::onAddBtn() +{ + const SALOME_ListIO& aList = mySelector->StoredIObjects(); + + int nbSelected = aList.Extent(); + if (nbSelected == 0) + return; + + TColStd_IndexedMapOfInteger toBeAdded; + + if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) { + if (nbSelected == 1) + mySelector->GetIndex(aList.First(),toBeAdded); + } else if (mySubmeshChk->isChecked()) { + SALOME_ListIteratorOfListIO anIter(aList); + for (; anIter.More(); anIter.Next()) { + SMESH::SMESH_subMesh_var aSubMesh = + SMESH::IObjectToInterface(anIter.Value()); + if (!aSubMesh->_is_nil()) { + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anIds = aSubMesh->GetElementsId(); + for (int i = 0, n = anIds->length(); i < n; i++) { + if (isIdValid(anIds[ i ])) + toBeAdded.Add(anIds[ i ]); + } + } + } + } + } else if (myGroupChk->isChecked()) { + SALOME_ListIteratorOfListIO anIter(aList); + for (; anIter.More(); anIter.Next()) { + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(anIter.Value()); + if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE && + entityType() == 0 || aGroup->GetType() == SMESH::VOLUME && + entityType() == 1)) { + if (aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anIds = aGroup->GetListOfID(); + for (int i = 0, n = anIds->length(); i < n; i++) { + if (isIdValid(anIds[ i ])) + toBeAdded.Add(anIds[ i ]); + } + } + } + } + } else { + } + + myBusy = true; + bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked()); + mySubmeshChk->setChecked(false); + myGroupChk->setChecked(false); + for(int i = 1; i <= toBeAdded.Extent(); i++) + if (myIds.Add(toBeAdded(i))) { + QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i))); + myListBox->insertItem(item); + myListBox->setSelected(item, true); + } + myBusy = false; + + emit ListContensChanged(); + + if (isGroupOrSubmesh) + onListSelectionChanged(); + + updateButtons(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::updateButtons +// Purpose : Enable/disable buttons of dialog in accordance with current state +//======================================================================= +void SMESHGUI_MultiEditDlg::updateButtons() +{ + bool isOk = isValid(false); + myOkBtn->setEnabled(isOk); + myApplyBtn->setEnabled(isOk); + + bool isListBoxNonEmpty = myListBox->count() > 0; + bool isToAll = myToAllChk->isChecked(); + myFilterBtn->setEnabled(!isToAll); + myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll); + mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll); + + const SALOME_ListIO& aList = mySelector->StoredIObjects(); + + if (isToAll || + myMesh->_is_nil() || + aList.Extent() != 1 || + (SMESH::IObjectToInterface(aList.First())->_is_nil() && + SMESH::IObjectToInterface(aList.First())->_is_nil() && + SMESH::IObjectToInterface(aList.First())->_is_nil())) + myAddBtn->setEnabled(false); + else + myAddBtn->setEnabled(true); + + mySubmeshChk->setEnabled(!isToAll); + mySubmeshBtn->setEnabled(mySubmeshChk->isChecked()); + mySubmesh->setEnabled(mySubmeshChk->isChecked()); + + myGroupChk->setEnabled(!isToAll); + myGroupBtn->setEnabled(myGroupChk->isChecked()); + myGroup->setEnabled(myGroupChk->isChecked()); + + if (!mySubmeshChk->isChecked()) + mySubmesh->clear(); + if (!myGroupChk->isChecked()) + myGroup->clear(); + +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onRemoveBtn +// Purpose : SLOT. Called when "Remove" button pressed. +// Remove selected in list box entities +//======================================================================= +void SMESHGUI_MultiEditDlg::onRemoveBtn() +{ + myBusy = true; + + for (int i = 0, n = myListBox->count(); i < n; i++) + { + for (int i = myListBox->count(); i > 0; i--) { + if (myListBox->isSelected(i - 1)) + { + int anId = myListBox->text(i - 1).toInt(); + myIds.Remove(anId); + myIds.Remove(anId); + myListBox->removeItem(i-1); + } + } + } + myBusy = false; + + emit ListContensChanged(); + updateButtons(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onSortListBtn +// Purpose : SLOT. Called when "Sort list" button pressed. +// Sort entities of list box +//======================================================================= +void SMESHGUI_MultiEditDlg::onSortListBtn() +{ + myBusy = true; + + int i, k = myListBox->count(); + if (k > 0) + { + QStringList aSelected; + std::vector anArray(k); + QListBoxItem* anItem; + for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) + { + anArray[ i ] = anItem->text().toInt(); + if (anItem->isSelected()) + aSelected.append(anItem->text()); + } + + std::sort(anArray.begin(), anArray.end()); + myListBox->clear(); + for (i = 0; i < k; i++) + myListBox->insertItem(QString::number(anArray[ i ])); + + for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) + { + anItem = myListBox->findItem(*it, Qt::ExactMatch); + if (anItem) + myListBox->setSelected(anItem, true); + } + } + myBusy = false; +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onListSelectionChanged +// Purpose : SLOT. Called when selection in list box changed. +// Highlight in selected entities +//======================================================================= +void SMESHGUI_MultiEditDlg::onListSelectionChanged() +{ + if (myActor == 0 || myBusy) + return; + + if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) + return; + + SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh); + if (!anActor) + anActor = myActor; + TVisualObjPtr anObj = anActor->GetObject(); + + TColStd_MapOfInteger anIndexes; + for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next()) + { + if (anItem->isSelected()) + { + int anId = anItem->text().toInt(); + if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight + anIndexes.Add(anId); + } + } + + mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight(anActor->getIO(),true,true); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onSubmeshChk +// Purpose : SLOT. Called when state of "SubMesh" check box changed. +// Activate/deactivate selection of submeshes +//======================================================================= +void SMESHGUI_MultiEditDlg::onSubmeshChk() +{ + bool isChecked = mySubmeshChk->isChecked(); + mySubmeshBtn->setEnabled(isChecked); + mySubmesh->setEnabled(isChecked); + if (!isChecked) + mySubmesh->clear(); + if (isChecked && myGroupChk->isChecked()) + myGroupChk->setChecked(false); + + setSelectionMode(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onGroupChk +// Purpose : SLOT. Called when state of "Group" check box changed. +// Activate/deactivate selection of groupes +//======================================================================= +void SMESHGUI_MultiEditDlg::onGroupChk() +{ + bool isChecked = myGroupChk->isChecked(); + myGroupBtn->setEnabled(isChecked); + myGroup->setEnabled(isChecked); + if (!isChecked) + myGroup->clear(); + if (isChecked && mySubmeshChk->isChecked()) + mySubmeshChk->setChecked(false); + + setSelectionMode(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onToAllChk +// Purpose : SLOT. Called when state of "Apply to all" check box changed. +// Activate/deactivate selection +//======================================================================= +void SMESHGUI_MultiEditDlg::onToAllChk() +{ + bool isChecked = myToAllChk->isChecked(); + + if (isChecked) + myListBox->clear(); + + myIds.Clear(); + + emit ListContensChanged(); + + updateButtons(); + setSelectionMode(); +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::setSelectionMode +// Purpose : Set selection mode +//======================================================================= +void SMESHGUI_MultiEditDlg::setSelectionMode() +{ + SMESH::RemoveFilters(); + + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + + if (mySubmeshChk->isChecked()) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH)); + } + else if (myGroupChk->isChecked()) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP)); + } + + if (entityType()) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(VolumeSelection); + SMESH::SetFilter(new SMESHGUI_VolumesFilter()); + } else { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + if (myFilterType == SMESHGUI_TriaFilter) + SMESH::SetFilter(new SMESHGUI_TriangleFilter()); + else if (myFilterType == SMESHGUI_QuadFilter) + SMESH::SetFilter(new SMESHGUI_QuadrangleFilter()); + else + SMESH::SetFilter(new SMESHGUI_FacesFilter()); + } +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::onApply +// Purpose : SLOT. Called when "Apply" button clicked. +//======================================================================= +bool SMESHGUI_MultiEditDlg::onApply() +{ + if (mySMESHGUI->isActiveStudyLocked()) + return false; + if (!isValid(true)) + return false; + + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + if (aMeshEditor->_is_nil()) + return false; + + myBusy = true; + + SMESH::long_array_var anIds = getIds(); + + bool aResult = process(aMeshEditor, anIds.inout()); + if (aResult) { + if (myActor) { + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + } + + myListBox->clear(); + myIds.Clear(); + emit ListContensChanged(); + + updateButtons(); + } + + myBusy = false; + return aResult; +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::on3d2dChanged +// Purpose : +//======================================================================= +void SMESHGUI_MultiEditDlg::on3d2dChanged (int type) +{ + if (myEntityType != type) { + myEntityType = type; + + myListBox->clear(); + myIds.Clear(); + + emit ListContensChanged(); + + if (type) + myFilterType = SMESHGUI_VolumeFilter; + else + myFilterType = SMESHGUI_FaceFilter; + + updateButtons(); + setSelectionMode(); + } +} + +//======================================================================= +// name : SMESHGUI_MultiEditDlg::entityType +// Purpose : +//======================================================================= +int SMESHGUI_MultiEditDlg::entityType() +{ + return myEntityType; +} + +/*! + * Class : SMESHGUI_ChangeOrientationDlg + * Description : Modification of orientation of faces + */ + +SMESHGUI_ChangeOrientationDlg +::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule, + const char* theName): + SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName) +{ + setCaption(tr("CAPTION")); +} + +SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg() +{ +} + +bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, + const SMESH::long_array& theIds) +{ + return theEditor->Reorient(theIds); +} + +/*! + * Class : SMESHGUI_UnionOfTrianglesDlg + * Description : Construction of quadrangles by automatic association of triangles + */ + +SMESHGUI_UnionOfTrianglesDlg +::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule, + const char* theName): + SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName) +{ + setCaption(tr("CAPTION")); + + myComboBoxFunctor->setEnabled(true); + myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only + myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only + + // Maximum angle + QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp); + aMaxAngleGrp->setInsideMargin(0); + aMaxAngleGrp->setFrameStyle(QFrame::NoFrame); + new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp); + myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp); + myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3); + myMaxAngleSpin->SetValue(30.0); + + myCriterionGrp->show(); +} + +SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg() +{ +} + +bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, + const SMESH::long_array& theIds) +{ + SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor(); + double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0; + return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle); +} + + +/*! + * Class : SMESHGUI_CuttingOfQuadsDlg + * Description : Automatic splitting of quadrangles into triangles + */ + +SMESHGUI_CuttingOfQuadsDlg +::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule, + const char* theName): + SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName) +{ + setCaption(tr("CAPTION")); + myPreviewActor = 0; + + myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp); + + myCriterionGrp->show(); + myGroupChoice->show(); + myComboBoxFunctor->setEnabled(false); + + connect(myPreviewChk , SIGNAL(stateChanged(int)) , this, SLOT(onPreviewChk())); + connect(myGroupChoice , SIGNAL(clicked(int)) , this, SLOT(onCriterionRB())); + connect(myComboBoxFunctor, SIGNAL(activated(int)) , this, SLOT(onPreviewChk())); + connect(this , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk())); +} + +SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg() +{ +} + +void SMESHGUI_CuttingOfQuadsDlg::onClose() +{ + erasePreview(); + SMESHGUI_MultiEditDlg::onClose(); +} + +bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, + const SMESH::long_array& theIds) +{ + switch (myGroupChoice->id(myGroupChoice->selected())) { + case 0: // use diagonal 1-3 + return theEditor->SplitQuad(theIds, true); + case 1: // use diagonal 2-4 + return theEditor->SplitQuad(theIds, false); + default: // use numeric functor + break; + } + + SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor(); + return theEditor->QuadToTri(theIds, aCriterion); +} + +void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB() +{ + if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor + myComboBoxFunctor->setEnabled(true); + else + myComboBoxFunctor->setEnabled(false); + + onPreviewChk(); +} + +void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk() +{ + myPreviewChk->isChecked() ? displayPreview() : erasePreview(); +} + +void SMESHGUI_CuttingOfQuadsDlg::erasePreview() +{ + if (myPreviewActor == 0) + return; + + if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) { + vf->RemoveActor(myPreviewActor); + vf->Repaint(); + } + myPreviewActor->Delete(); + myPreviewActor = 0; +} + +void SMESHGUI_CuttingOfQuadsDlg::displayPreview() +{ + if (myActor == 0) + return; + + if (myPreviewActor != 0) + erasePreview(); + + // get Ids of elements + SMESH::long_array_var anElemIds = getIds(); + if (getIds()->length() == 0) + return; + + SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + if (aMesh == 0) + return; + + // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor + int aChoice = myGroupChoice->id(myGroupChoice->selected()); + SMESH::NumericalFunctor_var aCriterion = SMESH::NumericalFunctor::_nil(); + SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil(); + if (aChoice == 2) { + aCriterion = getNumericalFunctor(); + aMeshEditor = myMesh->GetMeshEditor(); + if (aMeshEditor->_is_nil()) + return; + } + + //Create grid + vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); + + vtkIdType aNbCells = anElemIds->length() * 2; + vtkIdType aCellsSize = 4 * aNbCells; + vtkCellArray* aConnectivity = vtkCellArray::New(); + aConnectivity->Allocate(aCellsSize, 0); + + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(anElemIds->length() * 4); + + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents(1); + aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents()); + + vtkIdList *anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds(3); + + TColStd_DataMapOfIntegerInteger anIdToVtk; + + int aNodes[ 4 ]; + int nbPoints = -1; + for (int i = 0, n = anElemIds->length(); i < n; i++) + { + const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]); + if (anElem == 0 || anElem->NbNodes() != 4) + continue; + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + int k = 0; + while (anIter->more()) { + const SMDS_MeshNode* aNode = static_cast(anIter->next()); + if (aNode) + { + if (!anIdToVtk.IsBound(aNode->GetID())) + { + aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z()); + anIdToVtk.Bind(aNode->GetID(), nbPoints); + } + + aNodes[ k++ ] = aNode->GetID(); + } + } + + if (k != 4) + continue; + + bool isDiag13 = true; + if (aChoice == 0) // use diagonal 1-3 + { + isDiag13 = true; + } + else if (aChoice == 1) // use diagonal 2-4 + { + isDiag13 = false; + } + else // use numerical functor + { + // compare two sets of possible triangles + int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion); + if (diag == 1) // 1-3 + isDiag13 = true; + else if (diag == 2) // 2-4 + isDiag13 = false; + else // error + continue; + } + + if (isDiag13) + { + anIdList->SetId(0, anIdToVtk(aNodes[ 0 ])); + anIdList->SetId(1, anIdToVtk(aNodes[ 1 ])); + anIdList->SetId(2, anIdToVtk(aNodes[ 2 ])); + aConnectivity->InsertNextCell(anIdList); + aCellTypesArray->InsertNextValue(VTK_TRIANGLE); + + anIdList->SetId(0, anIdToVtk(aNodes[ 2 ])); + anIdList->SetId(1, anIdToVtk(aNodes[ 3 ])); + anIdList->SetId(2, anIdToVtk(aNodes[ 0 ])); + aConnectivity->InsertNextCell(anIdList); + aCellTypesArray->InsertNextValue(VTK_TRIANGLE); + } + else + { + anIdList->SetId(0, anIdToVtk(aNodes[ 1 ])); + anIdList->SetId(1, anIdToVtk(aNodes[ 2 ])); + anIdList->SetId(2, anIdToVtk(aNodes[ 3 ])); + aConnectivity->InsertNextCell(anIdList); + aCellTypesArray->InsertNextValue(VTK_TRIANGLE); + + anIdList->SetId(0, anIdToVtk(aNodes[ 3 ])); + anIdList->SetId(1, anIdToVtk(aNodes[ 0 ])); + anIdList->SetId(2, anIdToVtk(aNodes[ 1 ])); + aConnectivity->InsertNextCell(anIdList); + aCellTypesArray->InsertNextValue(VTK_TRIANGLE); + } + } + + vtkIntArray* aCellLocationsArray = vtkIntArray::New(); + aCellLocationsArray->SetNumberOfComponents(1); + aCellLocationsArray->SetNumberOfTuples(aNbCells); + + aConnectivity->InitTraversal(); + for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++) + aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts)); + + aGrid->SetPoints(aPoints); + aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity); + + // Create and display actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput(aGrid); + + myPreviewActor = SALOME_Actor::New(); + myPreviewActor->PickableOff(); + myPreviewActor->SetMapper(aMapper); + + vtkProperty* aProp = vtkProperty::New(); + aProp->SetRepresentationToWireframe(); + aProp->SetColor(250, 0, 250); + aProp->SetLineWidth(myActor->GetLineWidth() + 1); + myPreviewActor->SetProperty(aProp); + + SMESH::GetCurrentVtkView()->AddActor(myPreviewActor); + SMESH::GetCurrentVtkView()->Repaint(); + + aProp->Delete(); + aPoints->Delete(); + aConnectivity->Delete(); + aGrid->Delete(); + aMapper->Delete(); + anIdList->Delete(); + aCellTypesArray->Delete(); + aCellLocationsArray->Delete(); +} diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx new file mode 100644 index 000000000..014e88a5a --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -0,0 +1,433 @@ + +#include "SMESHGUI_Selection.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GEOMGenUtils.h" + +#include "SMESH_Type.h" +#include "SMESH_Actor.h" + +#include "SalomeApp_SelectionMgr.h" +#include "SalomeApp_Study.h" +#include "SalomeApp_VTKSelector.h" + +#include "SUIT_Session.h" + +#include "SVTK_RenderWindowInteractor.h" +#include "SVTK_ViewWindow.h" + +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) + +//======================================================================= +//function : SMESHGUI_Selection +//purpose : +//======================================================================= +SMESHGUI_Selection::SMESHGUI_Selection() +: SalomeApp_Selection() +{ +} + +//======================================================================= +//function : ~SMESHGUI_Selection +//purpose : +//======================================================================= +SMESHGUI_Selection::~SMESHGUI_Selection() +{ +} + +//======================================================================= +//function : init +//purpose : +//======================================================================= +void SMESHGUI_Selection::init( const QString& client, SalomeApp_SelectionMgr* mgr ) +{ + SalomeApp_Selection::init( client, mgr ); + + if( mgr && study() ) + { + _PTR(Study) aStudy = study()->studyDS(); + + SUIT_DataOwnerPtrList sel; + mgr->selected( sel, client ); + myDataOwners = sel; + SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(), + aLast = sel.end(); + for( ; anIt!=aLast; anIt++ ) + { + SUIT_DataOwner* owner = ( SUIT_DataOwner* )( (*anIt ).get() ); + SalomeApp_DataOwner* sowner = dynamic_cast( owner ); + if( sowner ) + myTypes.append( typeName( type( sowner, aStudy ) ) ); + else + myTypes.append( "Unknown" ); + } + } +} + +//======================================================================= +//function : param +//purpose : +//======================================================================= +QtxValue SMESHGUI_Selection::param( const int ind, const QString& p ) const +{ + QtxValue val; + if ( p=="client" ) val = QtxValue( globalParam( p ) ); + else if ( p=="type" ) val = QtxValue( myTypes[ind] ); + else if ( p=="elemTypes" ) val = QtxValue( elemTypes( ind ) ); + else if ( p=="numberOfNodes" ) val = QtxValue( numberOfNodes( ind ) ); + else if ( p=="labeledTypes" ) val = QtxValue( labeledTypes( ind ) ); + else if ( p=="shrinkMode" ) val = QtxValue( shrinkMode( ind ) ); + else if ( p=="entityMode" ) val = QtxValue( entityMode( ind ) ); + else if ( p=="controlMode" ) val = QtxValue( controlMode( ind ) ); + else if ( p=="displayMode" ) val = QtxValue( displayMode( ind ) ); + else if ( p=="isComputable" ) val = QtxValue( isComputable( ind ) ); + else if ( p=="hasReference" ) val = QtxValue( hasReference( ind ) ); + else if ( p=="isVisible" ) val = QtxValue( isVisible( ind ) ); + + // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() ); + //if ( val.type() == QVariant::List ) + //cout << "size: " << val.toList().count() << endl; + return val; +} + +//======================================================================= +//function : getVtkOwner +//purpose : +//======================================================================= + +SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const +{ + if ( ind >= 0 && ind < myDataOwners.count() ) { + const SalomeApp_SVTKDataOwner* owner = + dynamic_cast ( myDataOwners[ ind ].get() ); + if ( owner ) + return dynamic_cast( owner->GetActor() ); + } + return 0; +} + +//======================================================================= +//function : elemTypes +//purpose : may return {'Edge' 'Face' 'Volume'} at most +//======================================================================= + +QValueList SMESHGUI_Selection::elemTypes( int ind ) const +{ + QValueList types; + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + TVisualObjPtr object = actor->GetObject(); + if ( object ) { + if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" ); + if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" ); + if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" ); + } + } + return types; +} + +//======================================================================= +//function : labeledTypes +//purpose : may return {'Point' 'Cell'} at most +//======================================================================= + +QValueList SMESHGUI_Selection::labeledTypes( int ind ) const +{ + QValueList types; + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + if ( actor->GetPointsLabeled()) types.append( "Point" ); + if ( actor->GetCellsLabeled()) types.append( "Cell" ); + } + return types; +} + +//======================================================================= +//function : displayMode +//purpose : return SMESH_Actor::EReperesent +//======================================================================= + +QString SMESHGUI_Selection::displayMode( int ind ) const +{ + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + switch( actor->GetRepresentation() ) { + case SMESH_Actor::eEdge: return "eEdge"; + case SMESH_Actor::eSurface: return "eSurface"; + case SMESH_Actor::ePoint: return "ePoint"; + default:; + } + } + return "Unknown"; +} + +//======================================================================= +//function : shrinkMode +//purpose : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable' +//======================================================================= + +QString SMESHGUI_Selection::shrinkMode( int ind ) const +{ + SMESH_Actor* actor = getActor( ind ); + if ( actor && actor->IsShrunkable() ) { + if ( actor->IsShrunk() ) + return "IsShrunk"; + return "IsNotShrunk"; + } + return "IsNotShrinkable"; +} + +//======================================================================= +//function : entityMode +//purpose : may return {'Edge' 'Face' 'Volume'} at most +//======================================================================= + +QValueList SMESHGUI_Selection::entityMode( int ind ) const +{ + QValueList types; + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + unsigned int aMode = actor->GetEntityMode(); + if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume"); + if ( aMode & SMESH_Actor::eFaces ) types.append( "Face" ); + if ( aMode & SMESH_Actor::eEdges ) types.append( "Edge" ); + } + return types; +} + +//======================================================================= +//function : controlMode +//purpose : return SMESH_Actor::eControl +//======================================================================= + +QString SMESHGUI_Selection::controlMode( int ind ) const +{ + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + switch( actor->GetControlMode() ) { + case SMESH_Actor::eLength: return "eLength"; + case SMESH_Actor::eLength2D: return "eLength2D"; + case SMESH_Actor::eFreeEdges: return "eFreeEdges"; + case SMESH_Actor::eFreeBorders: return "eFreeBorders"; + case SMESH_Actor::eMultiConnection: return "eMultiConnection"; + case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D"; + case SMESH_Actor::eArea: return "eArea"; + case SMESH_Actor::eTaper: return "eTaper"; + case SMESH_Actor::eAspectRatio: return "eAspectRatio"; + case SMESH_Actor::eAspectRatio3D: return "eAspectRatio3D"; + case SMESH_Actor::eMinimumAngle: return "eMinimumAngle"; + case SMESH_Actor::eWarping: return "eWarping"; + case SMESH_Actor::eSkew: return "eSkew"; + default:; + } + } + return "eNone"; +} + +//======================================================================= +//function : numberOfNodes +//purpose : +//======================================================================= + +int SMESHGUI_Selection::numberOfNodes( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + CORBA::Object_var obj = + SMESH::DataOwnerToObject( static_cast( myDataOwners[ ind ].get() )); + if ( ! CORBA::is_nil( obj )) { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj ); + if ( ! mesh->_is_nil() ) + return mesh->NbNodes(); + SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj ); + if ( !aSubMeshObj->_is_nil() ) + return aSubMeshObj->GetNumberOfNodes(true); + SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj ); + if ( !aGroupObj->_is_nil() ) + return aGroupObj->Size(); + } + } + return 0; +} + +//======================================================================= +//function : isComputable +//purpose : +//======================================================================= + +QVariant SMESHGUI_Selection::isComputable( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + Handle(SALOME_InteractiveObject) io = + static_cast( myDataOwners[ ind ].get() )->IO(); + if ( !io.IsNull() ) { + SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io) ; // m,sm,gr->m + if ( !mesh->_is_nil() ) { + _PTR(SObject) so = SMESH::FindSObject( mesh ); + if ( so ) { + GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so ); + return QVariant( !shape->_is_nil(), 0 ); + } + } + } + } + return QVariant( false, 0 ); +} + +//======================================================================= +//function : hasReference +//purpose : +//======================================================================= + +QVariant SMESHGUI_Selection::hasReference( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + SalomeApp_DataOwner* owner = dynamic_cast( myDataOwners[ ind ].operator->() ); + if( owner ) + { + _PTR(SObject) obj ( study()->studyDS()->FindObjectID( owner->entry().latin1() ) ), ref; + return QVariant( obj->ReferencedObject( ref ), 0 ); + } + } + return QVariant( false, 0 ); +} + +//======================================================================= +//function : isVisible +//purpose : +//======================================================================= + +QVariant SMESHGUI_Selection::isVisible( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + QString entry = static_cast( myDataOwners[ ind ].get() )->entry(); + SMESH_Actor* actor = SMESH::FindActorByEntry( entry.latin1() ); + if ( actor && actor->hasIO() ) { + SVTK_RenderWindowInteractor* renderInter = SMESH::GetCurrentVtkView()->getRWInteractor(); + return QVariant( renderInter->isVisible( actor->getIO() ), 0 ); + } + } + return QVariant( false, 0 ); +} + + +//======================================================================= +//function : type +//purpose : +//======================================================================= +int SMESHGUI_Selection::type( SalomeApp_DataOwner* owner, _PTR(Study) study ) +{ + return type( owner->entry(), study ); +} + +//======================================================================= +//function : type +//purpose : +//======================================================================= + +int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study ) +{ + _PTR(SObject) obj (study->FindObjectID(entry.latin1())); + if( !obj ) + return -1; + + _PTR(SObject) ref; + if( obj->ReferencedObject( ref ) ) + obj = ref; + + _PTR(SObject) objFather = obj->GetFather(); + _PTR(SComponent) objComponent = obj->GetFatherComponent(); + + if( objComponent->ComponentDataType()!="SMESH" ) + return -1; + + int aLevel = obj->Depth() - objComponent->Depth(), + aFTag = objFather->Tag(), + anOTag = obj->Tag(), + res = -1; + + switch( aLevel ) + { + case 1: + if( anOTag>=3 ) + res = MESH; + break; + case 2: + switch( aFTag ) + { + case 1: + res = HYPOTHESIS; + break; + case 2: + res = ALGORITHM; + break; + } + break; + case 3: + switch( aFTag ) + { + case 4: + res = SUBMESH_VERTEX; + break; + case 5: + res = SUBMESH_EDGE; + break; + case 7: + res = SUBMESH_FACE; + break; + case 9: + res = SUBMESH_SOLID; + break; + case 10: + res = SUBMESH_COMPOUND; + break; + } + if( aFTag>10 ) + res = GROUP; + + break; + } + + return res; +} + +//======================================================================= +//function : typeName +//purpose : +//======================================================================= + +QString SMESHGUI_Selection::typeName( const int t ) +{ + switch( t ) + { + case HYPOTHESIS: + return "Hypothesis"; + case ALGORITHM: + return "Algorithm"; + case MESH: + return "Mesh"; + case SUBMESH: + return "SubMesh"; + case MESHorSUBMESH: + return "Mesh or submesh"; + case SUBMESH_VERTEX: + return "Mesh vertex"; + case SUBMESH_EDGE: + return "Mesh edge"; + case SUBMESH_FACE: + return "Mesh face"; + case SUBMESH_SOLID: + return "Mesh solid"; + case SUBMESH_COMPOUND: + return "Mesh compound"; + case GROUP: + return "Group"; + default: + return "Unknown"; + } +} diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx new file mode 100644 index 000000000..c9141ec82 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -0,0 +1,779 @@ +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + + +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_Filter.h" + +#include +#include + +#include + +#include +#include +#include + +#include "SalomeApp_SelectionMgr.h" + +#include "SVTK_Selector.h" +#include "SVTK_ViewModel.h" +#include "SVTK_ViewWindow.h" +#include "SVTK_RenderWindow.h" +#include "SVTK_InteractorStyle.h" +#include "SVTK_RenderWindowInteractor.h" + +#include "utilities.h" + +#include "SALOMEconfig.h" +#include CORBA_CLIENT_HEADER(SMESH_Gen) +#include CORBA_CLIENT_HEADER(SMESH_Mesh) +#include CORBA_CLIENT_HEADER(SMESH_Group) +#include CORBA_CLIENT_HEADER(SMESH_Hypothesis) + +#include "SMESHGUI.h" +#include "SMESH_Actor.h" +#include "SMESH_ObjectDef.h" + +#include +#include +#include + +#include +#include + +#include +#include + +#include +using namespace std; + +namespace SMESH{ + + typedef map TVisualObjCont; + static TVisualObjCont VISUAL_OBJ_CONT; + + TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){ + TVisualObjPtr aVisualObj; + try{ + TVisualObjCont::key_type aKey(theStudyId,theEntry); + TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); + if(anIter != VISUAL_OBJ_CONT.end()){ + aVisualObj = anIter->second; + }else{ + SalomeApp_Application* app = dynamic_cast( SMESHGUI::activeStudy()->application() ); + _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS(); + _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry); + if(aSObj){ + _PTR(GenericAttribute) anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeIOR")){ + _PTR(AttributeIOR) anIOR = anAttr; + CORBA::String_var aVal = anIOR->Value().c_str(); + CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() ); + if(!CORBA::is_nil(anObj)){ + //Try narrow to SMESH_Mesh interafce + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); + if(!aMesh->_is_nil()){ + aVisualObj.reset(new SMESH_MeshObj(aMesh)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + return aVisualObj; + } + //Try narrow to SMESH_Group interafce + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj); + if(!aGroup->_is_nil()){ + _PTR(SObject) aFatherSObj = aSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + return aVisualObj; + } + } + //Try narrow to SMESH_subMesh interafce + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); + if(!aSubMesh->_is_nil()){ + _PTR(SObject) aFatherSObj = aSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + return aVisualObj; + } + } + } + } + } + } + }catch(...){ + INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!"); + } + return aVisualObj; + } + + + SVTK_ViewWindow* + GetViewWindow(const SalomeApp_Module* theModule) + { + if (SalomeApp_Application* anApp = theModule->getApp()) + return dynamic_cast(anApp->desktop()->activeWindow()); + return NULL; + } + + SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager* theMgr, + SUIT_ViewWindow* theWindow ) + { + if( !theMgr ) + return NULL; + + QPtrVector views = theMgr->getViews(); + if( views.containsRef( theWindow ) ) + return GetVtkViewWindow( theWindow ); + else + return NULL; + } + + + SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){ + return dynamic_cast(theWindow); + } + + +/* SUIT_ViewWindow* GetActiveWindow() + { + SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( !app ) + return NULL; + SUIT_ViewManager* mgr = app->activeViewManager(); + if( mgr ) + return mgr->getActiveView(); + else + return NULL; + }*/ + + SVTK_ViewWindow* GetCurrentVtkView(){ + return GetVtkViewWindow( GetActiveWindow() ); + } + + void RepaintViewWindow(SVTK_ViewWindow* theWindow) + { + theWindow->Repaint(); + } + + void RenderViewWindow(SVTK_ViewWindow* theWindow) + { + theWindow->getRenderer()->Render(); + theWindow->Repaint(); + } + + SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow, + const char* theEntry) + { + if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){ + vtkRenderer *aRenderer = aViewWindow->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){ + return anActor; + } + } + } + } + } + return NULL; + } + + + SMESH_Actor* FindActorByEntry(const char* theEntry){ + return FindActorByEntry(GetActiveWindow(),theEntry); + } + + + SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){ + SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( !app ) + return NULL; + + if(!CORBA::is_nil(theObject)){ + _PTR(Study) aStudy = GetActiveStudyDocument(); + CORBA::String_var anIOR = app->orb()->object_to_string( theObject ); + _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in()); + if(aSObject){ + CORBA::String_var anEntry = aSObject->GetID().c_str(); + return FindActorByEntry(anEntry.in()); + } + } + return NULL; + } + + + SMESH_Actor* CreateActor(_PTR(Study) theStudy, + const char* theEntry, + int theIsClear) + { + SMESH_Actor *anActor = NULL; + CORBA::Long anId = theStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){ + _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry); + if(aSObj){ + _PTR(GenericAttribute) anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeName")){ + _PTR(AttributeName) aName = anAttr; + std::string aNameVal = aName->Value(); + anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear); + } + } + } + return anActor; + } + + + void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){ + if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){ + vtkWnd->AddActor(theActor); + vtkWnd->Repaint(); + } + } + + + void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){ + if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){ + vtkWnd->RemoveActor(theActor); + if(theActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); + if(anIO->hasEntry()){ + std::string anEntry = anIO->getEntry(); + SalomeApp_Study* aStudy = dynamic_cast( vtkWnd->getViewManager()->study() ); + int aStudyId = aStudy->id(); + TVisualObjCont::key_type aKey(aStudyId,anEntry); + VISUAL_OBJ_CONT.erase(aKey); + } + } + theActor->Delete(); + vtkWnd->Repaint(); + } + } + + + void FitAll(){ + if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){ + wnd->onFitAll(); + wnd->Repaint(); + } + } + + vtkRenderer* GetCurrentRenderer(){ + if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ) + return wnd->getRenderer(); + return NULL; + } + + void RepaintCurrentView(){ + if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ) + { + wnd->getRenderer()->Render(); + wnd->Repaint(false); + } + } + + void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry) + { + if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){ + vtkRenderer *aRenderer = aViewWnd->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + switch(theAction){ + case eDisplayAll: { + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetVisibility(true); + } + } + break; + } + case eDisplayOnly: + case eEraseAll: { + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetVisibility(false); + } + } + } + default: { + if(SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)){ + switch(theAction) { + case eDisplay: + case eDisplayOnly: + anActor->SetVisibility(true); + break; + case eErase: + anActor->SetVisibility(false); + break; + } + } else { + switch(theAction){ + case eDisplay: + case eDisplayOnly:{ + SalomeApp_Study* aStudy = dynamic_cast( theWnd->getViewManager()->study() ); + _PTR(Study) aDocument = aStudy->studyDS(); + if((anActor = CreateActor(aDocument,theEntry,true))) { + DisplayActor(theWnd,anActor); + FitAll(); + } + break; + } + } + } + } + } + } + } + + + void UpdateView(EDisplaing theAction, const char* theEntry){ + SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() ); + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() ); + SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView(); + UpdateView(aWnd,theAction,theEntry); + } + + void UpdateView(){ + if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){ + SalomeApp_SelectionMgr* mgr = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; mgr->selectedObjects( selected ); + + if( selected.Extent() == 0){ + vtkRenderer* aRenderer = aWnd->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()) + Update(anActor->getIO(),anActor->GetVisibility()); + } + } + }else{ + SALOME_ListIteratorOfListIO anIter( selected ); + for(; anIter.More(); anIter.Next()){ + Handle(SALOME_InteractiveObject) anIO = anIter.Value(); + Update(anIO,true); + } + } + RepaintCurrentView(); + } + } + + + void Update(const Handle(SALOME_InteractiveObject)& theIO, + bool theDisplay) + { + _PTR(Study) aStudy = GetActiveStudyDocument(); + CORBA::Long anId = aStudy->StudyId(); + TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry()); + if( aVisualObj ) + aVisualObj->Update(); + if ( theDisplay ) + UpdateView(SMESH::eDisplay,theIO->getEntry()); + } + + + void UpdateSelectionProp( SMESHGUI* theModule ) { + if( !theModule ) + return; + + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() ); + if( !app ) + { + MESSAGE( "UpdateSelectionProp: Application is null" ); + return; + } + + SUIT_ViewManager* vm = app->activeViewManager(); + if( !vm ) + { + MESSAGE( "UpdateSelectionProp: View manager is null" ); + return; + } + + QPtrVector views = vm->getViews(); + + SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule ); + if( !mgr ) + { + MESSAGE( "UpdateSelectionProp: Resource manager is null" ); + return; + } + + QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ), + aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ), + aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan ); + + int SW = mgr->integerValue( "SMESH", "selection_width", 5 ), + PW = mgr->integerValue( "SMESH", "highlight_width", 5 ); + + double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ), + SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ); + + for ( int i=0, n=views.count(); igetRWInteractor(); + if (anInteractor) { + // mesh element selection + anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255., + aSelColor.blue()/255., SW ); + + // tolerances + anInteractor->SetSelectionTolerance(SP1, SP2); + + // pre-selection + SVTK_InteractorStyle* aStyle = + dynamic_cast( anInteractor->GetInteractorStyle() ); + if (aStyle) { + aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255., PW); + } + } + // update actors + vtkRenderer* aRenderer = aVtkView->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255., + aHiColor.blue()/255.); + anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255.); + } + } + } + } + + + //---------------------------------------------------------------------------- + SVTK_InteractorStyle* GetInteractorStyle(SUIT_ViewWindow *theWindow){ + if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow)){ + if(SVTK_RenderWindowInteractor* anInteractor = aWnd->getRWInteractor()){ + return dynamic_cast( anInteractor->GetInteractorStyle() ); + } + } + return NULL; + } + + void SetFilter(const Handle(VTKViewer_Filter)& theFilter, + SVTK_InteractorStyle* theStyle) + { + if (theStyle) + theStyle->SetFilter(theFilter); + } + + Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_InteractorStyle* theStyle) + { + return theStyle->GetFilter(theId); + } + + bool IsFilterPresent(int theId, SVTK_InteractorStyle* theStyle) + { + return theStyle->IsFilterPresent(theId); + } + + void RemoveFilter(int theId, SVTK_InteractorStyle* theStyle) + { + theStyle->RemoveFilter(theId); + } + + void RemoveFilters(SVTK_InteractorStyle* theStyle) + { + for ( int id = SMESHGUI_NodeFilter; theStyle && id < SMESHGUI_LastFilter; id++ ) + theStyle->RemoveFilter( id ); + } + + bool IsValid(SALOME_Actor* theActor, int theCellId, + SVTK_InteractorStyle* theStyle) + { + return theStyle->IsValid(theActor,theCellId); + } + + + //---------------------------------------------------------------------------- + void SetPointRepresentation(bool theIsVisible){ + if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){ + vtkRenderer *aRenderer = aViewWindow->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPointRepresentation(theIsVisible); + } + } + } + RepaintCurrentView(); + } + } + + + void SetPickable(SMESH_Actor* theActor){ + if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){ + int anIsAllPickable = (theActor == NULL); + vtkRenderer *aRenderer = aWnd->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SALOME_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPickable(anIsAllPickable); + } + } + } + if(theActor) + theActor->SetPickable(!anIsAllPickable); + RepaintCurrentView(); + } + } + + + //---------------------------------------------------------------------------- + int GetNameOfSelectedNodes(SVTK_Selector* theSelector, + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) + { + theName = ""; + TColStd_IndexedMapOfInteger aMapIndex; + theSelector->GetIndex(theIO,aMapIndex); + + for(int i = 1; i <= aMapIndex.Extent(); i++) + theName += QString(" %1").arg(aMapIndex(i)); + + return aMapIndex.Extent(); + } + + int GetNameOfSelectedElements(SVTK_Selector* theSelector, + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) + { + theName = ""; + TColStd_IndexedMapOfInteger aMapIndex; + theSelector->GetIndex(theIO,aMapIndex); + + typedef std::set TIdContainer; + TIdContainer anIdContainer; + for( int i = 1; i <= aMapIndex.Extent(); i++) + anIdContainer.insert(aMapIndex(i)); + + TIdContainer::const_iterator anIter = anIdContainer.begin(); + for(; anIter != anIdContainer.end(); anIter++) + theName += QString(" %1").arg(*anIter); + + return aMapIndex.Extent(); + } + + + int GetEdgeNodes(SVTK_Selector* theSelector, + const TVisualObjPtr& theVisualObject, + int& theId1, + int& theId2) + { + const SALOME_ListIO& selected = theSelector->StoredIObjects(); + + if ( selected.Extent() != 1 ) + return -1; + + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO.IsNull() || !anIO->hasEntry() ) + return -1; + + TColStd_IndexedMapOfInteger aMapIndex; + theSelector->GetIndex( anIO, aMapIndex ); + if ( aMapIndex.Extent() != 2 ) + return -1; + + int anObjId = -1, anEdgeNum = -1; + for ( int i = 1; i <= aMapIndex.Extent(); i++ ) { + int aVal = aMapIndex( i ); + if ( aVal > 0 ) + anObjId = aVal; + else + anEdgeNum = abs( aVal ) - 1; + } + + if ( anObjId == -1 || anEdgeNum == -1 ) + return -1; + + return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1; + } + + //---------------------------------------------------------------------------- + int GetNameOfSelectedNodes(SalomeApp_SelectionMgr *theMgr, + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) + { + theName = ""; + if(theIO->hasEntry()){ + if(FindActorByEntry(theIO->getEntry())){ + TColStd_IndexedMapOfInteger aMapIndex; + theMgr->GetIndexes(theIO,aMapIndex); + for(int i = 1; i <= aMapIndex.Extent(); i++){ + theName += QString(" %1").arg(aMapIndex(i)); + } + return aMapIndex.Extent(); + } + } + return -1; + } + + int GetNameOfSelectedNodes(SalomeApp_SelectionMgr *theMgr, QString& theName){ + theName = ""; + SALOME_ListIO selected; theMgr->selectedObjects( selected ); + if(selected.Extent() == 1){ + Handle(SALOME_InteractiveObject) anIO = selected.First(); + return GetNameOfSelectedNodes(theMgr,anIO,theName); + } + return -1; + } + + + int GetNameOfSelectedElements(SalomeApp_SelectionMgr *theMgr, + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) + { + theName = ""; + if(theIO->hasEntry()){ + if(FindActorByEntry(theIO->getEntry())){ + TColStd_IndexedMapOfInteger aMapIndex; + theMgr->GetIndexes(theIO,aMapIndex); + typedef set TIdContainer; + TIdContainer anIdContainer; + for( int i = 1; i <= aMapIndex.Extent(); i++) + anIdContainer.insert(aMapIndex(i)); + TIdContainer::const_iterator anIter = anIdContainer.begin(); + for(; anIter != anIdContainer.end(); anIter++){ + theName += QString(" %1").arg(*anIter); + } + return aMapIndex.Extent(); + } + } + return -1; + } + + + int GetNameOfSelectedElements(SalomeApp_SelectionMgr *theMgr, QString& theName) + { + theName = ""; + SALOME_ListIO selected; theMgr->selectedObjects( selected ); + + if( selected.Extent() == 1){ + Handle(SALOME_InteractiveObject) anIO = selected.First(); + return GetNameOfSelectedElements(theMgr,anIO,theName); + } + return -1; + } + + int GetSelected(SalomeApp_SelectionMgr* theMgr, + TColStd_IndexedMapOfInteger& theMap, + const bool theIsElement) + { + theMap.Clear(); + SALOME_ListIO selected; theMgr->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) + { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO->hasEntry() ) { + theMgr->GetIndexes( anIO, theMap ); + } + } + return theMap.Extent(); + } + + + int GetEdgeNodes( SalomeApp_SelectionMgr* theMgr, int& theId1, int& theId2 ) + { + SALOME_ListIO selected; theMgr->selectedObjects( selected ); + + if ( selected.Extent() != 1 ) + return -1; + + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO.IsNull() || !anIO->hasEntry() ) + return -1; + + SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() ); + if ( anActor == 0 ) + return -1; + + TColStd_IndexedMapOfInteger aMapIndex; + theMgr->GetIndexes( anIO, aMapIndex ); + if ( aMapIndex.Extent() != 2 ) + return -1; + + int anObjId = -1, anEdgeNum = -1; + for ( int i = 1; i <= aMapIndex.Extent(); i++ ) { + int aVal = aMapIndex( i ); + if ( aVal > 0 ) + anObjId = aVal; + else + anEdgeNum = abs( aVal ); + } + + if ( anObjId == -1 || anEdgeNum == -1 ) + return -1; + + return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1; + } + + void SetControlsPrecision( const long theVal ) + { + if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() ) + { + vtkRenderer *aRenderer = aWnd->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + + while ( vtkActor *anAct = aCollection->GetNextActor()) + { + if ( SMESH_Actor *anActor = dynamic_cast( anAct ) ) + { + anActor->SetControlsPrecision( theVal ); + anActor->SetControlMode( anActor->GetControlMode() ); + } + } + + } + } +} diff --git a/src/SMESH_I/SMESH_1D_Algo_i.cxx b/src/SMESH_I/SMESH_1D_Algo_i.cxx new file mode 100644 index 000000000..06f621dc9 --- /dev/null +++ b/src/SMESH_I/SMESH_1D_Algo_i.cxx @@ -0,0 +1,89 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_1D_Algo_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESH_1D_Algo_i.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * SMESH_1D_Algo_i::SMESH_1D_Algo_i + * + * Constructor + */ +//============================================================================= + +SMESH_1D_Algo_i::SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) +{ + MESSAGE( "SMESH_1D_Algo_i::SMESH_1D_Algo_i" ); +} + +//============================================================================= +/*! + * SMESH_1D_Algo_i::~SMESH_1D_Algo_i + * + * Destructor + */ +//============================================================================= + +SMESH_1D_Algo_i::~SMESH_1D_Algo_i() +{ + MESSAGE( "SMESH_1D_Algo_i::~SMESH_1D_Algo_i" ); +} + +//================================================================================ +/*! + * \brief Verify whether algorithm supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean SMESH_1D_Algo_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + + + + + + + + + + + + + + diff --git a/src/SMESH_I/SMESH_1D_Algo_i.hxx b/src/SMESH_I/SMESH_1D_Algo_i.hxx new file mode 100644 index 000000000..1112a4019 --- /dev/null +++ b/src/SMESH_I/SMESH_1D_Algo_i.hxx @@ -0,0 +1,56 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_1D_Algo_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_1D_ALGO_I_HXX_ +#define _SMESH_1D_ALGO_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) + +#include "SMESH_Algo_i.hxx" + +// ====================================================== +// Generic 1D algorithm +// ====================================================== +class SMESH_1D_Algo_i: + public virtual POA_SMESH::SMESH_1D_Algo, + public virtual SMESH_Algo_i +{ +protected: + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA ); + +public: + // Destructor + virtual ~SMESH_1D_Algo_i(); + + // Verify whether algorithm supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/SMESH_I/SMESH_2D_Algo_i.cxx b/src/SMESH_I/SMESH_2D_Algo_i.cxx new file mode 100644 index 000000000..00744eea4 --- /dev/null +++ b/src/SMESH_I/SMESH_2D_Algo_i.cxx @@ -0,0 +1,75 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_2D_Algo_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESH_2D_Algo_i.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * SMESH_2D_Algo_i::SMESH_2D_Algo_i + * + * Constructor + */ +//============================================================================= + +SMESH_2D_Algo_i::SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) +{ + MESSAGE( "SMESH_2D_Algo_i::SMESH_2D_Algo_i" ); +} + +//============================================================================= +/*! + * SMESH_2D_Algo_i::~SMESH_2D_Algo_i + * + * Destructor + */ +//============================================================================= + +SMESH_2D_Algo_i::~SMESH_2D_Algo_i() +{ + MESSAGE( "SMESH_2D_Algo_i::~SMESH_2D_Algo_i" ); +} + +//================================================================================ +/*! + * \brief Verify whether algorithm supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean SMESH_2D_Algo_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} diff --git a/src/SMESH_I/SMESH_2D_Algo_i.hxx b/src/SMESH_I/SMESH_2D_Algo_i.hxx new file mode 100644 index 000000000..58664c9cf --- /dev/null +++ b/src/SMESH_I/SMESH_2D_Algo_i.hxx @@ -0,0 +1,56 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_2D_Algo_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_2D_ALGO_I_HXX_ +#define _SMESH_2D_ALGO_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) + +#include "SMESH_Algo_i.hxx" + +// ====================================================== +// Generic 2D algorithm +// ====================================================== +class SMESH_2D_Algo_i: + public virtual POA_SMESH::SMESH_2D_Algo, + public virtual SMESH_Algo_i +{ +protected: + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA ); + +public: + // Destructor + virtual ~SMESH_2D_Algo_i(); + + // Verify whether algorithm supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/SMESH_I/SMESH_3D_Algo_i.cxx b/src/SMESH_I/SMESH_3D_Algo_i.cxx new file mode 100644 index 000000000..14276fe12 --- /dev/null +++ b/src/SMESH_I/SMESH_3D_Algo_i.cxx @@ -0,0 +1,76 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_3D_Algo_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESH_3D_Algo_i.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * SMESH_3D_Algo_i::SMESH_3D_Algo_i + * + * Constructor + */ +//============================================================================= + +SMESH_3D_Algo_i::SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) +{ + MESSAGE( "SMESH_3D_Algo_i::SMESH_3D_Algo_i" ); +} + +//============================================================================= +/*! + * SMESH_3D_Algo_i::~SMESH_3D_Algo_i + * + * Destructor + */ +//============================================================================= + +SMESH_3D_Algo_i::~SMESH_3D_Algo_i() +{ + MESSAGE( "SMESH_3D_Algo_i::~SMESH_3D_Algo_i" ); +} + +//================================================================================ +/*! + * \brief Verify whether algorithm supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean SMESH_3D_Algo_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} + diff --git a/src/SMESH_I/SMESH_3D_Algo_i.hxx b/src/SMESH_I/SMESH_3D_Algo_i.hxx new file mode 100644 index 000000000..8589e166a --- /dev/null +++ b/src/SMESH_I/SMESH_3D_Algo_i.hxx @@ -0,0 +1,56 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_3D_Algo_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_3D_ALGO_I_HXX_ +#define _SMESH_3D_ALGO_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) + +#include "SMESH_Algo_i.hxx" + +// ====================================================== +// Generic 3D algorithm +// ====================================================== +class SMESH_3D_Algo_i: + public virtual POA_SMESH::SMESH_3D_Algo, + public virtual SMESH_Algo_i +{ +protected: + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA ); + +public: + // Destructor + virtual ~SMESH_3D_Algo_i(); + + // Verify whether algorithm supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx new file mode 100644 index 000000000..42fac7d5d --- /dev/null +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -0,0 +1,268 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Mesh_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_MESH_I_HXX_ +#define _SMESH_MESH_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) +#include CORBA_CLIENT_HEADER(GEOM_Gen) +#include CORBA_CLIENT_HEADER(MED) + +#include "SMESH_Hypothesis.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMesh_i.hxx" +#include "SMESH_subMesh.hxx" + +#include "SALOME_GenericObj_i.hh" + +class SMESH_Gen_i; +class SMESH_GroupBase_i; + +#include + +class SMESH_Mesh_i: + public virtual POA_SMESH::SMESH_Mesh, + public virtual SALOME::GenericObj_i +{ + SMESH_Mesh_i(); + SMESH_Mesh_i(const SMESH_Mesh_i&); +public: + SMESH_Mesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* myGen_i, + CORBA::Long studyId ); + + virtual ~SMESH_Mesh_i(); + + // --- CORBA + void SetShape( GEOM::GEOM_Object_ptr theShapeObject ) + throw (SALOME::SALOME_Exception); + + GEOM::GEOM_Object_ptr GetShapeToMesh() + throw (SALOME::SALOME_Exception); + + SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp) + throw (SALOME::SALOME_Exception); + + SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp) + throw (SALOME::SALOME_Exception); + + SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName) + throw (SALOME::SALOME_Exception); + + void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_GroupOnGeom_ptr CreateGroupFromGEOM(SMESH::ElementType theElemType, + const char* theName, + GEOM::GEOM_Object_ptr theGeomObj ) + throw (SALOME::SALOME_Exception); + + void RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) + throw (SALOME::SALOME_Exception); + + void RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, + const char* theName ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, + const char* theName ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, + const char* theName ) + throw (SALOME::SALOME_Exception); + +// SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet) +// throw (SALOME::SALOME_Exception); + + SMESH::log_array* GetLog(CORBA::Boolean clearAfterGet) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_MeshEditor_ptr GetMeshEditor(); + + void ClearLog() + throw (SALOME::SALOME_Exception); + + CORBA::Long GetId() + throw (SALOME::SALOME_Exception); + + CORBA::Long GetStudyId() + throw (SALOME::SALOME_Exception); + + // --- C++ interface + + void SetImpl(::SMESH_Mesh* impl); + ::SMESH_Mesh& GetImpl(); // :: force no namespace here + + SMESH_Gen_i* GetGen() { return _gen_i; } + + int ImportUNVFile( const char* theFileName ) + throw (SALOME::SALOME_Exception); + + int ImportSTLFile( const char* theFileName ) + throw (SALOME::SALOME_Exception); + + /*! + * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value + */ + SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName ) + throw (SALOME::SALOME_Exception); + + void ExportToMED( const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion ) + throw (SALOME::SALOME_Exception); + void ExportMED( const char* file, CORBA::Boolean auto_groups ) + throw (SALOME::SALOME_Exception); + + void ExportDAT( const char* file ) + throw (SALOME::SALOME_Exception); + void ExportUNV( const char* file ) + throw (SALOME::SALOME_Exception); + void ExportSTL( const char* file, const bool isascii ) + throw (SALOME::SALOME_Exception); + + SALOME_MED::MESH_ptr GetMEDMesh() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbNodes() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbElements() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbEdges() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbFaces() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbTriangles() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbQuadrangles() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbPolygons() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbVolumes() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbTetras() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbHexas() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbPyramids() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbPrisms() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbPolyhedrons() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbSubMesh() + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetElementsId() + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetNodesId() + throw (SALOME::SALOME_Exception); + + SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem ) + throw (SALOME::SALOME_Exception); + + char* Dump(); + + // Internal methods not available through CORBA + // They are called by corresponding interface methods + SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp); + + SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp); + + int importMEDFile( const char* theFileName, const char* theMeshName ); + + SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject ); + + void removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh, + GEOM::GEOM_Object_ptr theSubShapeObject ); + + SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType theElemType, + const char* theName, + const TopoDS_Shape& theShape = TopoDS_Shape()); + + void removeGroup( const int theId ); + + SMESH::SMESH_subMesh_ptr getSubMesh(int shapeID); + // return an existing subMesh object for the shapeID. shapeID == submeshID. + + const map& getGroups() { return _mapGroups; } + // return an existing group object. + + virtual SMESH::long_array* GetIDs(); + + map _mapSubMesh_i; //NRI + map _mapSubMesh; //NRI + +private: + static int myIdGenerator; + ::SMESH_Mesh* _impl; // :: force no namespace here + SMESH_Gen_i* _gen_i; + int _id; // id given by creator (unique within the creator instance) + int _studyId; + map _mapSubMeshIor; + map _mapGroups; + map _mapHypo; +}; + +#endif + diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx new file mode 100644 index 000000000..f8ade30f5 --- /dev/null +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -0,0 +1,487 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_subMesh_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESH_subMesh_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Mesh_i.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" +#include "OpUtil.hxx" +#include "Utils_ExceptHandlers.hxx" + +#include +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_subMesh_i::SMESH_subMesh_i() + : SALOME::GenericObj_i( PortableServer::POA::_nil() ) +{ + MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use"); + ASSERT(0); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ) + : SALOME::GenericObj_i( thePOA ) +{ + MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i"); + _gen_i = gen_i; + _mesh_i = mesh_i; + _localId = localId; + thePOA->activate_object( this ); + // **** +} +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_subMesh_i::~SMESH_subMesh_i() +{ + MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i"); + // **** +} + +//======================================================================= +//function : getSubMeshes +//purpose : for a submesh on shape to which elements are not bound directly, +// return submeshes containing elements +//======================================================================= + +typedef list TListOfSubMeshes; + +bool getSubMeshes(::SMESH_subMesh* theSubMesh, + TListOfSubMeshes& theSubMeshList) +{ + int size = theSubMeshList.size(); + + SMESH_Mesh* aMesh = theSubMesh->GetFather(); + SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS(); + SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS(); + + // nodes can be bound to either vertex, edge, face or solid_or_shell + TopoDS_Shape aShape = theSubMesh->GetSubShape(); + switch ( aShape.ShapeType() ) + { + case TopAbs_SOLID: { + // add submesh of solid itself + aSubMeshDS = aMeshDS->MeshElements( aShape ); + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); + // and of the first shell + TopExp_Explorer exp( aShape, TopAbs_SHELL ); + if ( exp.More() ) { + aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); + } + break; + } + case TopAbs_WIRE: + case TopAbs_COMPOUND: + case TopAbs_COMPSOLID: { + // call getSubMeshes() for sub-shapes + list shapeList; + shapeList.push_back( aShape ); + list::iterator sh = shapeList.begin(); + for ( ; sh != shapeList.end(); ++sh ) { + for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) { + ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ); + if ( aSubMesh ) + getSubMeshes( aSubMesh, theSubMeshList ); + else + // no submesh for a compound inside compound + shapeList.push_back( it.Value() ); + } + } + // return only unique submeshes + set smSet; + TListOfSubMeshes::iterator sm = theSubMeshList.begin(); + while ( sm != theSubMeshList.end() ) { + if ( !smSet.insert( *sm ).second ) + sm = theSubMeshList.erase( sm ); + else + ++sm; + } + break; + } + } + return size < theSubMeshList.size(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_subMesh_i::GetNumberOfElements() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetNumberOfElements"); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return 0; + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; + + // volumes are bound to shell + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); + } + return nbElems; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetNumberOfNodes"); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return 0; + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + set nodeIds; + + // nodes are bound to shell instead of solid + TListOfSubMeshes smList; + if ( all && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + { + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } + return nodeIds.size(); + } + + if ( aSubMeshDS == NULL ) + return 0; + + if ( all ) { // all nodes of submesh elements + SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + return nodeIds.size(); + } + + return aSubMeshDS->NbNodes(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetElementsId() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetElementsId"); + SMESH::long_array_var aResult = new SMESH::long_array(); + + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return aResult._retn(); + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; + TListOfSubMeshes smList; + if ( nbElems ) + smList.push_back( aSubMeshDS ); + + // volumes are bound to shell + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); + } + + aResult->length( nbElems ); + if ( nbElems ) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( int i = 0; sm != smList.end(); sm++ ) + { + SMDS_ElemIteratorPtr anIt = (*sm)->GetElements(); + for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) + aResult[i] = anIt->next()->GetID(); + } + } + return aResult._retn(); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType ) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetElementsByType"); + SMESH::long_array_var aResult = new SMESH::long_array(); + + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return aResult._retn(); + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + // PAL5440, return all nodes belonging to elements of submesh + set nodeIds; + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; + + // volumes may be bound to shell instead of solid + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + { + if ( theElemType == SMESH::NODE ) + { + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } + else + { + nbElems += (*sm)->NbElements(); + } + } + aSubMeshDS = 0; + } + else + { + if ( nbElems ) + smList.push_back( aSubMeshDS ); + } + + if ( theElemType == SMESH::NODE && aSubMeshDS ) + { + SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } + + if ( theElemType == SMESH::NODE ) + aResult->length( nodeIds.size() ); + else + aResult->length( nbElems ); + + int i = 0, n = aResult->length(); + + if ( theElemType == SMESH::NODE && !nodeIds.empty() ) { + set::iterator idIt = nodeIds.begin(); + for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ ) + aResult[i] = *idIt; + } + + if ( theElemType != SMESH::NODE ) { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( i = 0; sm != smList.end(); sm++ ) + { + aSubMeshDS = *sm; + SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); + while ( i < n && anIt->more() ) { + const SMDS_MeshElement* anElem = anIt->next(); + if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) + aResult[i++] = anElem->GetID(); + } + } + } + + aResult->length( i ); + + return aResult._retn(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetNodesId() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetNodesId"); + SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE ); + return aResult._retn(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetFather"); + return _mesh_i->_this(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_subMesh_i::GetId() +{ + MESSAGE("SMESH_subMesh_i::GetId"); + return _localId; +} + +//======================================================================= +//function : GetSubShape +//purpose : +//======================================================================= + +GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + GEOM::GEOM_Object_var aShapeObj; + try { + if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) { + TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape(); + if ( !S.IsNull() ) + aShapeObj = _gen_i->ShapeToGeomObject( S ); + } + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + return aShapeObj._retn(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily() + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh(); + + SALOME_MED::Family_array_var families = + MEDMesh->getFamilies(SALOME_MED::MED_NODE); + + for ( int i = 0; i < families->length(); i++ ) { + if ( families[i]->getIdentifier() == ( _localId ) ) + return families[i]; + } + + return SALOME_MED::FAMILY::_nil(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESH::long_array* SMESH_subMesh_i::GetIDs() +{ + SMESH::long_array_var aResult = GetElementsId(); + return aResult._retn(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem ) + throw (SALOME::SALOME_Exception) +{ + return GetFather()->GetElementType( id, iselem ); +} diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx new file mode 100644 index 000000000..e8d84b37e --- /dev/null +++ b/src/SMESH_I/SMESH_subMesh_i.hxx @@ -0,0 +1,93 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_subMesh_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_SUBMESH_I_HXX_ +#define _SMESH_SUBMESH_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) +#include CORBA_CLIENT_HEADER(GEOM_Gen) +#include CORBA_CLIENT_HEADER(MED) + +#include "SALOME_GenericObj_i.hh" + +class SMESH_Gen_i; +class SMESH_Mesh_i; + +class SMESH_subMesh_i: + public virtual POA_SMESH::SMESH_subMesh, + public virtual SALOME::GenericObj_i +{ +public: + SMESH_subMesh_i(); + SMESH_subMesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ); + ~SMESH_subMesh_i(); + + CORBA::Long GetNumberOfElements() + throw (SALOME::SALOME_Exception); + + CORBA::Long GetNumberOfNodes( CORBA::Boolean all ) + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetElementsId() + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) + throw (SALOME::SALOME_Exception); + + SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem ) + throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetNodesId() + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Mesh_ptr GetFather() + throw (SALOME::SALOME_Exception); + + GEOM::GEOM_Object_ptr GetSubShape() + throw (SALOME::SALOME_Exception); + + CORBA::Long GetId(); + + SALOME_MED::FAMILY_ptr GetFamily() + throw (SALOME::SALOME_Exception); + + virtual SMESH::long_array* GetIDs(); + + SMESH_Mesh_i* _mesh_i; //NRI + +protected: + SMESH_Gen_i* _gen_i; + int _localId; +}; + +#endif diff --git a/src/SMESH_SWIG/Makefile.in b/src/SMESH_SWIG/Makefile.in new file mode 100644 index 000000000..df7e19a17 --- /dev/null +++ b/src/SMESH_SWIG/Makefile.in @@ -0,0 +1,120 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Nicolas REJNERI, Paul RASCLE +# Module : SMESH +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# Libraries targets + +LIB = libSMESH_Swigcmodule.la +LIB_SRC = + +SWIG_DEF = libSMESH_Swig.i +EXPORT_PYSCRIPTS = libSMESH_Swig.py \ + smesh.py \ + batchmode_smesh.py \ + batchmode_mefisto.py \ + ex00_all.py \ + ex01_cube2build.py \ + ex02_cube2primitive.py \ + ex03_cube2partition.py \ + ex04_cube5tetraHexa.py \ + ex05_hole1build.py \ + ex06_hole1boolean.py \ + ex07_hole1partition.py \ + ex08_hole2build.py \ + ex09_grid4build.py \ + ex10_grid4geometry.py \ + ex11_grid3partition.py \ + ex12_grid17partition.py \ + ex13_hole1partial.py \ + ex14_cyl1holed.py \ + ex15_cyl2geometry.py \ + ex16_cyl2complementary.py \ + ex17_dome1.py \ + ex18_dome2.py \ + ex19_sphereINcube.py \ + SMESH_test.py\ + SMESH_test0.py\ + SMESH_test1.py \ + SMESH_test2.py \ + SMESH_test3.py \ + SMESH_test4.py \ + SMESH_test5.py \ + SMESH_mechanic.py \ + SMESH_mechanic_tetra.py \ + SMESH_mechanic_editor.py \ + SMESH_fixation.py \ + SMESH_fixation_hexa.py \ + SMESH_fixation_tetra.py \ + SMESH_box_tetra.py \ + SMESH_box2_tetra.py \ + SMESH_box3_tetra.py \ + SMESH_flight_skin.py \ + SMESH_Partition1_tetra.py\ + SMESH_controls.py \ + SMESH_freebord.py \ + SMESH_blocks.py \ + SMESH_BelongToGeom.py \ + SMESH_GroupFromGeom2.py \ + SMESH_box.py \ + SMESH_demo_hexa2_upd.py \ + SMESH_hexaedre.py \ + SMESH_Sphere.py \ + SMESH_GroupFromGeom.py \ + SMESH_Nut.py \ + SMESH_GroupLyingOnGeom.py \ + PAL_MESH_041_mesh.py \ + PAL_MESH_043_2D.py \ + PAL_MESH_043_3D.py \ + SMESH_reg.py + +LIB_CLIENT_IDL = SALOMEDS.idl \ + SALOME_Exception.idl \ + GEOM_Gen.idl \ + SMESH_Gen.idl \ + SMESH_Mesh.idl \ + SMESH_Hypothesis.idl \ + SMESH_BasicHypothesis.idl \ + SMESH_Group.idl \ + SALOME_ModuleCatalog.idl \ + SALOME_Component.idl \ + SALOME_GenericObj.idl \ + MED.idl \ + SALOME_Comm.idl + +EXPORT_SHAREDPYSCRIPTS=SMESH_shared_modules.py + +CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -DHAVE_CONFIG_H +LIBS+= $(PYTHON_LIBS) +LDFLAGS+= -lSMESH -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeGenericObj + +@CONCLUDE@ diff --git a/src/SMESH_SWIG/SMESH_test.py b/src/SMESH_SWIG/SMESH_test.py new file mode 100644 index 000000000..d2385f3a9 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_test.py @@ -0,0 +1,200 @@ +# SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +# +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : SMESH_test.py +# Module : SMESH + +import salome +import geompy +import smeshpy + +import SMESH +import StdMeshers + +# ---- define a box + +box = geompy.MakeBox(0., 0., 0., 100., 200., 300.) +idb = geompy.addToStudy(box, "box") + +# ---- add first face of box in study + +subShapeList = geompy.SubShapeAll(box, geompy.ShapeType["FACE"]) +face = subShapeList[0] +name = geompy.SubShapeName(face, box) +idf = geompy.addToStudyInFather(box, face, name) + +# ---- add shell from box in study + +subShellList = geompy.SubShapeAll(box, geompy.ShapeType["SHELL"]) +shell = subShellList[0] +name = geompy.SubShapeName(shell, box) +ids = geompy.addToStudyInFather(box, shell, name) + +# ---- add first edge of face in study + +edgeList = geompy.SubShapeAll(face, geompy.ShapeType["EDGE"]) +edge = edgeList[0]; +name = geompy.SubShapeName(edge, face) +ide = geompy.addToStudyInFather(face, edge, name) + +# ---- launch SMESH, init a Mesh with the box + +gen = smeshpy.smeshpy() +mesh = gen.CreateMesh(idb) + +print "-------------------------- create Hypothesis" + +print "-------------------------- LocalLength" + +hypo1 = gen.CreateHypothesis("LocalLength", "libStdMeshersEngine.so") +print hypo1.GetName() +print hypo1.GetId() +print hypo1.GetLength() +hypo1.SetLength(100) +print hypo1.GetLength() + +print "-------------------------- bidon" + +hyp3 = gen.CreateHypothesis("bidon", "") + +print "-------------------------- NumberOfSegments" + +hypo3 = gen.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hypo3.SetNumberOfSegments(7) +print hypo3.GetName() +print hypo3.GetNumberOfSegments() +print hypo3.GetId() + +print "-------------------------- MaxElementArea" + +hypo4 = gen.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hypo4.SetMaxElementArea(5000) +print hypo4.GetName() +print hypo4.GetMaxElementArea() +print hypo4.GetId() + +print "-------------------------- Regular_1D" + +algo_1 = gen.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +print algo_1.GetName() +print algo_1.GetId() +listHyp = algo_1.GetCompatibleHypothesis() +for hyp in listHyp: + print hyp +print algo_1.GetId() + +print "-------------------------- MEFISTO_2D" + +algo_2 = gen.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +print algo_2.GetName() +print algo_2.GetId() +listHyp = algo_2.GetCompatibleHypothesis() +for hyp in listHyp: + print hyp +print algo_2.GetId() + +print "-------------------------- add hypothesis to edge" + +edge = salome.IDToObject(ide) +submesh = mesh.GetSubMesh(edge, "SubMeshEdge") +ret = mesh.AddHypothesis(edge,algo_1) +print ret +ret = mesh.AddHypothesis(edge,hypo1) +print ret + +##print "-------------------------- compute edge" +##ret=gen.Compute(mesh,ide) +##print ret +##log=mesh.GetLog(1); +##for a in log: +## print a + +print "-------------------------- add hypothesis to box" + +box = salome.IDToObject(idb) +submesh = mesh.GetSubMesh(box, "SubMeshBox") +ret = mesh.AddHypothesis(box,algo_1) +print ret +ret = mesh.AddHypothesis(box,hypo1) +print ret +ret = mesh.AddHypothesis(box,algo_2) +print ret +ret = mesh.AddHypothesis(box,hypo4) +print ret + +print "-------------------------- compute face" + +ret = gen.Compute(mesh,idf) +print ret +log = mesh.GetLog(0) # 0 - GetLog without ClearLog after, else if 1 - ClearLog after +for a in log: + print "-------" + ii = 0 + ir = 0 + comType = a.commandType + if comType == 0: + for i in range(a.number): + ind = a.indexes[ii] + ii = ii+1 + r1 = a.coords[ir] + ir = ir+1 + r2 = a.coords[ir] + ir = ir+1 + r3 = a.coords[ir] + ir = ir+1 + print "AddNode %i - %g %g %g" % (ind, r1, r2, r3) + elif comType == 1: + for i in range(a.number): + ind = a.indexes[ii] + ii = ii+1 + i1 = a.indexes[ii] + ii = ii+1 + i2 = a.indexes[ii] + ii = ii+1 + print "AddEdge %i - %i %i" % (ind, i1, i2) + elif comType == 2: + for i in range(a.number): + ind = a.indexes[ii] + ii = ii+1 + i1 = a.indexes[ii] + ii = ii+1 + i2 = a.indexes[ii] + ii = ii+1 + i3 = a.indexes[ii] + ii = ii+1 + print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3) + +##print "-------------------------- compute box" +##ret=gen.Compute(mesh,idb) +##print ret +##log=mesh.GetLog(1); +##print log + +##shell=salome.IDToObject(ids) +##submesh=mesh.GetElementsOnShape(shell) +##ret=mesh.AddHypothesis(shell,algo_1) +##print ret +##ret=mesh.AddHypothesis(shell,hypo1) +##print ret +##ret=gen.Compute(mesh,ids) +##print ret diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx new file mode 100644 index 000000000..a3ed4f11a --- /dev/null +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -0,0 +1,1068 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Hexa_3D.cxx +// Moved here from SMESH_Hexa_3D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_Hexa_3D.hxx" +#include "StdMeshers_Quadrangle_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMesh.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMDS_VolumeOfNodes.hxx" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + +//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f +#include "StdMeshers_Penta_3D.hxx" + +static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); +//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); + _name = "Hexa_3D"; +// _shapeType = TopAbs_SOLID; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type +// MESSAGE("_shapeType octal " << oct << _shapeType); + for (int i = 0; i < 6; i++) + _quads[i] = 0; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() +{ + MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); + for (int i = 0; i < 6; i++) + StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Hexa_3D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis"); + + bool isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + + // nothing to check + + return isOk; +} + +//======================================================================= +//function : findIJ +//purpose : return i,j of the node +//======================================================================= + +static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J) +{ + I = J = 0; + const SMDS_FacePosition* fpos = + static_cast(node->GetPosition().get()); + if ( ! fpos ) return false; + gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() ); + + double minDist = DBL_MAX; + int nbhoriz = Min(quad->nbPts[0], quad->nbPts[2]); + int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]); + for (int i = 1; i < nbhoriz - 1; i++) { + for (int j = 1; j < nbvertic - 1; j++) { + int ij = j * nbhoriz + i; + gp_Pnt2d uv2( quad->uv_grid[ij].u, quad->uv_grid[ij].v ); + double dist = uv.SquareDistance( uv2 ); + if ( dist < minDist ) { + minDist = dist; + I = i; + J = j; + } + } + } + return true; +} + +//============================================================================= +/*! + * Hexahedron mesh on hexaedron like form + * -0. - shape and face mesh verification + * -1. - identify faces and vertices of the "cube" + * -2. - Algorithm from: + * "Application de l'interpolation transfinie à la création de maillages + * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres + * et hexaedres déformés." + * Alain PERONNET - 8 janvier 1999 + */ +//============================================================================= + +bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape)throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + MESSAGE("StdMeshers_Hexa_3D::Compute"); + //bool isOk = false; + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS(); + + // 0. - shape and face mesh verification + // 0.1 - shape must be a solid (or a shell) with 6 faces + //MESSAGE("---"); + + vector < SMESH_subMesh * >meshFaces; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) + { + SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT(aSubMesh); + meshFaces.push_back(aSubMesh); + } + if (meshFaces.size() != 6) + { + SCRUTE(meshFaces.size()); +// ASSERT(0); + return false; + } + + // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) + //MESSAGE("---"); + + for (int i = 0; i < 6; i++) + { + TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); + string algoName = algo->GetName(); + bool isAllQuad = false; + if (algoName == "Quadrangle_2D") { + SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); + if ( sm ) { + isAllQuad = true; + SMDS_ElemIteratorPtr eIt = sm->GetElements(); + while ( isAllQuad && eIt->more() ) + isAllQuad = ( eIt->next()->NbNodes() == 4 ); + } + } + if ( ! isAllQuad ) { + //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f + bool bIsOk; + // + bIsOk=ComputePentahedralMesh(aMesh, aShape); + if (bIsOk) { + return true; + } + //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t + SCRUTE(algoName); + // ASSERT(0); + return false; + } + StdMeshers_Quadrangle_2D *quadAlgo = + dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); + ASSERT(quadAlgo); + try + { + _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace); + // *** to delete after usage + } + catch(SALOME_Exception & S_ex) + { + // *** delete _quads + // *** throw exception + // ASSERT(0); + return false; + } + + // 0.2.1 - number of points on the opposite edges must be the same + if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || + _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) + { + MESSAGE("different number of points on the opposite edges of face " << i); + // ASSERT(0); + return false; + } + } + + // 1. - identify faces and vertices of the "cube" + // 1.1 - ancestor maps vertex->edges in the cube + //MESSAGE("---"); + + TopTools_IndexedDataMapOfShapeListOfShape MS; + TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); + + // 1.2 - first face is choosen as face Y=0 of the unit cube + //MESSAGE("---"); + + const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); + const TopoDS_Face & F = TopoDS::Face(aFace); + + // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 + //MESSAGE("---"); + + int i = 0; + TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = + (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + + if (isForward) + { + _cube.V000 = VFirst; // will be (0,0,0) on the unit cube + _cube.V100 = VLast; // will be (1,0,0) on the unit cube + } + else + { + _cube.V000 = VLast; + _cube.V100 = VFirst; + } + + i = 1; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V101 = VLast; // will be (1,0,1) on the unit cube + else + _cube.V101 = VFirst; + + i = 2; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V001 = VLast; // will be (0,0,1) on the unit cube + else + _cube.V001 = VFirst; + + // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) + // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) + // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) + // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) + //MESSAGE("---"); + + TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS); + ASSERT(!E_0Y0.IsNull()); + + TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS); + ASSERT(!E_1Y0.IsNull()); + + TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS); + ASSERT(!E_1Y1.IsNull()); + + TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS); + ASSERT(!E_0Y1.IsNull()); + + // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 + //MESSAGE("---"); + + TopExp::Vertices(E_0Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V000)) + _cube.V010 = VLast; + else + _cube.V010 = VFirst; + + TopExp::Vertices(E_1Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V100)) + _cube.V110 = VLast; + else + _cube.V110 = VFirst; + + TopExp::Vertices(E_1Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V101)) + _cube.V111 = VLast; + else + _cube.V111 = VFirst; + + TopExp::Vertices(E_0Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V001)) + _cube.V011 = VLast; + else + _cube.V011 = VFirst; + + // 1.6 - find remaining faces given 4 vertices + //MESSAGE("---"); + + _indY0 = 0; + _cube.quad_Y0 = _quads[_indY0]; + + _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V010, _cube.V011, _cube.V110, _cube.V111); + _cube.quad_Y1 = _quads[_indY1]; + + _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V010, _cube.V100, _cube.V110); + _cube.quad_Z0 = _quads[_indZ0]; + + _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V001, _cube.V011, _cube.V101, _cube.V111); + _cube.quad_Z1 = _quads[_indZ1]; + + _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V001, _cube.V010, _cube.V011); + _cube.quad_X0 = _quads[_indX0]; + + _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V100, _cube.V101, _cube.V110, _cube.V111); + _cube.quad_X1 = _quads[_indX1]; + + //MESSAGE("---"); + + // 1.7 - get convertion coefs from face 2D normalized to 3D normalized + + Conv2DStruct cx0; // for face X=0 + Conv2DStruct cx1; // for face X=1 + Conv2DStruct cy0; + Conv2DStruct cy1; + Conv2DStruct cz0; + Conv2DStruct cz1; + + GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(), + _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0); + GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(), + _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1); + GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0); + GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(), + _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1); + GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0); + GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), + _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1); + + // 1.8 - create a 3D structure for normalized values + + //MESSAGE("---"); + int nbx = _cube.quad_Z0->nbPts[0]; + if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1]; + + int nby = _cube.quad_X0->nbPts[0]; + if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1]; + + int nbz = _cube.quad_Y0->nbPts[0]; + if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1]; + + int i1, j1, nbxyz = nbx * nby * nbz; + Point3DStruct *np = new Point3DStruct[nbxyz]; + + // 1.9 - store node indexes of faces + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); + + faceQuadStruct *quad = _cube.quad_X0; + int i = 0; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face + int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_X1; + int i = nbx - 1; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face + int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Y0; + int j = 0; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face + int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Y1; + int j = nby - 1; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face + int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Z0; + int k = 0; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face + int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Z1; + int k = nbz - 1; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face + int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + // 2.0 - for each node of the cube: + // - get the 8 points 3D = 8 vertices of the cube + // - get the 12 points 3D on the 12 edges of the cube + // - get the 6 points 3D on the 6 faces with their ID + // - compute the point 3D + // - store the point 3D in SMESHDS, store its ID in 3D structure + + int shapeID = meshDS->ShapeToIndex( aShape ); + + Pt3 p000, p001, p010, p011, p100, p101, p110, p111; + Pt3 px00, px01, px10, px11; + Pt3 p0y0, p0y1, p1y0, p1y1; + Pt3 p00z, p01z, p10z, p11z; + Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; + + GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + for (int i = 1; i < nbx - 1; i++) + { + for (int j = 1; j < nby - 1; j++) + { + for (int k = 1; k < nbz - 1; k++) + { + // *** seulement maillage regulier + // 12 points on edges + GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); + + // 12 points on faces + GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); + GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); + + int ijk = k * nbx * nby + j * nbx + i; + double x = double (i) / double (nbx - 1); // *** seulement + double y = double (j) / double (nby - 1); // *** maillage + double z = double (k) / double (nbz - 1); // *** regulier + + Pt3 X; + for (int i = 0; i < 3; i++) + { + X[i] = + (1 - x) * p0yz[i] + x * p1yz[i] + + (1 - y) * px0z[i] + y * px1z[i] + + (1 - z) * pxy0[i] + z * pxy1[i] + - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) + - x * ((1 - y) * p10z[i] + y * p11z[i]) + - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) + - y * ((1 - z) * px10[i] + z * px11[i]) + - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) + - z * ((1 - x) * p0y1[i] + x * p1y1[i]) + + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) + + y * ((1 - z) * p010[i] + z * p011[i])) + + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) + + y * ((1 - z) * p110[i] + z * p111[i])); + } + + SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); + np[ijk].node = node; + meshDS->SetNodeInVolume(node, shapeID); + } + } + } + + // find orientation of furute volumes according to MED convention + vector< bool > forward( nbx * nby ); + SMDS_VolumeTool vTool; + for (int i = 0; i < nbx - 1; i++) + for (int j = 0; j < nby - 1; j++) + { + int n1 = j * nbx + i; + int n2 = j * nbx + i + 1; + int n3 = (j + 1) * nbx + i + 1; + int n4 = (j + 1) * nbx + i; + int n5 = nbx * nby + j * nbx + i; + int n6 = nbx * nby + j * nbx + i + 1; + int n7 = nbx * nby + (j + 1) * nbx + i + 1; + int n8 = nbx * nby + (j + 1) * nbx + i; + + SMDS_VolumeOfNodes tmpVol (np[n1].node,np[n2].node,np[n3].node,np[n4].node, + np[n5].node,np[n6].node,np[n7].node,np[n8].node); + vTool.Set( &tmpVol ); + forward[ n1 ] = vTool.IsForward(); + } + + //2.1 - for each node of the cube (less 3 *1 Faces): + // - store hexahedron in SMESHDS + MESSAGE("Storing hexahedron into the DS"); + for (int i = 0; i < nbx - 1; i++) + for (int j = 0; j < nby - 1; j++) + { + bool isForw = forward.at( j * nbx + i ); + for (int k = 0; k < nbz - 1; k++) + { + int n1 = k * nbx * nby + j * nbx + i; + int n2 = k * nbx * nby + j * nbx + i + 1; + int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; + int n4 = k * nbx * nby + (j + 1) * nbx + i; + int n5 = (k + 1) * nbx * nby + j * nbx + i; + int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; + int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; + int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; + + SMDS_MeshVolume * elt; + if ( isForw ) + elt = meshDS->AddVolume(np[n1].node, + np[n2].node, + np[n3].node, + np[n4].node, + np[n5].node, + np[n6].node, + np[n7].node, + np[n8].node); + else + elt = meshDS->AddVolume(np[n1].node, + np[n4].node, + np[n3].node, + np[n2].node, + np[n5].node, + np[n8].node, + np[n7].node, + np[n6].node); + + meshDS->SetMeshElementOnShape(elt, shapeID); + } + } + if ( np ) delete [] np; + //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, + int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS) +{ + int ijk = k * nbx * nby + j * nbx + i; + const SMDS_MeshNode * node = np[ijk].node; + p[0] = node->X(); + p[1] = node->Y(); + p[2] = node->Z(); + //MESSAGE(" "<&meshFaces, + const TopoDS_Vertex & V0, + const TopoDS_Vertex & V1, + const TopoDS_Vertex & V2, const TopoDS_Vertex & V3) +{ + //MESSAGE("StdMeshers_Hexa_3D::GetFaceIndex"); + int faceIndex = -1; + for (int i = 1; i < 6; i++) + { + const TopoDS_Shape & aFace = meshFaces[i]->GetSubShape(); + //const TopoDS_Face& F = TopoDS::Face(aFace); + TopTools_IndexedMapOfShape M; + TopExp::MapShapes(aFace, TopAbs_VERTEX, M); + bool verticesInShape = false; + if (M.Contains(V0)) + if (M.Contains(V1)) + if (M.Contains(V2)) + if (M.Contains(V3)) + verticesInShape = true; + if (verticesInShape) + { + faceIndex = i; + break; + } + } + ASSERT(faceIndex > 0); + //SCRUTE(faceIndex); + return faceIndex; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +TopoDS_Edge + StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const TopoDS_Face & aFace, + const TopoDS_Vertex & aVertex, + const TopTools_IndexedDataMapOfShapeListOfShape & MS) +{ + //MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace"); + TopTools_IndexedDataMapOfShapeListOfShape MF; + TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF); + const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex); + const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex); +// SCRUTE(ancestorsInSolid.Extent()); +// SCRUTE(ancestorsInFace.Extent()); + ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees) + ASSERT(ancestorsInFace.Extent() == 2); + + TopoDS_Edge E; + E.Nullify(); + TopTools_ListIteratorOfListOfShape its(ancestorsInSolid); + for (; its.More(); its.Next()) + { + TopoDS_Shape ancestor = its.Value(); + TopTools_ListIteratorOfListOfShape itf(ancestorsInFace); + bool isInFace = false; + for (; itf.More(); itf.Next()) + { + TopoDS_Shape ancestorInFace = itf.Value(); + if (ancestorInFace.IsSame(ancestor)) + { + isInFace = true; + break; + } + } + if (!isInFace) + { + E = TopoDS::Edge(ancestor); + break; + } + } + return E; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad, + const TopoDS_Shape & aShape, + const TopoDS_Vertex & V0, + const TopoDS_Vertex & V1, + const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv) +{ +// MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs"); + const TopoDS_Face & F = TopoDS::Face(aShape); + TopoDS_Edge E = quad.edge[0]; + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0); + TopoDS_Vertex VA, VB; + if (isForward) + { + VA = VFirst; + VB = VLast; + } + else + { + VA = VLast; + VB = VFirst; + } + int a1, b1, c1, a2, b2, c2; + if (VA.IsSame(V0)) + if (VB.IsSame(V1)) + { + a1 = 1; + b1 = 0; + c1 = 0; // x + a2 = 0; + b2 = 1; + c2 = 0; // y + } + else + { + ASSERT(VB.IsSame(V3)); + a1 = 0; + b1 = 1; + c1 = 0; // y + a2 = 1; + b2 = 0; + c2 = 0; // x + } + if (VA.IsSame(V1)) + if (VB.IsSame(V2)) + { + a1 = 0; + b1 = -1; + c1 = 1; // 1-y + a2 = 1; + b2 = 0; + c2 = 0; // x + } + else + { + ASSERT(VB.IsSame(V0)); + a1 = -1; + b1 = 0; + c1 = 1; // 1-x + a2 = 0; + b2 = 1; + c2 = 0; // y + } + if (VA.IsSame(V2)) + if (VB.IsSame(V3)) + { + a1 = -1; + b1 = 0; + c1 = 1; // 1-x + a2 = 0; + b2 = -1; + c2 = 1; // 1-y + } + else + { + ASSERT(VB.IsSame(V1)); + a1 = 0; + b1 = -1; + c1 = 1; // 1-y + a2 = -1; + b2 = 0; + c2 = 1; // 1-x + } + if (VA.IsSame(V3)) + if (VB.IsSame(V0)) + { + a1 = 0; + b1 = 1; + c1 = 0; // y + a2 = -1; + b2 = 0; + c2 = 1; // 1-x + } + else + { + ASSERT(VB.IsSame(V2)); + a1 = 1; + b1 = 0; + c1 = 0; // x + a2 = 0; + b2 = -1; + c2 = 1; // 1-y + } +// MESSAGE("X = " << c1 << "+ " << a1 << "*x + " << b1 << "*y"); +// MESSAGE("Y = " << c2 << "+ " << a2 << "*x + " << b2 << "*y"); + conv.a1 = a1; + conv.b1 = b1; + conv.c1 = c1; + conv.a2 = a2; + conv.b2 = b2; + conv.c2 = c2; + + int nbdown = quad.nbPts[0]; + int nbright = quad.nbPts[1]; + conv.ia = int (a1); + conv.ib = int (b1); + conv.ic = + int (c1 * a1 * a1) * (nbdown - 1) + int (c1 * b1 * b1) * (nbright - 1); + conv.ja = int (a2); + conv.jb = int (b2); + conv.jc = + int (c2 * a2 * a2) * (nbdown - 1) + int (c2 * b2 * b2) * (nbright - 1); +// MESSAGE("I " << conv.ia << " " << conv.ib << " " << conv.ic); +// MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_Hexa_3D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp) +{ + return hyp.LoadFrom( load ); +} + +//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f +/////////////////////////////////////////////////////////////////////////////// +//ZZ +//#include + +//======================================================================= +//function : ComputePentahedralMesh +//purpose : +//======================================================================= +bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + //printf(" ComputePentahedralMesh HERE\n"); + // + bool bOK; + //int iErr; + StdMeshers_Penta_3D anAlgo; + // + bOK=anAlgo.Compute(aMesh, aShape); + /* + iErr=anAlgo.ErrorStatus(); + + if (iErr) { + printf(" *** Error# %d\n", iErr); + } + else { + printf(" *** No errors# %d\n", iErr); + } + */ + return bOK; +} + diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx new file mode 100644 index 000000000..ed166fc03 --- /dev/null +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -0,0 +1,872 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MEFISTO_2D.cxx +// Moved here from SMESH_MEFISTO_2D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MEFISTO_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMesh.hxx" + +#include "StdMeshers_MaxElementArea.hxx" +#include "StdMeshers_LengthFromEdges.hxx" + +#include "Rn.h" +#include "aptrte.h" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); + _name = "MEFISTO_2D"; +// _shapeType = TopAbs_FACE; + _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("MaxElementArea"); + _compatibleHypothesis.push_back("LengthFromEdges"); + + _edgeLength = 0; + _maxElementArea = 0; + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() +{ + MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis"); + + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; + + list ::const_iterator itl; + const SMESHDS_Hypothesis *theHyp; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + int nbHyp = hyps.size(); + if (!nbHyp) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + itl = hyps.begin(); + theHyp = (*itl); // use only the first hypothesis + + string hypName = theHyp->GetName(); + //int hypId = theHyp->GetID(); + //SCRUTE(hypName); + + bool isOk = false; + + if (hypName == "MaxElementArea") + { + _hypMaxElementArea = static_cast(theHyp); + ASSERT(_hypMaxElementArea); + _maxElementArea = _hypMaxElementArea->GetMaxArea(); + _edgeLength = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "LengthFromEdges") + { + _hypLengthFromEdges = static_cast(theHyp); + ASSERT(_hypLengthFromEdges); + _edgeLength = 0; + _maxElementArea = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + + if (isOk) + { + isOk = false; + if (_maxElementArea > 0) + { +// _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant + _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0)); + isOk = true; + } + else + isOk = (_hypLengthFromEdges != NULL); // **** check mode + if (!isOk) + aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; + } + + //SCRUTE(_edgeLength); + //SCRUTE(_maxElementArea); + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_MEFISTO_2D::Compute"); + + if (_hypLengthFromEdges) + _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + + bool isOk = false; + //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + Z nblf; //nombre de lignes fermees (enveloppe en tete) + Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee + R2 *uvslf = NULL; + Z nbpti = 0; //nombre points internes futurs sommets de la triangulation + R2 *uvpti = NULL; + + Z nbst; + R2 *uvst = NULL; + Z nbt; + Z *nust = NULL; + Z ierr = 0; + + Z nutysu = 1; // 1: il existe un fonction areteideale_() + // Z nutysu=0; // 0: on utilise aretmx + R aretmx = _edgeLength; // longueur max aretes future triangulation + + nblf = NumberOfWires(F); + + nudslf = new Z[1 + nblf]; + nudslf[0] = 0; + int iw = 1; + int nbpnt = 0; + + myOuterWire = BRepTools::OuterWire(F); + nbpnt += NumberOfPoints(aMesh, myOuterWire); + if ( nbpnt < 3 ) // ex: a circle with 2 segments + return false; + nudslf[iw++] = nbpnt; + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) + { + nbpnt += NumberOfPoints(aMesh, W); + nudslf[iw++] = nbpnt; + } + } + + // avoid passing same uv points for a vertex common to 2 wires + TopTools_IndexedDataMapOfShapeListOfShape VWMap; + if ( iw - 1 > 1 ) // nbofWires > 1 + TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap ); + + uvslf = new R2[nudslf[nblf]]; + int m = 0; + + double scalex, scaley; + ComputeScaleOnFace(aMesh, F, scalex, scaley); + + map mefistoToDS; // correspondence mefisto index--> points IDNodes + if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m, + mefistoToDS, scalex, scaley, VWMap)) + return false; + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) + { + if (! LoadPoints(aMesh, F, W, uvslf, m, + mefistoToDS, scalex, scaley, VWMap )) + return false; + } + } + + uvst = NULL; + nust = NULL; + aptrte(nutysu, aretmx, + nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr); + + if (ierr == 0) + { + MESSAGE("... End Triangulation Generated Triangle Number " << nbt); + MESSAGE(" Node Number " << nbst); + StoreResult(aMesh, nbst, uvst, nbt, nust, F, + faceIsForward, mefistoToDS, scalex, scaley); + isOk = true; + } + else + { + MESSAGE("Error in Triangulation"); + isOk = false; + } + if (nudslf != NULL) + delete[]nudslf; + if (uvslf != NULL) + delete[]uvslf; + if (uvst != NULL) + delete[]uvst; + if (nust != NULL) + delete[]nust; + return isOk; +} + +//======================================================================= +//function : fixOverlappedLinkUV +//purpose : prevent failure due to overlapped adjacent links +//======================================================================= + +static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 ) +{ + gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y ); + gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y ); + + double tol2 = DBL_MIN * DBL_MIN; + double sqMod1 = v1.SquareModulus(); + if ( sqMod1 <= tol2 ) return false; + double sqMod2 = v2.SquareModulus(); + if ( sqMod2 <= tol2 ) return false; + + double dot = v1*v2; + + // check sinus >= 1.e-3 + const double minSin = 1.e-3; + if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) { + MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y); + v1.SetCoord( -v1.Y(), v1.X() ); + double delta = sqrt( sqMod1 ) * minSin; + if ( v1.X() < 0 ) + uv0.x -= delta; + else + uv0.x += delta; + if ( v1.Y() < 0 ) + uv0.y -= delta; + else + uv0.y += delta; +// MESSAGE(" -> " << uv0.x << " " << uv0.y << " "); +// MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " << +// "v2( " << v2.X() << " " << v2.Y() << " ) "); +// MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2))); +// v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y ); +// v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y ); +// gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y ); +// sqMod1 = v1.SquareModulus(); +// sqMod2 = v2.SquareModulus(); +// dot = v1*v2; +// double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2)); +// MESSAGE("NEW SIN: " << sin); + return true; + } + return false; +} + +//======================================================================= +//function : fixCommonVertexUV +//purpose : +//======================================================================= + +static bool fixCommonVertexUV (gp_Pnt2d & theUV, + const TopoDS_Vertex& theV, + const TopoDS_Wire& theW, + const TopoDS_Wire& theOW, + const TopoDS_Face& theF, + const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap, + SMESH_Mesh & theMesh) +{ + if( theW.IsSame( theOW ) || + !theVWMap.Contains( theV )) return false; + + // check if there is another wire sharing theV + const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV ); + TopTools_ListIteratorOfListOfShape aWIt; + for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() ) + if ( !theW.IsSame( aWIt.Value() )) + break; + if ( !aWIt.More() ) return false; + + TopTools_ListOfShape EList; + list< double > UList; + + // find edges of theW sharing theV + // and find 2d normal to them at theV + gp_Vec2d N(0.,0.); + TopoDS_Iterator itE( theW ); + for ( ; itE.More(); itE.Next() ) + { + const TopoDS_Edge& E = TopoDS::Edge( itE.Value() ); + TopoDS_Iterator itV( E ); + for ( ; itV.More(); itV.Next() ) + { + const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() ); + if ( !V.IsSame( theV )) + continue; + EList.Append( E ); + Standard_Real u = BRep_Tool::Parameter( V, E ); + UList.push_back( u ); + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l); + gp_Vec2d d1; + gp_Pnt2d p; + C2d->D1( u, p, d1 ); + gp_Vec2d n( d1.Y(), -d1.X() ); + if ( E.Orientation() == TopAbs_REVERSED ) + n.Reverse(); + N += n.Normalized(); + } + } + + // define step size by which to move theUV + + gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four + double maxDist = -DBL_MAX; + TopTools_ListIteratorOfListOfShape aEIt (EList); + list< double >::iterator aUIt = UList.begin(); + for ( ; aEIt.More(); aEIt.Next(), aUIt++ ) + { + const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() ); + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l); + + double umin = DBL_MAX, umax = -DBL_MAX; + SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + if ( !nIt->more() ) // no nodes on edge, only on vertices + { + umin = l; + umax = f; + } + else + { + while ( nIt->more() ) { + const SMDS_MeshNode* node = nIt->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double u = epos->GetUParameter(); + if ( u < umin ) + umin = u; + if ( u > umax ) + umax = u; + } + } + bool isFirstCommon = ( *aUIt == f ); + gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax ); + double dist = theUV.SquareDistance( uv ); + if ( dist > maxDist ) { + maxDist = dist; + nextUV = uv; + } + } + R2 uv0, uv1, uv2; + uv0.x = theUV.X(); uv0.y = theUV.Y(); + uv1.x = nextUV.X(); uv1.y = nextUV.Y(); + uv2.x = uv0.x; uv2.y = uv0.y; + if ( fixOverlappedLinkUV( uv0, uv1, uv2 )) + { + double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y )); + + // move theUV along the normal by the step + + N *= step; + + MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y() + << ") by (" << N.X() << " " << N.Y() << ")" + << endl << "--- MAX DIST " << maxDist); + + theUV.SetXY( theUV.XY() + N.XY() ); + + return true; + } + return false; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, + const TopoDS_Face & FF, + const TopoDS_Wire & WW, + R2 * uvslf, + int & m, + map&mefistoToDS, + double scalex, + double scaley, + const TopTools_IndexedDataMapOfShapeListOfShape& VWMap) +{ +// MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints"); + + //SMDS_Mesh * meshDS = aMesh.GetMeshDS(); + + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + int mInit = m, mFirst, iEdge; + gp_XY scale( scalex, scaley ); + + TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD)); + BRepTools_WireExplorer wexp(W, F); + for (wexp.Init(W, F), iEdge = 0; wexp.More(); wexp.Next(), iEdge++) + { + const TopoDS_Edge & E = wexp.Current(); + + // --- IDNodes of first and last Vertex + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + + ASSERT(!VFirst.IsNull()); + SMDS_NodeIteratorPtr lid= + aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); + if ( !lid->more() ) { + MESSAGE (" NO NODE BUILT ON VERTEX "); + return false; + } + const SMDS_MeshNode* idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + if ( !lid->more() ) { + MESSAGE (" NO NODE BUILT ON VERTEX "); + return false; + } + const SMDS_MeshNode* idLast = lid->next(); + + // --- edge internal IDNodes (relies on good order storage, not checked) + + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + + SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + + //bool isForward = (E.Orientation() == TopAbs_FORWARD); + map params; + + while(ite->more()) + { + const SMDS_MeshNode * node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + if ( nbPoints != params.size()) + { + MESSAGE( "BAD NODE ON EDGE POSITIONS" ); + return false; + } + + mFirst = m; + + // --- load 2D values into MEFISTO structure, + // add IDNodes in mefistoToDS map + if (E.Orientation() == TopAbs_FORWARD) + { + gp_Pnt2d p = C2d->Value(f).XY().Multiplied( scale ); // first point = Vertex Forward + if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh )) + myNodesOnCommonV.push_back( idFirst ); + uvslf[m].x = p.X(); + uvslf[m].y = p.Y(); + mefistoToDS[m + 1] = idFirst; + //MESSAGE(" "<::iterator itp = params.begin(); + for (int i = 1; i <= nbPoints; i++) // nbPoints internal + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale ); + uvslf[m].x = p.X(); + uvslf[m].y = p.Y(); + mefistoToDS[m + 1] = (*itp).second; + //MESSAGE(" "<Value(l).XY().Multiplied( scale ); // last point = Vertex Reversed + if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh )) + myNodesOnCommonV.push_back( idLast ); + uvslf[m].x = p.X(); + uvslf[m].y = p.Y(); + mefistoToDS[m + 1] = idLast; + //MESSAGE(" "<::reverse_iterator itp = params.rbegin(); + for (int i = nbPoints; i >= 1; i--) + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale ); + uvslf[m].x = p.X(); + uvslf[m].y = p.Y(); + mefistoToDS[m + 1] = (*itp).second; + //MESSAGE(" "< 0 ) + fixOverlappedLinkUV (uvslf[ mFirst - 1], + uvslf[ mFirst ], + uvslf[ mFirst + 1 ]); + + } // for wexp + + fixOverlappedLinkUV (uvslf[ m - 1], + uvslf[ mInit ], + uvslf[ mInit + 1 ]); + + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh, + const TopoDS_Face & aFace, double &scalex, double &scaley) +{ + //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace"); + TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD)); + TopoDS_Wire W = BRepTools::OuterWire(F); + + double xmin = 1.e300; // min & max of face 2D parametric coord. + double xmax = -1.e300; + double ymin = 1.e300; + double ymax = -1.e300; + int nbp = 23; + scalex = 1; + scaley = 1; + + TopExp_Explorer wexp(W, TopAbs_EDGE); + for ( ; wexp.More(); wexp.Next()) + { + const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() ); + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + if ( C2d.IsNull() ) continue; + double du = (l - f) / double (nbp); + for (int i = 0; i <= nbp; i++) + { + double param = f + double (i) * du; + gp_Pnt2d p = C2d->Value(param); + if (p.X() < xmin) + xmin = p.X(); + if (p.X() > xmax) + xmax = p.X(); + if (p.Y() < ymin) + ymin = p.Y(); + if (p.Y() > ymax) + ymax = p.Y(); + // MESSAGE(" "<< f<<" "<Value(xmin, ymoy); + gp_Pnt PY0 = S->Value(xmoy, ymin); + double dx = xsize / double (nbp); + double dy = ysize / double (nbp); + for (int i = 1; i <= nbp; i++) + { + double x = xmin + double (i) * dx; + gp_Pnt PX = S->Value(x, ymoy); + double y = ymin + double (i) * dy; + gp_Pnt PY = S->Value(xmoy, y); + length_x += PX.Distance(PX0); + length_y += PY.Distance(PY0); + PX0 = PX; + PY0 = PY; + } + scalex = length_x / xsize; + scaley = length_y / ysize; +// SCRUTE(xsize); +// SCRUTE(ysize); + double xyratio = xsize*scalex/(ysize*scaley); + const double maxratio = 1.e2; + //SCRUTE(xyratio); + if (xyratio > maxratio) { + SCRUTE( scaley ); + scaley *= xyratio / maxratio; + SCRUTE( scaley ); + } + else if (xyratio < 1./maxratio) { + SCRUTE( scalex ); + scalex *= 1 / xyratio / maxratio; + SCRUTE( scalex ); + } + ASSERT(scalex); + ASSERT(scaley); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh, + Z nbst, R2 * uvst, Z nbt, Z * nust, + const TopoDS_Face & F, bool faceIsForward, + map&mefistoToDS, + double scalex, double scaley) +{ + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + int faceID = meshDS->ShapeToIndex( F ); + + Z n, m; + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + for (n = 0; n < nbst; n++) + { + if (mefistoToDS.find(n + 1) == mefistoToDS.end()) + { + double u = uvst[n][0] / scalex; + double v = uvst[n][1] / scaley; + gp_Pnt P = S->Value(u, v); + + SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(node, faceID, u, v); + + //MESSAGE(P.X()<<" "<AddFace(n1, n2, n3); + else + elt = meshDS->AddFace(n1, n3, n2); + + meshDS->SetMeshElementOnShape(elt, faceID); + m++; + } + + // remove bad elements build on vertices shared by wires + + list::iterator itN = myNodesOnCommonV.begin(); + for ( ; itN != myNodesOnCommonV.end(); itN++ ) + { + const SMDS_MeshNode* node = *itN; + SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator(); + while ( invElemIt->more() ) + { + const SMDS_MeshElement* elem = invElemIt->next(); + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int nbSame = 0; + while ( itN->more() ) + if ( itN->next() == node) + nbSame++; + if (nbSame > 1) { + MESSAGE( "RM bad element " << elem->GetID()); + meshDS->RemoveElement( elem ); + } + } + } + +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) +{ + //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength"); + // **** a mettre dans SMESH_2D_Algo ? + + const TopoDS_Face & FF = TopoDS::Face(aShape); + //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + double meanElementLength = 100; + double wireLength = 0; + int wireElementsNumber = 0; + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next()) + { + const TopoDS_Edge & E = TopoDS::Edge(expe.Current()); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + double length = EdgeLength(E); + wireLength += length; + wireElementsNumber += nb; + } + } + if (wireElementsNumber) + meanElementLength = wireLength / wireElementsNumber; + //SCRUTE(meanElementLength); + return meanElementLength; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx new file mode 100644 index 000000000..ad6ebc831 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -0,0 +1,1582 @@ +// SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Penta_3D.cxx +// Module : SMESH + +#include "StdMeshers_Penta_3D.hxx" + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + +#include "SMDS_EdgePosition.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMESHDS_SubMesh.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_MeshEditor.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; + +typedef map < int, int, less >::iterator \ + StdMeshers_IteratorOfDataMapOfIntegerInteger; + +//======================================================================= +//function : StdMeshers_Penta_3D +//purpose : +//======================================================================= +StdMeshers_Penta_3D::StdMeshers_Penta_3D() +: myErrorStatus(1) +{ + myTol3D=0.1; + myWallNodesMaps.resize( SMESH_Block::NbFaces() ); + myShapeXYZ.resize( SMESH_Block::NbSubShapes() ); +} +//======================================================================= +//function : Compute +//purpose : +//======================================================================= +bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + MESSAGE("StdMeshers_Penta_3D::Compute()"); + // + myErrorStatus=0; + // + bool bOK=false; + // + myShape=aShape; + SetMesh(aMesh); + // + CheckData(); + if (myErrorStatus){ + return bOK; + } + // + MakeBlock(); + if (myErrorStatus){ + return bOK; + } + // + MakeNodes(); + if (myErrorStatus){ + return bOK; + } + // + MakeConnectingMap(); + // + ClearMeshOnFxy1(); + if (myErrorStatus) { + return bOK; + } + // + MakeMeshOnFxy1(); + if (myErrorStatus) { + return bOK; + } + // + MakeVolumeMesh(); + // + return !bOK; +} +//======================================================================= +//function : MakeNodes +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeNodes() +{ + myErrorStatus=0; + // + const int aNbSIDs=9; + int i, j, k, ij, iNbN, aNodeID, aSize, iErr; + double aX, aY, aZ; + SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={ + SMESH_Block::ID_V000, SMESH_Block::ID_V100, + SMESH_Block::ID_V110, SMESH_Block::ID_V010, + SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0, + SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0, + SMESH_Block::ID_Fxy0 + }; + // + SMESH_Mesh* pMesh=GetMesh(); + // + // 1. Define the sizes of mesh + // + // 1.1 Horizontal size + myJSize=0; + for (i=0; iGetSubMeshContaining(aS); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + iNbN=aSM->NbNodes(); + myJSize+=iNbN; + } + //printf("*** Horizontal: number of nodes summary=%d\n", myJSize); + // + // 1.2 Vertical size + myISize=2; + { + const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z); + SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + iNbN=aSM->NbNodes(); + myISize+=iNbN; + } + //printf("*** Vertical: number of nodes on edges and vertices=%d\n", myISize); + // + aSize=myISize*myJSize; + myTNodes.resize(aSize); + // + StdMeshers_TNode aTNode; + gp_XYZ aCoords; + gp_Pnt aP3D; + // + // 2. Fill the repers on base face (Z=0) + i=0; j=0; + // vertices + for (k=0; kGetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + while(ite->more()) { + const SMDS_MeshNode* aNode = ite->next(); + aNodeID=aNode->GetID(); + // + aTNode.SetNode(aNode); + aTNode.SetShapeSupportID(aSID); + aTNode.SetBaseNodeID(aNodeID); + // + if ( SMESH_Block::IsEdgeID (aSID)) + { + const SMDS_EdgePosition* epos = + static_cast(aNode->GetPosition().get()); + myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); + } + else { + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + aP3D.SetCoord(aX, aY, aZ); + myBlock.ComputeParameters(aP3D, aS, aCoords); + } + iErr=myBlock.ErrorStatus(); + if (iErr) { + MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << + "SMESHBlock: ComputeParameters operation failed"); + myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed + return; + } + aTNode.SetNormCoord(aCoords); + ij=i*myJSize+j; + myTNodes[ij]=aTNode; + ++j; + } + } + /* + //DEB + { + int iShapeSupportID, iBaseNodeID; + // + //printf("\n\n*** Base Face\n"); + i=0; + for (j=0; j aZL(myISize); +// vector::iterator aItZL1, aItZL2 ; +// // +// const TopoDS_Shape& aE00z=myBlock.Shape(SMESH_Block::ID_E00z); +// SMDS_NodeIteratorPtr aItaE00z = +// pMesh->GetSubMeshContaining(aE00z)->GetSubMeshDS()->GetNodes(); +// // +// aZL[0]=0.; +// i=1; +// while (aItaE00z->more()) { +// const SMDS_MeshNode* aNode=aItaE00z->next(); +// const SMDS_EdgePosition* epos = +// static_cast(aNode->GetPosition().get()); +// myBlock.ComputeParameters( epos->GetUParameter(), aE00z, aCoords ); +// iErr=myBlock.ErrorStatus(); +// if (iErr) { +// MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << +// "SMESHBlock: ComputeParameters operation failed"); +// myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed +// return; +// } +// aZL[i]=aCoords.Z(); +// ++i; +// } +// aZL[i]=1.; +// // +// aItZL1=aZL.begin(); +// aItZL2=aZL.end(); +// // +// // Sorting the layers +// sort(aItZL1, aItZL2); + //DEB + /* + printf("** \n\n Layers begin\n"); + for(i=0, aItZL=aItZL1; aItZL!=aItZL2; ++aItZL, ++i) { + printf(" #%d : %lf\n", i, *aItZL); + } + printf("** Layers end\n"); + */ + //DEB + // + // + + // 3.1 Fill maps of wall nodes + SMESH_Block::TShapeID wallFaceID[4] = { + SMESH_Block::ID_Fx0z, SMESH_Block::ID_Fx1z, + SMESH_Block::ID_F0yz, SMESH_Block::ID_F1yz + }; + SMESH_Block::TShapeID baseEdgeID[4] = { + SMESH_Block::ID_Ex00, SMESH_Block::ID_Ex10, + SMESH_Block::ID_E0y0, SMESH_Block::ID_E1y0 + }; + for ( i = 0; i < 4; ++i ) { + int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ i ]); + bool ok = LoadIJNodes (myWallNodesMaps[ fIndex ], + TopoDS::Face( myBlock.Shape( wallFaceID[ i ] )), + TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )), + pMesh->GetMeshDS()); + if ( !ok ) { + myErrorStatus = i + 1; + MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus ); + return; + } + } + + // 3.2 find node columns for vertical edges and edge IDs + vector * verticEdgeNodes[ 4 ]; + SMESH_Block::TShapeID verticEdgeID [ 4 ]; + for ( i = 0; i < 4; ++i ) { // 4 first base nodes are nodes on vertices + // edge ID + SMESH_Block::TShapeID eID, vID = aSIDs[ i ]; + ShapeSupportID(false, vID, eID); + verticEdgeID[ i ] = eID; + // column nodes + StdMeshers_TNode& aTNode = myTNodes[ i ]; + verticEdgeNodes[ i ] = 0; + for ( j = 0; j < 4; ++j ) { // loop on 4 wall faces + int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ j ]); + StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ]; + if ( ijNodes.begin()->second[0] == aTNode.Node() ) + verticEdgeNodes[ i ] = & ijNodes.begin()->second; + else if ( ijNodes.rbegin()->second[0] == aTNode.Node() ) + verticEdgeNodes[ i ] = & ijNodes.rbegin()->second; + if ( verticEdgeNodes[ i ] ) + break; + } + } + + // 3.3 set XYZ of vertices, and initialize of the rest + SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS(); + for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) + { + if ( SMESH_Block::IsVertexID( id )) { + TopoDS_Shape V = myBlock.Shape( id ); + SMESHDS_SubMesh* sm = aMesh->MeshElements( V ); + const SMDS_MeshNode* n = sm->GetNodes()->next(); + myShapeXYZ[ id ].SetCoord( n->X(), n->Y(), n->Z() ); + } + else + myShapeXYZ[ id ].SetCoord( 0., 0., 0. ); + } + + + // 4. Fill the rest repers + bool bIsUpperLayer; + int iBNID; + SMESH_Block::TShapeID aSSID, aBNSSID; + StdMeshers_TNode aTN; + // + for (j=0; j* nColumns[8]; + double ratio[4]; // base node position between columns [0.-1.] + if ( createNode ) + for ( k = 0; k < 4; ++k ) + ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ], + nColumns[k*2], nColumns[k*2+1]); + // + // XYZ on the bottom and top faces + const SMDS_MeshNode* n = aBN.Node(); + myShapeXYZ[ SMESH_Block::ID_Fxy0 ].SetCoord( n->X(), n->Y(), n->Z() ); + myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. ); + // + // first create or find a top node, then the rest ones in a column + for (i=myISize-1; i>0; --i) + { + if ( createNode ) { + // set XYZ on vertical edges and faces + for ( k = 0; k < 4; ++k ) { + const SMDS_MeshNode* n = (*verticEdgeNodes[ k ]) [ i ]; + myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() ); + // + n = (*nColumns[k*2]) [ i ]; + gp_XYZ xyz( n->X(), n->Y(), n->Z() ); + myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz; + n = (*nColumns[k*2+1]) [ i ]; + xyz.SetCoord( n->X(), n->Y(), n->Z() ); + myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz; + } + } + // fill current node info + // -index in aTNodes + ij=i*myJSize+j; + // -normalized coordinates + aX=aBNXYZ.X(); + aY=aBNXYZ.Y(); + //aZ=aZL[i]; + aZ=(double)i/(double)(myISize-1); + aCoords.SetCoord(aX, aY, aZ); + // + // suporting shape ID + bIsUpperLayer=(i==(myISize-1)); + ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); + return; + } + // + aTN.SetShapeSupportID(aSSID); + aTN.SetNormCoord(aCoords); + aTN.SetBaseNodeID(iBNID); + // + if (aSSID!=SMESH_Block::ID_NONE){ + // try to find the node + const TopoDS_Shape& aS=myBlock.Shape((int)aSSID); + FindNodeOnShape(aS, aCoords, i, aTN); + } + else{ + // create node and get it id + CreateNode (bIsUpperLayer, aCoords, aTN); + // + if ( bIsUpperLayer ) { + const SMDS_MeshNode* n = aTN.Node(); + myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() ); + } + } + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); + return; + } + // + myTNodes[ij]=aTN; + } + } + //DEB + /* + { + int iSSID, iBNID, aID; + // + for (i=0; iGetID(); + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf }, { %lf %lf %lf }\n", + j, iBNID, iSSID, aID, aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aX, aY, aZ); + } + } + } + */ + //DEB t +} +//======================================================================= +//function : FindNodeOnShape +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, + const gp_XYZ& aParams, + const int z, + StdMeshers_TNode& aTN) +{ + myErrorStatus=0; + // + double aX, aY, aZ, aD, aTol2, minD; + gp_Pnt aP1, aP2; + // + SMESH_Mesh* pMesh=GetMesh(); + aTol2=myTol3D*myTol3D; + minD = 1.e100; + SMDS_MeshNode* pNode=NULL; + // + if ( aS.ShapeType() == TopAbs_FACE || + aS.ShapeType() == TopAbs_EDGE ) + { + // find a face ID to which aTN belongs to + int faceID; + if ( aS.ShapeType() == TopAbs_FACE ) + faceID = myBlock.ShapeID( aS ); + else { // edge maybe vertical or top horizontal + gp_XYZ aCoord = aParams; + if ( aCoord.Z() == 1. ) + aCoord.SetZ( 0.5 ); // move from top down + else + aCoord.SetX( 0.5 ); // move along X + faceID = SMESH_Block::GetShapeIDByParams( aCoord ); + } + ASSERT( SMESH_Block::IsFaceID( faceID )); + int fIndex = SMESH_Block::ShapeIndex( faceID ); + StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ]; + // look for a base node in ijNodes + const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() ); + StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin(); + for ( ; par_nVec != ijNodes.end(); par_nVec++ ) + if ( par_nVec->second[ 0 ] == baseNode ) { + pNode=(SMDS_MeshNode*)par_nVec->second.at( z ); + aTN.SetNode(pNode); + return; + } + } + // + myBlock.Point(aParams, aS, aP1); + // + SMDS_NodeIteratorPtr ite= + pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + while(ite->more()) { + const SMDS_MeshNode* aNode = ite->next(); + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + aP2.SetCoord(aX, aY, aZ); + aD=(double)aP1.SquareDistance(aP2); + //printf("** D=%lf ", aD, aTol2); + if (aD < minD) { + pNode=(SMDS_MeshNode*)aNode; + aTN.SetNode(pNode); + minD = aD; + //printf(" Ok\n"); + if (aD*& aCol1, + vector*& aCol2) +{ + // find base and top edges of the face + vector< int > edgeVec; // 0-base, 1-top + SMESH_Block::GetFaceEdgesIDs( aFaceID, edgeVec ); + // + int coord = SMESH_Block::GetCoordIndOnEdge( edgeVec[ 0 ] ); + double param = aBaseNodeParams.Coord( coord ); + if ( !myBlock.IsForwadEdge( edgeVec[ 0 ] )) + param = 1. - param; + // + // look for columns around param + StdMeshers_IJNodeMap & ijNodes = + myWallNodesMaps[ SMESH_Block::ShapeIndex( aFaceID )]; + StdMeshers_IJNodeMap::iterator par_nVec_1 = ijNodes.begin(); + while ( par_nVec_1->first < param ) + par_nVec_1++; + StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1; + // + double r = 0; + if ( par_nVec_1 != ijNodes.begin() ) { + par_nVec_1--; + r = ( param - par_nVec_1->first ) / ( par_nVec_2->first - par_nVec_1->first ); + } + aCol1 = & par_nVec_1->second; + aCol2 = & par_nVec_2->second; + + // base edge + const SMDS_MeshNode* n1 = aCol1->front(); + const SMDS_MeshNode* n2 = aCol2->front(); + gp_XYZ xyz1( n1->X(), n1->Y(), n1->Z() ), xyz2( n2->X(), n2->Y(), n2->Z() ); + myShapeXYZ[ edgeVec[ 0 ] ] = ( 1. - r ) * xyz1 + r * xyz2; + + // top edge + n1 = aCol1->back(); + n2 = aCol2->back(); + xyz1.SetCoord( n1->X(), n1->Y(), n1->Z() ); + xyz2.SetCoord( n2->X(), n2->Y(), n2->Z() ); + myShapeXYZ[ edgeVec[ 1 ] ] = ( 1. - r ) * xyz1 + r * xyz2; + + return r; +} + +//======================================================================= +//function : MakeVolumeMesh +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeVolumeMesh() +{ + myErrorStatus=0; + // + int i, j, ij, ik, i1, i2, aSSID; + // + SMESH_Mesh* pMesh =GetMesh(); + SMESHDS_Mesh* meshDS=pMesh->GetMeshDS(); + // + int shapeID = meshDS->ShapeToIndex( myShape ); + // + // 1. Set Node In Volume + ik=myISize-1; + for (i=1; iSetNodeInVolume(aNode, shapeID); + } + } + } + // + // 2. Make pentahedrons + int aID0, k , aJ[3]; + vector aN; + // + SMDS_ElemIteratorPtr itf, aItNodes; + // + const TopoDS_Face& aFxy0= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); + SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); + SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + // + itf=aSM0->GetElements(); + while(itf->more()) { + const SMDS_MeshElement* pE0=itf->next(); + // + int nbFaceNodes = pE0->NbNodes(); + if ( aN.size() < nbFaceNodes * 2 ) + aN.resize( nbFaceNodes * 2 ); + // + k=0; + aItNodes=pE0->nodesIterator(); + while (aItNodes->more()) { + const SMDS_MeshElement* pNode=aItNodes->next(); + aID0=pNode->GetID(); + aJ[k]=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); + return; + } + // + ++k; + } + // + bool forward = true; + for (i=0; iAddVolume(aN[0], aN[1], aN[2], + aN[3], aN[4], aN[5]); + else + aV = meshDS->AddVolume(aN[0], aN[2], aN[1], + aN[3], aN[5], aN[4]); + break; + case 4: + if ( forward ) + aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + aN[4], aN[5], aN[6], aN[7]); + else + aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1], + aN[4], aN[7], aN[6], aN[5]); + break; + default: + continue; + } + meshDS->SetMeshElementOnShape(aV, shapeID); + } + } +} + +//======================================================================= +//function : MakeMeshOnFxy1 +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeMeshOnFxy1() +{ + myErrorStatus=0; + // + int aID0, aJ, aLevel, ij, aNbNodes, k; + // + SMDS_NodeIteratorPtr itn; + SMDS_ElemIteratorPtr itf, aItNodes; + SMDSAbs_ElementType aElementType; + // + const TopoDS_Face& aFxy0= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); + const TopoDS_Face& aFxy1= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1)); + // + SMESH_Mesh* pMesh=GetMesh(); + SMESHDS_Mesh * meshDS = pMesh->GetMeshDS(); + // + SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); + SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + // + // set nodes on aFxy1 + aLevel=myISize-1; + itn=aSM0->GetNodes(); + aNbNodes=aSM0->NbNodes(); + //printf("** aNbNodes=%d\n", aNbNodes); + while(itn->more()) { + const SMDS_MeshNode* aN0=itn->next(); + aID0=aN0->GetID(); + aJ=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); + return; + } + // + ij=aLevel*myJSize+aJ; + const StdMeshers_TNode& aTN1=myTNodes[ij]; + SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node(); + // + meshDS->SetNodeOnFace(aN1, aFxy1); + } + // + // set elements on aFxy1 + vector aNodes1; + // + itf=aSM0->GetElements(); + while(itf->more()) { + const SMDS_MeshElement * pE0=itf->next(); + aElementType=pE0->GetType(); + if (!aElementType==SMDSAbs_Face) { + continue; + } + aNbNodes=pE0->NbNodes(); +// if (aNbNodes!=3) { +// continue; +// } + if ( aNodes1.size() < aNbNodes ) + aNodes1.resize( aNbNodes ); + // + k=aNbNodes-1; // reverse a face + aItNodes=pE0->nodesIterator(); + while (aItNodes->more()) { + const SMDS_MeshElement* pNode=aItNodes->next(); + aID0=pNode->GetID(); + aJ=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); + return; + } + // + ij=aLevel*myJSize+aJ; + const StdMeshers_TNode& aTN1=myTNodes[ij]; + const SMDS_MeshNode* aN1=aTN1.Node(); + aNodes1[k]=aN1; + --k; + } + SMDS_MeshFace * face = 0; + switch ( aNbNodes ) { + case 3: + face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + break; + case 4: + face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + break; + default: + continue; + } + meshDS->SetMeshElementOnShape(face, aFxy1); + } +} +//======================================================================= +//function : ClearMeshOnFxy1 +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::ClearMeshOnFxy1() +{ + myErrorStatus=0; + // + SMESH_subMesh* aSubMesh; + SMESH_Mesh* pMesh=GetMesh(); + // + const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1); + aSubMesh = pMesh->GetSubMeshContaining(aFxy1); + if (aSubMesh) + aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); +} + +//======================================================================= +//function : GetIndexOnLayer +//purpose : +//======================================================================= +int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID) +{ + myErrorStatus=0; + // + int j=-1; + StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt; + // + aMapIt=myConnectingMap.find(aID); + if (aMapIt==myConnectingMap.end()) { + myErrorStatus=200; + return j; + } + j=(*aMapIt).second; + return j; +} +//======================================================================= +//function : MakeConnectingMap +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeConnectingMap() +{ + int j, aBNID; + // + for (j=0; jGetMeshDS(); + // + pNode = pMeshDS->AddNode(aX, aY, aZ); + aTN.SetNode(pNode); +} +//======================================================================= +//function : ShapeSupportID +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, + const SMESH_Block::TShapeID aBNSSID, + SMESH_Block::TShapeID& aSSID) +{ + myErrorStatus=0; + // + switch (aBNSSID) { + case SMESH_Block::ID_V000: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z; + break; + case SMESH_Block::ID_V100: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V101 : SMESH_Block::ID_E10z; + break; + case SMESH_Block::ID_V110: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V111 : SMESH_Block::ID_E11z; + break; + case SMESH_Block::ID_V010: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V011 : SMESH_Block::ID_E01z; + break; + case SMESH_Block::ID_Ex00: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z; + break; + case SMESH_Block::ID_Ex10: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z; + break; + case SMESH_Block::ID_E0y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz; + break; + case SMESH_Block::ID_E1y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz; + break; + case SMESH_Block::ID_Fxy0: + aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ? Shape_ID_Fxy1 : Shape_ID_NONE; + break; + default: + aSSID=SMESH_Block::ID_NONE; + myErrorStatus=10; // Can not find supporting shape ID + break; + } + return; +} +//======================================================================= +//function : MakeBlock +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeBlock() +{ + myErrorStatus=0; + // + bool bFound; + int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF; + // + TopoDS_Vertex aV000, aV001; + TopoDS_Shape aFTr; + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopTools_IndexedMapOfShape aME ,aMEV, aM; + TopTools_ListIteratorOfListOfShape aIt; + // + TopExp::MapShapes(myShape, TopAbs_FACE, aM); + // + // 0. Find triangulated face aFTr + SMDSAbs_ElementType aElementType; + SMESH_Mesh* pMesh=GetMesh(); + // + iCnt=0; + iNbF=aM.Extent(); + for (i=1; i<=iNbF; ++i) { + const TopoDS_Shape& aF=aM(i); + SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + SMDS_ElemIteratorPtr itf=aSM->GetElements(); + while(itf->more()) { + const SMDS_MeshElement * pElement=itf->next(); + aElementType=pElement->GetType(); + if (aElementType==SMDSAbs_Face) { + iNbNodes=pElement->NbNodes(); + if (iNbNodes==3) { + aFTr=aF; + ++iCnt; + if (iCnt>1) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=5; // more than one face has triangulation + return; + } + break; // next face + } + } + } + } + // + // 1. Vetrices V00, V001; + // + TopExp::MapShapes(aFTr, TopAbs_EDGE, aME); + TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + // + // 1.1 Base vertex V000 + iNbE=aME.Extent(); + if (iNbE!=4){ + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=7; // too few edges are in base face aFTr + return; + } + const TopoDS_Edge& aE1=TopoDS::Edge(aME(1)); + aV000=TopExp::FirstVertex(aE1); + // + const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000); + aIt.Initialize(aLE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aEx=aIt.Value(); + aMEV.Add(aEx); + } + iNbEV=aMEV.Extent(); + if (iNbEV!=3){ + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=7; // too few edges meet in base vertex + return; + } + // + // 1.2 Vertex V001 + bFound=false; + for (j=1; j<=iNbEV; ++j) { + const TopoDS_Shape& aEx=aMEV(j); + if (!aME.Contains(aEx)) { + TopoDS_Vertex aV[2]; + // + const TopoDS_Edge& aE=TopoDS::Edge(aEx); + TopExp::Vertices(aE, aV[0], aV[1]); + for (i=0; i<2; ++i) { + if (!aV[i].IsSame(aV000)) { + aV001=aV[i]; + bFound=!bFound; + break; + } + } + } + } + // + if (!bFound) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=8; // can not find reper V001 + return; + } + //DEB + //gp_Pnt aP000, aP001; + // + //aP000=BRep_Tool::Pnt(TopoDS::Vertex(aV000)); + //printf("*** aP000 { %lf, %lf, %lf }\n", aP000.X(), aP000.Y(), aP000.Z()); + //aP001=BRep_Tool::Pnt(TopoDS::Vertex(aV001)); + //printf("*** aP001 { %lf, %lf, %lf }\n", aP001.X(), aP001.Y(), aP001.Z()); + //DEB + // + aME.Clear(); + TopExp::MapShapes(myShape, TopAbs_SHELL, aME); + iNbE=aME.Extent(); + if (iNbE!=1) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=9; // number of shells in source shape !=1 + return; + } + // + // 2. Load Block + const TopoDS_Shell& aShell=TopoDS::Shell(aME(1)); + myBlock.Load(aShell, aV000, aV001); + iErr=myBlock.ErrorStatus(); + if (iErr) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=100; // SMESHBlock: Load operation failed + return; + } +} +//======================================================================= +//function : CheckData +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::CheckData() +{ + myErrorStatus=0; + // + int i, iNb; + int iNbEx[]={8, 12, 6}; + // + TopAbs_ShapeEnum aST; + TopAbs_ShapeEnum aSTEx[]={ + TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE + }; + TopTools_IndexedMapOfShape aM; + // + if (myShape.IsNull()){ + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=2; // null shape + return; + } + // + aST=myShape.ShapeType(); + if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) { + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=3; // not compatible type of shape + return; + } + // + for (i=0; i<3; ++i) { + aM.Clear(); + TopExp::MapShapes(myShape, aSTEx[i], aM); + iNb=aM.Extent(); + if (iNb!=iNbEx[i]){ + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=4; // number of subshape is not compatible + return; + } + } +} + +//======================================================================= +//function : LoadIJNodes +//purpose : Load nodes bound to theFace into column (vectors) and rows +// of theIJNodes. +// The value of theIJNodes map is a vector of ordered nodes so +// that the 0-the one lies on theBaseEdge. +// The key of theIJNodes map is a normalized parameter of each +// 0-the node on theBaseEdge. +//======================================================================= + +bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, + const TopoDS_Face& theFace, + const TopoDS_Edge& theBaseEdge, + SMESHDS_Mesh* theMesh) +{ + // get vertices of theBaseEdge + TopoDS_Vertex vfb, vlb, vft; // first and last, bottom and top vertices + TopoDS_Edge eFrw = TopoDS::Edge( theBaseEdge.Oriented( TopAbs_FORWARD )); + TopExp::Vertices( eFrw, vfb, vlb ); + + // find the other edges of theFace and orientation of e1 + TopoDS_Edge e1, e2, eTop; + bool rev1, CumOri = false; + TopExp_Explorer exp( theFace, TopAbs_EDGE ); + int nbEdges = 0; + for ( ; exp.More(); exp.Next() ) + { + if ( ++nbEdges > 4 ) + return false; // more than 4 edges in theFace + TopoDS_Edge e = TopoDS::Edge( exp.Current() ); + if ( theBaseEdge.IsSame( e )) + continue; + TopoDS_Vertex vCommon; + if ( !TopExp::CommonVertex( theBaseEdge, e, vCommon )) + eTop = e; + else if ( vCommon.IsSame( vfb )) { + e1 = e; + vft = TopExp::LastVertex( e1, CumOri ); + rev1 = vfb.IsSame( vft ); + if ( rev1 ) + vft = TopExp::FirstVertex( e1, CumOri ); + } + else + e2 = e; + } + if ( nbEdges < 4 ) + return false; // lass than 4 edges in theFace + + // submeshes corresponding to shapes + SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace ); + SMESHDS_SubMesh* smb = theMesh->MeshElements( theBaseEdge ); + SMESHDS_SubMesh* smt = theMesh->MeshElements( eTop ); + SMESHDS_SubMesh* sm1 = theMesh->MeshElements( e1 ); + SMESHDS_SubMesh* sm2 = theMesh->MeshElements( e2 ); + SMESHDS_SubMesh* smVfb = theMesh->MeshElements( vfb ); + SMESHDS_SubMesh* smVlb = theMesh->MeshElements( vlb ); + SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft ); + if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) { + MESSAGE( "NULL submesh " <NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) { + MESSAGE(" Diff nb of nodes on opposite edges" ); + return false; + } + if (smVfb->NbNodes() != 1 || smVlb->NbNodes() != 1 || smVft->NbNodes() != 1) { + MESSAGE("Empty submesh of vertex"); + return false; + } + if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) { + MESSAGE( "Wrong nb face nodes: " << + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + return false; + } + // IJ size + int vsize = sm1->NbNodes() + 2; + int hsize = smb->NbNodes() + 2; + + // load nodes from theBaseEdge + + set loadedNodes; + const SMDS_MeshNode* nullNode = 0; + + vector & nVecf = theIJNodes[ 0.]; + nVecf.resize( vsize, nullNode ); + loadedNodes.insert( nVecf[ 0 ] = smVfb->GetNodes()->next() ); + + vector & nVecl = theIJNodes[ 1.]; + nVecl.resize( vsize, nullNode ); + loadedNodes.insert( nVecl[ 0 ] = smVlb->GetNodes()->next() ); + + double f, l; + BRep_Tool::Range( eFrw, f, l ); + double range = l - f; + SMDS_NodeIteratorPtr nIt = smb->GetNodes(); + const SMDS_MeshNode* node; + while ( nIt->more() ) + { + node = nIt->next(); + const SMDS_EdgePosition* pos = + dynamic_cast( node->GetPosition().get() ); + if ( !pos ) return false; + double u = ( pos->GetUParameter() - f ) / range; + vector & nVec = theIJNodes[ u ]; + nVec.resize( vsize, nullNode ); + loadedNodes.insert( nVec[ 0 ] = node ); + } + if ( theIJNodes.size() != hsize ) { + MESSAGE( "Wrong node positions on theBaseEdge" ); + return false; + } + + // load nodes from e1 + + map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge + nIt = sm1->GetNodes(); + while ( nIt->more() ) + { + node = nIt->next(); + const SMDS_EdgePosition* pos = + dynamic_cast( node->GetPosition().get() ); + if ( !pos ) return false; + sortedNodes.insert( make_pair( pos->GetUParameter(), node )); + } + loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() ); + map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin(); + int row = rev1 ? vsize - 1 : 0; + for ( ; u_n != sortedNodes.end(); u_n++ ) + { + if ( rev1 ) row--; + else row++; + loadedNodes.insert( nVecf[ row ] = u_n->second ); + } + + // try to load the rest nodes + + // get all faces from theFace + set allFaces, foundFaces; + SMDS_ElemIteratorPtr eIt = smFace->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* e = eIt->next(); + if ( e->GetType() == SMDSAbs_Face ) + allFaces.insert( e ); + } + // Starting from 2 neighbour nodes on theBaseEdge, look for a face + // the nodes belong to, and between the nodes of the found face, + // look for a not loaded node considering this node to be the next + // in a column of the starting second node. Repeat, starting + // from nodes next to the previous starting nodes in their columns, + // and so on while a face can be found. Then go the the next pair + // of nodes on theBaseEdge. + StdMeshers_IJNodeMap::iterator par_nVec_1 = theIJNodes.begin(); + StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1; + // loop on columns + int col = 0; + for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) + { + col++; + row = 0; + const SMDS_MeshNode* n1 = par_nVec_1->second[ row ]; + const SMDS_MeshNode* n2 = par_nVec_2->second[ row ]; + const SMDS_MeshElement* face = 0; + do { + // look for a face by 2 nodes + face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces ); + if ( face ) + { + int nbFaceNodes = face->NbNodes(); + if ( nbFaceNodes > 4 ) { + MESSAGE(" Too many nodes in a face: " << nbFaceNodes ); + return false; + } + // look for a not loaded node of the + bool found = false; + const SMDS_MeshNode* n3 = 0; // a node defferent from n1 and n2 + eIt = face->nodesIterator() ; + while ( !found && eIt->more() ) { + node = static_cast( eIt->next() ); + found = loadedNodes.insert( node ).second; + if ( !found && node != n1 && node != n2 ) + n3 = node; + } + if ( found ) { + if ( ++row > vsize - 1 ) { + MESSAGE( "Too many nodes in column "<< col <<": "<< row+1); + return false; + } + par_nVec_2->second[ row ] = node; + foundFaces.insert( face ); + n2 = node; + if ( nbFaceNodes == 4 ) + n1 = par_nVec_1->second[ row ]; + } + else if (nbFaceNodes == 3 && + n3 == par_nVec_1->second[ row ] ) + n1 = n3; + else { + MESSAGE( "Not quad mesh, column "<< col ); + return false; + } + } + } while ( face && n1 && n2 ); + + if ( row < vsize - 1 ) { + MESSAGE( "Too few nodes in column "<< col <<": "<< row+1); + MESSAGE( "Base node 1: "<< par_nVec_1->second[0]); + MESSAGE( "Base node 2: "<< par_nVec_2->second[0]); + MESSAGE( "Current node 1: "<< n1); + MESSAGE( "Current node 2: "<< n2); + MESSAGE( "first base node: "<< theIJNodes.begin()->second[0]); + MESSAGE( "last base node: "<< theIJNodes.rbegin()->second[0]); + return false; + } + } // loop on columns + + return true; +} + +////////////////////////////////////////////////////////////////////////// +// +// StdMeshers_SMESHBlock +// +////////////////////////////////////////////////////////////////////////// + +//======================================================================= +//function : StdMeshers_SMESHBlock +//purpose : +//======================================================================= +StdMeshers_SMESHBlock::StdMeshers_SMESHBlock() +{ + myErrorStatus=1; + myIsEdgeForward.resize( SMESH_Block::NbEdges(), -1 ); +} + +//======================================================================= +//function : IsForwadEdge +//purpose : +//======================================================================= + +bool StdMeshers_SMESHBlock::IsForwadEdge(const int theEdgeID) +{ + int index = myTBlock.ShapeIndex( theEdgeID ); + if ( !myTBlock.IsEdgeID( theEdgeID )) + return false; + + if ( myIsEdgeForward[ index ] < 0 ) + myIsEdgeForward[ index ] = + myTBlock.IsForwardEdge( TopoDS::Edge( Shape( theEdgeID )), myShapeIDMap ); + + return myIsEdgeForward[ index ]; +} + +//======================================================================= +//function : ErrorStatus +//purpose : +//======================================================================= +int StdMeshers_SMESHBlock::ErrorStatus() const +{ + return myErrorStatus; +} +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell) +{ + + TopoDS_Vertex aV000, aV001; + // + Load(theShell, aV000, aV001); +} +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theV000, + const TopoDS_Vertex& theV001) +{ + myErrorStatus=0; + // + myShell=theShell; + // + bool bOk; + // + myShapeIDMap.Clear(); + bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); + if (!bOk) { + myErrorStatus=2; + return; + } +} +//======================================================================= +//function : ComputeParameters +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, + gp_XYZ& theXYZ) +{ + ComputeParameters(thePnt, myShell, theXYZ); +} +//======================================================================= +//function : ComputeParameters +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ) +{ + myErrorStatus=0; + // + int aID; + bool bOk; + // + aID=ShapeID(theShape); + if (myErrorStatus) { + return; + } + bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID); + if (!bOk) { + myErrorStatus=4; // problems with computation Parameters + return; + } +} + +//======================================================================= +//function : ComputeParameters +//purpose : +//======================================================================= + +void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ) +{ + myErrorStatus=0; + // + int aID; + bool bOk=false; + // + aID=ShapeID(theShape); + if (myErrorStatus) { + return; + } + if ( SMESH_Block::IsEdgeID( aID )) + bOk=myTBlock.EdgeParameters( aID, theU, theXYZ ); + if (!bOk) { + myErrorStatus=4; // problems with computation Parameters + return; + } +} + +//======================================================================= +//function : Point +//purpose : +//======================================================================= + void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, + gp_Pnt& aP3D) +{ + TopoDS_Shape aS; + // + Point(theParams, aS, aP3D); +} +//======================================================================= +//function : Point +//purpose : +//======================================================================= + void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, + const TopoDS_Shape& theShape, + gp_Pnt& aP3D) +{ + myErrorStatus=0; + // + int aID; + bool bOk=false; + gp_XYZ aXYZ(99.,99.,99.); + aP3D.SetXYZ(aXYZ); + // + if (theShape.IsNull()) { + bOk=myTBlock.ShellPoint(theParams, aXYZ); + } + // + else { + aID=ShapeID(theShape); + if (myErrorStatus) { + return; + } + // + if (SMESH_Block::IsVertexID(aID)) { + bOk=myTBlock.VertexPoint(aID, aXYZ); + } + else if (SMESH_Block::IsEdgeID(aID)) { + bOk=myTBlock.EdgePoint(aID, theParams, aXYZ); + } + // + else if (SMESH_Block::IsFaceID(aID)) { + bOk=myTBlock.FacePoint(aID, theParams, aXYZ); + } + } + if (!bOk) { + myErrorStatus=4; // problems with point computation + return; + } + aP3D.SetXYZ(aXYZ); +} +//======================================================================= +//function : ShapeID +//purpose : +//======================================================================= +int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape) +{ + myErrorStatus=0; + // + int aID=-1; + TopoDS_Shape aSF, aSR; + // + aSF=theShape; + aSF.Orientation(TopAbs_FORWARD); + aSR=theShape; + aSR.Orientation(TopAbs_REVERSED); + // + if (myShapeIDMap.Contains(aSF)) { + aID=myShapeIDMap.FindIndex(aSF); + return aID; + } + if (myShapeIDMap.Contains(aSR)) { + aID=myShapeIDMap.FindIndex(aSR); + return aID; + } + myErrorStatus=2; // unknown shape; + return aID; +} +//======================================================================= +//function : Shape +//purpose : +//======================================================================= +const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID) +{ + myErrorStatus=0; + // + int aNb; + // + aNb=myShapeIDMap.Extent(); + if (theID<1 || theID>aNb) { + myErrorStatus=3; // ID is out of range + return myEmptyShape; + } + // + const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID); + return aS; +} diff --git a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx new file mode 100644 index 000000000..090f0a7d2 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx @@ -0,0 +1,66 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Arithmetic1D_i.hxx +// Author : Damien COQUERET, OCC +// Module : SMESH +// $Header$ + +#ifndef _SMESH_ARITHMETIC1D_I_HXX_ +#define _SMESH_ARITHMETIC1D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_Arithmetic1D.hxx" + +// ====================================================== +// Arithmetic 1D hypothesis +// ====================================================== +class StdMeshers_Arithmetic1D_i: + public virtual POA_StdMeshers::StdMeshers_Arithmetic1D, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_Arithmetic1D_i(); + + // Set length + void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) + throw ( SALOME::SALOME_Exception ); + // Get length + CORBA::Double GetLength(CORBA::Boolean theIsStart); + + // Get implementation + ::StdMeshers_Arithmetic1D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx b/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx new file mode 100644 index 000000000..138b1d9cf --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx @@ -0,0 +1,70 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Deflection1D_i.hxx +// Moved here from SMESH_LocalLength_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_Deflection1D_I_HXX_ +#define _SMESH_Deflection1D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_Deflection1D.hxx" + +class SMESH_Gen; + +// ====================================================== +// Local Length hypothesis +// ====================================================== +class StdMeshers_Deflection1D_i: + public virtual POA_StdMeshers::StdMeshers_Deflection1D, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_Deflection1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_Deflection1D_i(); + + // Set deflection + void SetDeflection( CORBA::Double theLength ) + throw ( SALOME::SALOME_Exception ); + // Get deflection + CORBA::Double GetDeflection(); + + // Get implementation + ::StdMeshers_Deflection1D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx new file mode 100644 index 000000000..35d871c56 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx @@ -0,0 +1,135 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LengthFromEdges_i.cxx +// Moved here from SMESH_LengthFromEdges_i.cxx +// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_LengthFromEdges_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" ); + myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i() +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i" ); +} + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::SetMode + * + * Set mode + */ +//============================================================================= + +void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode ) + throw (SALOME::SALOME_Exception) +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::SetMode" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetMode( theMode ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::GetMode + * + * Get mode + */ +//============================================================================= + +CORBA::Long StdMeshers_LengthFromEdges_i::GetMode() +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::GetMode" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetMode(); +} + + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_LengthFromEdges* StdMeshers_LengthFromEdges_i::GetImpl() +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::GetImpl" ); + return ( ::StdMeshers_LengthFromEdges* )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_LengthFromEdges_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} + diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx new file mode 100644 index 000000000..1075278d7 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx @@ -0,0 +1,68 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LengthFromEdges_i.hxx +// Moved here from SMESH_LengthFromEdges_i.hxx +// Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_LENGTHFROMEDGES_I_HXX_ +#define _SMESH_LENGTHFROMEDGES_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_LengthFromEdges.hxx" + +// ====================================================== +// Length from edges hypothesis +// ====================================================== +class StdMeshers_LengthFromEdges_i: + public virtual POA_StdMeshers::StdMeshers_LengthFromEdges, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_LengthFromEdges_i(); + + // Set mode + void SetMode( CORBA::Long theMode ) + throw ( SALOME::SALOME_Exception ); + // Get mode + CORBA::Long GetMode(); + + // Get implementation + ::StdMeshers_LengthFromEdges* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx new file mode 100644 index 000000000..f0b6b21e6 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx @@ -0,0 +1,70 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LocalLength_i.hxx +// Moved here from SMESH_LocalLength_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_LOCALLENGTH_I_HXX_ +#define _SMESH_LOCALLENGTH_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_LocalLength.hxx" + +class SMESH_Gen; + +// ====================================================== +// Local Length hypothesis +// ====================================================== +class StdMeshers_LocalLength_i: + public virtual POA_StdMeshers::StdMeshers_LocalLength, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_LocalLength_i(); + + // Set length + void SetLength( CORBA::Double theLength ) + throw ( SALOME::SALOME_Exception ); + // Get length + CORBA::Double GetLength(); + + // Get implementation + ::StdMeshers_LocalLength* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx new file mode 100644 index 000000000..39dde7639 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx @@ -0,0 +1,67 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementArea_i.hxx +// Moved here from SMESH_MaxElementArea_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_MAXELEMENTAREA_I_HXX_ +#define _SMESH_MAXELEMENTAREA_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_MaxElementArea.hxx" + +// ====================================================== +// Maximum Element Area hypothesis +// ====================================================== +class StdMeshers_MaxElementArea_i: + public virtual POA_StdMeshers::StdMeshers_MaxElementArea, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_MaxElementArea_i(); + + // Set maximum element area + void SetMaxElementArea( CORBA::Double theArea ) + throw ( SALOME::SALOME_Exception ); + // Get maximum element area + CORBA::Double GetMaxElementArea(); + + // Get implementation + ::StdMeshers_MaxElementArea* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx new file mode 100644 index 000000000..928fab59a --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx @@ -0,0 +1,67 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementVolume_i.hxx +// Moved here from SMESH_MaxElementVolume_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_ +#define _SMESH_MAXELEMENTVOLUME_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_MaxElementVolume.hxx" + +// ====================================================== +// Maximum Element Volume hypothesis +// ====================================================== +class StdMeshers_MaxElementVolume_i: + public virtual POA_StdMeshers::StdMeshers_MaxElementVolume, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_MaxElementVolume_i(); + + // Set maximum element volume + void SetMaxElementVolume( CORBA::Double theVolume ) + throw (SALOME::SALOME_Exception); + // Get maximum element volume + CORBA::Double GetMaxElementVolume(); + + // Get implementation + ::StdMeshers_MaxElementVolume* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx new file mode 100644 index 000000000..8940cf7a7 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx @@ -0,0 +1,81 @@ +// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NotConformAllowed_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +using namespace std; +#include "StdMeshers_NotConformAllowed_i.hxx" +#include "SMESH_Gen.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * Constructor: + * _name is related to the class name: prefix = SMESH_ ; suffix = _i . + */ +//============================================================================= + +StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i + (PortableServer::POA_ptr thePOA, + int studyId, + ::SMESH_Gen* genImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE("StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i"); + myBaseImpl = new ::StdMeshers_NotConformAllowed(genImpl->GetANewId(), + studyId, + genImpl); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_NotConformAllowed_i::~StdMeshers_NotConformAllowed_i() +{ +} + +//================================================================================ +/*! + * \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_NotConformAllowed_i::IsDimSupported( SMESH::Dimension /*type*/ ) +{ + return true; +} + + + diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx new file mode 100644 index 000000000..ceddb3287 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx @@ -0,0 +1,57 @@ +// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NotConformAllowed_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _StdMeshers_NotConformAllowed_I_HXX_ +#define _StdMeshers_NotConformAllowed_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" + +#include "StdMeshers_NotConformAllowed.hxx" + +class StdMeshers_NotConformAllowed_i: + public POA_StdMeshers::StdMeshers_NotConformAllowed, + public SMESH_Hypothesis_i +{ +public: + StdMeshers_NotConformAllowed_i(PortableServer::POA_ptr thePOA, + int studyId, + ::SMESH_Gen* genImpl); + virtual ~StdMeshers_NotConformAllowed_i(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + +protected: + ::StdMeshers_NotConformAllowed* _impl; +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.cxx b/src/StdMeshers_I/StdMeshers_Propagation_i.cxx new file mode 100644 index 000000000..4e038748c --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Propagation_i.cxx @@ -0,0 +1,91 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 CEA +// +// 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.org +// +// +// +// File : StdMeshers_Propagation_i.cxx +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_Propagation_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_Propagation_i::StdMeshers_Propagation_i + * + * Constructor + */ +//============================================================================= +StdMeshers_Propagation_i::StdMeshers_Propagation_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_Propagation_i::StdMeshers_Propagation_i" ); + myBaseImpl = new ::StdMeshers_Propagation(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_Propagation_i::~StdMeshers_Propagation_i + * + * Destructor + */ +//============================================================================= +StdMeshers_Propagation_i::~StdMeshers_Propagation_i() +{ + MESSAGE( "StdMeshers_Propagation_i::~StdMeshers_Propagation_i" ); +} + +//============================================================================= +/*! + * StdMeshers_Propagation_i::GetImpl + * + * Get implementation + */ +//============================================================================= +::StdMeshers_Propagation* StdMeshers_Propagation_i::GetImpl() +{ + MESSAGE( "StdMeshers_Propagation_i::GetImpl" ); + return ( ::StdMeshers_Propagation* )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_Propagation_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.hxx b/src/StdMeshers_I/StdMeshers_Propagation_i.hxx new file mode 100644 index 000000000..ca130bc2f --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Propagation_i.hxx @@ -0,0 +1,60 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 CEA +// +// 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.org +// +// +// +// File : StdMeshers_Propagation_i.hxx +// Module : SMESH +// $Header$ + +#ifndef _SMESH_PROPAGATION_I_HXX_ +#define _SMESH_PROPAGATION_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_Propagation.hxx" + +class SMESH_Gen; + +// ====================================================== +// Propagation hypothesis +// ====================================================== +class StdMeshers_Propagation_i: + public virtual POA_StdMeshers::StdMeshers_Propagation, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_Propagation_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + // Destructor + virtual ~StdMeshers_Propagation_i(); + + // Get implementation + ::StdMeshers_Propagation* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx b/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx new file mode 100644 index 000000000..d937f9390 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx @@ -0,0 +1,70 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_StartEndLength_i.hxx +// Moved here from SMESH_LocalLength_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_StartEndLength_I_HXX_ +#define _SMESH_StartEndLength_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_StartEndLength.hxx" + +class SMESH_Gen; + +// ====================================================== +// Local Length hypothesis +// ====================================================== +class StdMeshers_StartEndLength_i: + public virtual POA_StdMeshers::StdMeshers_StartEndLength, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_StartEndLength_i(PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_StartEndLength_i(); + + // Set length + void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) + throw ( SALOME::SALOME_Exception ); + // Get length + CORBA::Double GetLength(CORBA::Boolean theIsStart); + + // Get implementation + ::StdMeshers_StartEndLength* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif +