X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Measurements_i.cxx;h=ce71af650a3a13297a0f9eaa3990ef839a5441a4;hp=8da1cd7cf9c4b944f293a54e1319fa537968b978;hb=61bac50f78623aabd9e4ddbcbba072c63ea02165;hpb=20248b6e76a67595f7f449a71ebbf18c13429389 diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx index 8da1cd7cf..ce71af650 100644 --- a/src/SMESH_I/SMESH_Measurements_i.cxx +++ b/src/SMESH_I/SMESH_Measurements_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 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 @@ -24,19 +24,19 @@ #include "SMESH_Measurements_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_Filter_i.hxx" -#include "SMESH_PythonDump.hxx" - +#include "SMDS_ElemIterator.hxx" #include "SMDS_Mesh.hxx" -#include "SMDS_MeshNode.hxx" #include "SMDS_MeshElement.hxx" -#include "SMDS_ElemIterator.hxx" - +#include "SMDS_MeshNode.hxx" #include "SMESHDS_Mesh.hxx" +#include "SMESH_Filter_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_MeshAlgos.hxx" +#include "SMESH_PythonDump.hxx" +#include -using namespace SMESH; +//using namespace SMESH; /** * this local function to avoid uninitialized fields @@ -76,7 +76,7 @@ SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements() // name : Measurements_i // Purpose : Constructor //======================================================================= -Measurements_i::Measurements_i() +SMESH::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 @@ -88,7 +88,7 @@ Measurements_i::Measurements_i() // name : ~Measurements_i // Purpose : Destructor //======================================================================= -Measurements_i::~Measurements_i() +SMESH::Measurements_i::~Measurements_i() { //TPythonDump()<Project( point, SMDSAbs_All, &closestElement ); + + if ( closestElement ) + { + theMeasure.value = point.Distance( closestPoint ); + theMeasure.node1 = theNode->GetID(); + theMeasure.elem2 = closestElement->GetID(); + theMeasure.maxX = closestPoint.X(); + theMeasure.maxY = closestPoint.Y(); + theMeasure.maxZ = closestPoint.Z(); + theMeasure.minX = closestPoint.X() - point.X(); + theMeasure.minY = closestPoint.Y() - point.Y(); + theMeasure.minZ = closestPoint.Z() - point.Z(); + } + + return closestElement; +} + static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource) { if (!CORBA::is_nil( theSource )) { - SMESH_Mesh_i* anImplPtr = DownCast(theSource->GetMesh()); + SMESH::SMESH_Mesh_var mesh = theSource->GetMesh(); + SMESH_Mesh_i* anImplPtr = SMESH::DownCast( mesh ); if (anImplPtr) return anImplPtr->GetImpl().GetMeshDS(); } @@ -142,7 +170,7 @@ static double getNumericalValue(SMESH::SMESH_IDSource_ptr theSource, if ( aMesh ) { theFunctor->SetMesh( aMesh ); - SMESH::long_array_var anElementsId = theSource->GetIDs(); + SMESH::smIdType_array_var anElementsId = theSource->GetIDs(); for ( CORBA::ULong i = 0; i < anElementsId->length(); i++) { value += theFunctor->GetValue( anElementsId[i] ); } @@ -155,7 +183,7 @@ static double getNumericalValue(SMESH::SMESH_IDSource_ptr theSource, // name : MinDistance // Purpose : minimal distance between two given entities //======================================================================= -SMESH::Measure Measurements_i::MinDistance +SMESH::Measure SMESH::Measurements_i::MinDistance (SMESH::SMESH_IDSource_ptr theSource1, SMESH::SMESH_IDSource_ptr theSource2) { @@ -177,9 +205,8 @@ SMESH::Measure Measurements_i::MinDistance bool isNode1 = isNodeType(types1); bool isNode2 = isOrigin || isNodeType(types2); - SMESH::long_array_var aElementsId1 = theSource1->GetIDs(); - SMESH::long_array_var aElementsId2; - if ( !isOrigin ) aElementsId2 = theSource2->GetIDs(); + SMESH::smIdType_array_var aElementsId1 = theSource1->GetIDs(); + SMESH::smIdType_array_var aElementsId2; // compute distance between two entities /* NOTE: currently only node-to-node case is implemented @@ -192,10 +219,25 @@ SMESH::Measure Measurements_i::MinDistance // node - node const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 ); const SMESHDS_Mesh* aMesh2 = isOrigin ? 0 : getMesh( theSource2 ); + if ( !isOrigin ) aElementsId2 = theSource2->GetIDs(); const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0; const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0; getNodeNodeDistance( aMeasure, theNode1, theNode2 ); } + if (isNode1 && !isNode2 && aElementsId1->length() == 1 ) + { + // node - elements + SMESHDS_Mesh* aMesh1 = getMesh( theSource1 ); + SMESHDS_Mesh* aMesh2 = getMesh( theSource2 ); + if ( aMesh1 && aMesh2 ) + { + const SMDS_MeshNode* aNode = aMesh1->FindNode( aElementsId1[0] ); + SMDS_ElemIteratorPtr anElemIt = SMESH_Mesh_i::GetElements( theSource2, SMESH::ALL ); + std::unique_ptr< SMESH_ElementSearcher > aSearcher + ( SMESH_MeshAlgos::GetElementSearcher( *aMesh2, anElemIt )); + getNodeElemDistance( aMeasure, aNode, aSearcher.get() ); + } + } else { // NOT_IMPLEMENTED @@ -242,31 +284,37 @@ static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, 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 (SMESH::DownCast( theObject )) // theObject is mesh + { + for (SMDS_NodeIteratorPtr aNodeIter = aMesh->nodesIterator(); aNodeIter->more(); ) + enlargeBoundingBox( aNodeIter->next(), theMeasure); + } + else { - if (isNode) - enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure); - else + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::smIdType_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++) { - const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] ); - if (!elem) - continue; - SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator(); - while( aNodeIter->more() ) - enlargeBoundingBox( dynamic_cast( aNodeIter->next() ), theMeasure); + if (isNode) + enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure); + else + { + if ( const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] )) + for (SMDS_NodeIteratorPtr aNodeIter = elem->nodeIterator(); aNodeIter->more(); ) + enlargeBoundingBox( aNodeIter->next(), theMeasure); + } } } } - + //======================================================================= // name : BoundingBox // Purpose : compute common bounding box of entities //======================================================================= -SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) +SMESH::Measure SMESH::Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) { SMESH::Measure aMeasure; initMeasure(aMeasure); @@ -282,7 +330,7 @@ SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSou // name : Length // Purpose : sum of length of 1D elements of the source //======================================================================= -double Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Length()) ); } @@ -291,7 +339,7 @@ double Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) // name : Area // Purpose : sum of area of 2D elements of the source //======================================================================= -double Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Area()) ); } @@ -300,7 +348,76 @@ double Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) // name : Volume // Purpose : sum of volume of 3D elements of the source //======================================================================= -double Measurements_i::Volume(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Volume(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Volume()) ); } + +//======================================================================= +//function : GravityCenter +//purpose : return gravity center of the source: average coordinates of all nodes +//======================================================================= + +SMESH::PointStruct SMESH::Measurements_i::GravityCenter(SMESH::SMESH_IDSource_ptr theSource) +{ + SMESH::PointStruct grCenter = { 0.,0.,0. }; + const SMESHDS_Mesh* mesh = getMesh( theSource ); + if ( !mesh ) + return grCenter; + + // unmark all nodes; visited nodes will be marked + SMESH_MeshAlgos::MarkElems( mesh->nodesIterator(), /*isMarked=*/false ); + + gp_XYZ sumCoord( 0,0,0 ); + int nodeCount = 0; + + SMDS_ElemIteratorPtr eIt = SMESH_Mesh_i::GetElements( theSource, SMESH::ALL ); + while ( eIt->more() ) + { + const SMDS_MeshElement* elem = eIt->next(); + for ( SMDS_NodeIteratorPtr nIt = elem->nodeIterator(); nIt->more(); ) + { + const SMDS_MeshNode* n = nIt->next(); + if ( !n->isMarked() ) + { + sumCoord += SMESH_NodeXYZ( n ); + ++nodeCount; + n->setIsMarked( true ); + } + } + } + sumCoord /= nodeCount; + + grCenter.x = sumCoord.X(); + grCenter.y = sumCoord.Y(); + grCenter.z = sumCoord.Z(); + + return grCenter; +} + +//======================================================================= +//function : Angle +//purpose : Return angle in radians defined by 3 points <(p1,p2,p3) +//======================================================================= + +CORBA::Double SMESH::Measurements_i::Angle(const SMESH::PointStruct& p1, + const SMESH::PointStruct& p2, + const SMESH::PointStruct& p3 ) +{ + gp_Vec v1( p1.x - p2.x, p1.y - p2.y, p1.z - p2.z ); + gp_Vec v2( p3.x - p2.x, p3.y - p2.y, p3.z - p2.z ); + + double angle = -1; + + try + { + angle = v1.Angle( v2 ); + } + catch(...) + { + } + if ( std::isnan( angle )) + angle = -1; + + return angle; +}