0020885: EDF 607 SMESH: Measure tools

This commit is contained in:
ptv 2010-11-01 10:09:14 +00:00
parent 5ba9e5dffc
commit e69dd23c49
12 changed files with 416 additions and 4 deletions

View File

@ -32,7 +32,8 @@ BASEIDL_FILES = \
SMESH_Filter.idl \
SMESH_Group.idl \
SMESH_Pattern.idl \
SMESH_MeshEditor.idl
SMESH_MeshEditor.idl \
SMESH_Measurements.idl
# This variable defines the files to be installed
dist_salomeidl_DATA = $(BASEIDL_FILES)
@ -49,7 +50,8 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \
SMESH_FilterSK.cc \
SMESH_GroupSK.cc \
SMESH_PatternSK.cc \
SMESH_MeshEditorSK.cc
SMESH_MeshEditorSK.cc \
SMESH_MeasurementsSK.cc
# header files must be exported: other modules have to use this library
nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh)

View File

@ -42,6 +42,7 @@ module SMESH
interface FilterManager;
interface SMESH_Pattern;
interface Measurements;
/*!
* Tags definition
@ -119,6 +120,8 @@ module SMESH
SMESH_Pattern GetPattern();
Measurements CreateMeasurements();
/*!
Set the current mode
*/

View File

@ -122,6 +122,7 @@
#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
#include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
#include CORBA_CLIENT_HEADER(SMESH_Measurements)
// Qt includes
// #define INCLUDE_MENUITEM_DEF // VSR commented ????????
@ -1433,6 +1434,7 @@ LightApp_Module( "SMESH" )
SMESH::GetFilterManager();
SMESH::GetPattern();
SMESH::GetMeasurements();
/* load resources for all available meshers */
SMESH::InitAvailableHypotheses();
@ -1447,8 +1449,10 @@ SMESHGUI::~SMESHGUI()
{
#ifdef WITHGENERICOBJ
SMESH::GetFilterManager()->Destroy();
SMESH::GetMeasurements()->Destroy();
#endif
SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
SMESH::GetMeasurements() = SMESH::Measurements::_nil();
}
//=============================================================================

View File

@ -27,6 +27,7 @@
//
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
// SALOME KERNEL includes
@ -38,6 +39,7 @@
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Measurements)
namespace SMESH
{
@ -82,4 +84,14 @@ namespace SMESH
}
return baseName;
}
SMESH::Measurements_var& GetMeasurements()
{
static SMESH::Measurements_var aMeasurements;
if (CORBA::is_nil(aMeasurements)) {
aMeasurements = SMESHGUI::GetSMESHGen()->CreateMeasurements();
}
return aMeasurements;
}
} // end of namespace SMESH

View File

@ -39,6 +39,7 @@
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
#include CORBA_SERVER_HEADER(SMESH_Measurements)
namespace SMESH
{
@ -47,6 +48,8 @@ namespace SMESH
SMESHGUI_EXPORT
QString UniqueMeshName( const QString&, const QString& = QString() );
SMESHGUI_EXPORT SMESH::Measurements_var& GetMeasurements();
}
#endif // SMESHGUI_MESHUTILS_H

View File

@ -46,6 +46,7 @@ salomeinclude_HEADERS = \
SMESH_Pattern_i.hxx \
SMESH_2smeshpy.hxx \
SMESH_NoteBook.hxx \
SMESH_Measurements_i.hxx \
SMESH.hxx
# Scripts to be installed.
@ -76,7 +77,8 @@ dist_libSMESHEngine_la_SOURCES = \
SMESH_Group_i.cxx \
SMESH_Pattern_i.cxx \
SMESH_2smeshpy.cxx \
SMESH_NoteBook.cxx
SMESH_NoteBook.cxx \
SMESH_Measurements_i.cxx
# Executables targets
bin_PROGRAMS = SMESHEngine

View File

@ -308,6 +308,15 @@ namespace SMESH
return *this;
}
TPythonDump&
TPythonDump::
operator<<(SMESH::Measurements_i* theArg)
{
myStream<<"aMeasurements";
return *this;
}
TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg)
{
myStream << SMESHGenName(); return *this;
@ -685,6 +694,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
TCollection_AsciiString aScript;
aScript = "def RebuildData(theStudy):\n\t";
aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t";
aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t";
if ( isPublished )
aScript += aSMESHGen + ".SetCurrentStudy(theStudy)";
else

View File

@ -223,7 +223,7 @@ public:
SMESH::SMESH_Mesh_ptr CreateEmptyMesh()
throw ( SALOME::SALOME_Exception );
// Create mesh(es) and import data from UNV file
// Create mesh(es) and import data from UNV fileter
SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName )
throw ( SALOME::SALOME_Exception );
@ -357,6 +357,9 @@ public:
// Return a pattern mesher
SMESH::SMESH_Pattern_ptr GetPattern();
// Create measurement instance
SMESH::Measurements_ptr CreateMeasurements();
// Clears study-connected data when it is closed
void Close( SALOMEDS::SComponent_ptr theComponent );

View File

@ -0,0 +1,243 @@
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : SMESH_Filter_i.cxx
// Author : Alexey Petrov, OCC
// Module : SMESH
//
#include "SMESH_Measurements_i.hxx"
#include "SMESH_Gen_i.hxx"
#include "SMESH_PythonDump.hxx"
#include "SMDS_Mesh.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_ElemIterator.hxx"
#include "SMESHDS_Mesh.hxx"
using namespace SMESH;
/**
* this local function to avoid uninitialized fields
*/
static void initMeasure( SMESH::Measure& theMeasure)
{
theMeasure.minX = theMeasure.minY = theMeasure.minZ = 0.;
theMeasure.maxX = theMeasure.maxY = theMeasure.maxZ = 0.;
theMeasure.node1 = theMeasure.node2 = -1;
theMeasure.elem1 = theMeasure.elem2 = -1;
theMeasure.value = 0.;
}
//=============================================================================
/*!
* SMESH_Gen_i::CreateMeasurements
*
* Create measurement instance
*/
//=============================================================================
SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements()
{
SMESH::Measurements_i* aMeasure = new SMESH::Measurements_i();
SMESH::Measurements_var anObj = aMeasure->_this();
return anObj._retn();
}
/*
Class : Measurements
Description : make measure of mesh qunatities
*/
//=======================================================================
// name : Measurements_i
// Purpose : Constructor
//=======================================================================
Measurements_i::Measurements_i()
: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
{
//Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
//PortableServer::ObjectId_var anObjectId =
// SMESH_Gen_i::GetPOA()->activate_object( this );
}
//=======================================================================
// name : ~Measurements_i
// Purpose : Destructor
//=======================================================================
Measurements_i::~Measurements_i()
{
//TPythonDump()<<this<<".Destroy()";
}
static double getNodeNodeDistance (const SMDS_MeshNode* theNode1,
const SMDS_MeshNode* theNode2)
{
double dist = 0., dd = 0.;
if (!theNode1 || !theNode2)
return dist;
dd = theNode1->X(); dd -= theNode2->X(); dd *= dd; dist += dd;
dd = theNode1->Y(); dd -= theNode2->Y(); dd *= dd; dist += dd;
dd = theNode1->Z(); dd -= theNode2->Z(); dd *= dd; dist += dd;
if (dist < 0)
return 0;
return sqrt(dist);
}
static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource)
{
if (!CORBA::is_nil( theSource ))
{
SMESH_Mesh_i* anImplPtr = DownCast<SMESH_Mesh_i*>(theSource->GetMesh());
if (anImplPtr)
return anImplPtr->GetImpl().GetMeshDS();
}
return 0;
}
static bool isNodeType (SMESH::array_of_ElementType_var theTypes)
{
return theTypes->length() > 0 && theTypes[0] == SMESH::NODE;
}
//=======================================================================
// name : MinDistance
// Purpose : minimal distance between two given entities
//=======================================================================
SMESH::Measure Measurements_i::MinDistance
(SMESH::SMESH_IDSource_ptr theSource1,
SMESH::SMESH_IDSource_ptr theSource2)
{
SMESH::Measure aMeasure;
initMeasure(aMeasure);
if (CORBA::is_nil( theSource1 ) || CORBA::is_nil( theSource2 ))
return aMeasure;
// calculate minimal distance between two mesh entities
SMESH::array_of_ElementType_var types1 = theSource1->GetTypes();
SMESH::array_of_ElementType_var types2 = theSource2->GetTypes();
// here we assume that type of all IDs defined by first type in array
const bool isNode1 = isNodeType(types1);
const bool isNode2 = isNodeType(types2);
SMESH::long_array_var aElementsId1 = theSource1->GetIDs();
SMESH::long_array_var aElementsId2 = theSource2->GetIDs();
// compute distance between two entities
/** NOTE: currently only node-node case implemented
* all other cases could be implemented later
* this IF should be replaced by comples swtich
* on mesh entities types
*/
if (isNode1 && isNode2)
{
// node - node
const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 );
const SMESHDS_Mesh* aMesh2 = getMesh( theSource2 );
const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0;
const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0;
aMeasure.value = getNodeNodeDistance( theNode1, theNode2 );
if (theNode1 && theNode2)
{
aMeasure.node1 = theNode1->GetID();
aMeasure.node2 = theNode2->GetID();
}
}
else
{
// NOT_IMPLEMENTED
}
return aMeasure;
}
//=======================================================================
// name : enlargeBoundingBox
// Purpose :
//=======================================================================
static void enlargeBoundingBox(const SMDS_MeshNode* theNode,
SMESH::Measure& theMeasure)
{
if (!theNode)
return;
theMeasure.minX = min( theMeasure.minX, theNode->X() );
theMeasure.maxX = max( theMeasure.maxX, theNode->X() );
theMeasure.minY = min( theMeasure.minY, theNode->Y() );
theMeasure.maxY = max( theMeasure.maxY, theNode->Y() );
theMeasure.minZ = min( theMeasure.minZ, theNode->Z() );
theMeasure.maxZ = max( theMeasure.maxZ, theNode->Z() );
}
//=======================================================================
// name : enlargeBoundingBox
// Purpose :
//=======================================================================
static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject,
SMESH::Measure& theMeasure)
{
if ( CORBA::is_nil( theObject ) )
return;
const SMESHDS_Mesh* aMesh = getMesh( theObject );
if ( !aMesh )
return;
SMESH::array_of_ElementType_var types = theObject->GetTypes();
SMESH::long_array_var aElementsId = theObject->GetIDs();
// here we assume that type of all IDs defined by first type in array
const bool isNode = isNodeType( types );
for(int i = 0, n = aElementsId->length(); i < n; i++)
{
if (isNode)
enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure);
else
{
const SMDS_MeshElement * elem = aMesh->FindElement( aElementsId[i] );
if (!elem)
continue;
SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator();
while( aNodeIter->more() )
enlargeBoundingBox( dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() ), theMeasure);
}
}
}
//=======================================================================
// name : BoundingBox
// Purpose : compute common bounding box of entities
//=======================================================================
SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources)
{
SMESH::Measure aMeasure;
initMeasure(aMeasure);
// calculate bounding box on sources
for ( int i = 0, n = theSources.length(); i < n ; ++i )
enlargeBoundingBox( theSources[i], aMeasure );
return aMeasure;
}

View File

@ -0,0 +1,66 @@
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : SMESH_Measurements_i.hxx
// Author : Pavel Telkov, OCC
// Module : SMESH
//
#ifndef _SMESH_MEASUREMENTS_I_HXX_
#define _SMESH_MEASUREMENTS_I_HXX_
#include "SMESH.hxx"
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Measurements)
#include "SALOME_GenericObj_i.hh"
class SMESHDS_Mesh;
namespace SMESH
{
/*
Measurements
*/
class SMESH_I_EXPORT Measurements_i: public virtual POA_SMESH::Measurements,
public virtual SALOME::GenericObj_i
{
public:
Measurements_i();
~Measurements_i();
/*!
* minimal distance between two given entities
*/
SMESH::Measure MinDistance(SMESH::SMESH_IDSource_ptr theSource1,
SMESH::SMESH_IDSource_ptr theSource2);
/*!
* common bounding box of entities
*/
SMESH::Measure BoundingBox(const SMESH::ListOfIDSources& theSources);
};
}
#endif

View File

@ -73,6 +73,7 @@ namespace SMESH
class FilterManager_i;
class Filter_i;
class Functor_i;
class Measurements_i;
// ===========================================================================================
/*!
@ -142,6 +143,9 @@ namespace SMESH
TPythonDump&
operator<<(SMESH::Functor_i* theArg);
TPythonDump&
operator<<(SMESH::Measurements_i* theArg);
TPythonDump&
operator<<(SMESH_Gen_i* theArg);

View File

@ -842,6 +842,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
aCriteria = []
aCriteria.append(aCriterion)
aFilter.SetCriteria(aCriteria)
aFilterMgr.Destroy()
return aFilter
## Creates a numerical functor by its type
@ -1628,6 +1629,7 @@ class Mesh:
aCriteria.append(Criterion)
aFilter.SetCriteria(aCriteria)
group = self.MakeGroupByFilter(groupName, aFilter)
aFilterMgr.Destroy()
return group
## Creates a mesh group by the given criteria (list of criteria)
@ -1640,6 +1642,7 @@ class Mesh:
aFilter = aFilterMgr.CreateFilter()
aFilter.SetCriteria(theCriteria)
group = self.MakeGroupByFilter(groupName, aFilter)
aFilterMgr.Destroy()
return group
## Creates a mesh group by the given filter
@ -1669,6 +1672,7 @@ class Mesh:
aPredicate = aFilterMgr.CreateFreeEdges()
aPredicate.SetMesh(self.mesh)
aBorders = aPredicate.GetBorders()
aFilterMgr.Destroy()
return aBorders
## Removes a group
@ -2188,6 +2192,62 @@ class Mesh:
return self.mesh.BaryCenter(id)
# Get mesh measurements information:
# ------------------------------------
def MinDistance(self, id1, id2, isElem1=False, isElem2=False):
aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
return aMeasure.value
# @param node1, node2 is nodes to measure distance
# @return Measure structure
def GetMinDistance(self, id1, id2, isElem1=False, isElem2=False):
if isinstance( id1, int):
if (isElem1):
id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
else:
id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
if isinstance( id2, int):
if (isElem2):
id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
else:
id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
aMeasurements = self.smeshpyD.CreateMeasurements()
aMeasure = aMeasurements.MinDistance(id1, id2)
aMeasurements.Destroy()
return aMeasure
# @param IDsOfElements is a list of ids of elements or nodes
# @return Measure structure
def GetBoundingBox(self, IDs = None, isElem=True):
if isinstance( IDs, Mesh ):
IDs = [ IDs.mesh ]
elif (IDs == None):
IDs = [ self.mesh ]
elif isinstance( IDs, int):
if (isElem):
IDs = [ self.editor.MakeIDSource(IDs, SMESH.FACE) ]
else:
IDs = [ self.editor.MakeIDSource(IDs, SMESH.NODE) ]
elif isinstance( IDs, list ) and isinstance( IDs[0], int):
if (isElem):
IDs = [ self.editor.MakeIDSource(IDs, SMESH.FACE) ]
else:
IDs = [ self.editor.MakeIDSource(IDs, SMESH.NODE) ]
elif hasattr(IDs, "_narrow"):
anIDs = IDs._narrow(SMESH.SMESH_IDSource)
if (anIDs):
IDs = [ anIDs ]
aMeasure = None
if isinstance(IDs, list):
aMeasurements = self.smeshpyD.CreateMeasurements()
aMeasure = aMeasurements.BoundingBox(IDs)
aMeasurements.Destroy()
return aMeasure
# Mesh edition (SMESH_MeshEditor functionality):
# ---------------------------------------------