Enable FrontTrack for CAO boundaries

This commit is contained in:
jfa 2021-12-21 10:01:40 +03:00
parent a16cda24fd
commit 010b8a9efd
4 changed files with 2052 additions and 24 deletions

File diff suppressed because it is too large Load Diff

View File

@ -53,14 +53,29 @@
#include <vector>
#include <string>
#include <list>
#include <map>
#include <iostream>
#include <fstream>
#include <TopoDS_Shape.hxx>
#include <Bnd_Box.hxx>
#include <NCollection_DataMap.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
#if defined WIN32
#pragma warning ( disable: 4251 )
#endif
namespace MEDCoupling {
class DataArrayDouble;
}
namespace XAO {
class Xao;
class Group;
class BrepGeometry;
}
namespace SMESHHOMARDImpl
{
@ -472,6 +487,240 @@ private:
std::list<std::string> _ListFieldInterpTSR;
};
// HOMARD/FrontTrack
class FrontTrack
{
public:
/*!
* \brief Relocate nodes to lie on geometry
* \param [in] theInputMedFile - a MED file holding a mesh including nodes that will be
* moved onto the geometry
* \param [in] theOutputMedFile - a MED file to create, that will hold a modified mesh
* \param [in] theInputNodeFiles - an array of names of files describing groups of nodes that
* will be moved onto the geometry
* \param [in] theXaoFileName - a path to a file in XAO format holding the geometry and
* the geometrical groups.
* \param [in] theIsParallel - if \c true, all processors are used to treat boundary shapes
* in parallel.
*/
void track( const std::string& theInputMedFile,
const std::string& theOutputMedFile,
const std::vector< std::string > & theInputNodeFiles,
const std::string& theXaoFileName,
bool theIsParallel=true);
};
struct FT_RealProjector;
/*!
* \brief Projector of a point to a boundary shape. Wrapper of a real projection algo
*/
class FT_Projector
{
public:
FT_Projector(const TopoDS_Shape& shape = TopoDS_Shape());
FT_Projector(const FT_Projector& other);
~FT_Projector();
// initialize with a boundary shape, compute the bounding box
void setBoundaryShape(const TopoDS_Shape& shape);
// return the boundary shape
const TopoDS_Shape& getShape() const { return _shape; }
// return the bounding box
const Bnd_Box getBoundingBox() const { return _bndBox; }
// create a real projector
void prepareForProjection();
// return true if a previously found solution can be used to speed up the projection
bool canUsePrevSolution() const;
// return true if projection is not needed
bool isPlanarBoundary() const;
// switch a mode of usage of prevSolution.
// If projection fails, to try to project without usage of prevSolution.
// By default this mode is off
void tryWithoutPrevSolution( bool toTry ) { _tryWOPrevSolution = toTry; }
// project a point to the boundary shape
bool project( const gp_Pnt& point,
const double maxDist2,
gp_Pnt& projection,
double* newSolution,
const double* prevSolution = 0);
// project a point to the boundary shape and check if the projection is within the shape boundary
bool projectAndClassify( const gp_Pnt& point,
const double maxDist2,
gp_Pnt& projection,
double* newSolution,
const double* prevSolution = 0);
// check if a point lies on the boundary shape
bool isOnShape( const gp_Pnt& point,
const double tol2,
double* newSolution,
const double* prevSolution = 0);
private:
FT_RealProjector* _realProjector;
Bnd_Box _bndBox;
TopoDS_Shape _shape;
bool _tryWOPrevSolution;
};
namespace FT_Utils
{
// Check if a file exists
bool fileExists( const std::string& path );
// Check if a file can be created/overwritten
bool canWrite( const std::string& path );
// Transform anything printable to a string
template< typename T> std::string toStr( const T& t )
{
std::ostringstream s;
s << t;
return s.str();
}
//--------------------------------------------------------------------------------------------
/*!
* \brief Return projectors by group name
*/
struct XaoGroups
{
XaoGroups( const XAO::Xao* xao );
int getProjectors( const std::string& groupName,
const int dim,
const std::vector< FT_Projector > & allProjectors,
std::vector< const FT_Projector* > & groupProjectors ) const;
private:
typedef std::multimap< std::string, XAO::Group* > TGroupByNameMap;
TGroupByNameMap _xaoGroups[ 2 ]; // by dim
};
} // namespace FT_Utils
/*!
* \brief Node group and geometry to project onto
*/
class FT_NodesOnGeom
{
public:
// read node IDs form a file and try to find a boundary sub-shape by name
void read( const std::string& nodesFile,
const FT_Utils::XaoGroups& xaoGroups,
MEDCoupling::DataArrayDouble* nodeCoords,
std::vector< FT_Projector > * allProjectorsByDim);
// chose boundary shapes by evaluating distance between nodes and shapes
//void choseShape( const std::vector< FT_Utils::ShapeAndBndBox >& shapeAndBoxList );
// project nodes to the shapes and move them to new positions
void projectAndMove();
// return true if all nodes were successfully relocated
bool isOK() const { return _OK; }
// return dimension of boundary shapes
int getShapeDim() const { return _shapeDim; }
// return nb of nodes to move
int nbNodes() const { return _nodes.size(); }
private:
// put nodes in the order for optimal projection
void putNodesInOrder();
// get node coordinates
gp_Pnt getPoint( const int nodeID );
// change node coordinates
void moveNode( const int nodeID, const gp_Pnt& xyz );
// Ids of a node to move and its 2 or 4 neighbors
struct FT_NodeToMove
{
int _nodeToMove;
std::vector< int > _neighborNodes;
double _params[2]; // parameters on shape (U or UV) found by projection
double *_nearParams; // _params of a neighbor already projected node
FT_NodeToMove(): _nearParams(0) {}
};
std::vector< std::string > _groupNames;
int _shapeDim; // dimension of boundary shapes
std::vector< FT_NodeToMove > _nodes; // ids of nodes to move and their neighbors
std::vector< FT_Projector > _projectors; // FT_Projector's initialized with boundary shapes
std::vector< FT_Projector > * _allProjectors; // FT_Projector's for all shapes of _shapeDim
MEDCoupling::DataArrayDouble* _nodeCoords;
bool _OK; // projecting is successful
// map of { FT_NodeToMove::_neighborNodes[i] } to { FT_NodeToMove* }
// this map is used to find neighbor nodes
typedef NCollection_DataMap< int, std::vector< FT_NodeToMove* > > TNodeIDToLinksMap;
TNodeIDToLinksMap _neigborsMap;
std::vector<int> _nodesOrder;
};
/*!
* \brief Container of node groups.
*/
class FT_NodeGroups
{
public:
// Load node groups from files
void read( const std::vector< std::string >& nodeFiles,
const XAO::Xao* xaoGeom,
MEDCoupling::DataArrayDouble* nodeCoords );
// return number of groups of nodes to move
int nbOfGroups() const { return _nodesOnGeom.size(); }
// Move nodes of a group in parallel mode
void operator() ( const int groupIndex ) const
{
const_cast< FT_NodeGroups* >( this )->projectAndMove( groupIndex );
}
// Project and move nodes of a given group of nodes
void projectAndMove( const int groupIndex );
// return true if all nodes were successfully relocated
bool isOK() const;
// print some statistics on node groups
void dumpStat() const;
private:
std::vector< FT_NodesOnGeom > _nodesOnGeom;
std::vector< FT_Projector > _projectors[2]; // curves and surfaces separately
};
}; // namespace SMESHHOMARDImpl
#endif

View File

@ -472,6 +472,7 @@ bool SMESHGUI_HomardAdaptDlg::PushOnApply()
// Compute and publish
bool isSuccess = true;
try {
SUIT_OverrideCursor aWaitCursor;
isSuccess = myHomardGen->Compute() == 0;
}
catch( SALOME::SALOME_Exception& S_ex ) {
@ -540,6 +541,7 @@ void SMESHGUI_HomardAdaptDlg::selectionChanged()
if (!myArgs->myInBrowserRadio->isChecked())
return;
//SUIT_OverrideCursor aWaitCursor;
LightApp_SelectionMgr *selMgr = SMESHGUI::selectionMgr();
// get selected mesh
@ -580,6 +582,10 @@ void SMESHGUI_HomardAdaptDlg::selectionChanged()
myArgs->mySelectOutMedFileLineEdit->setText(aFileInfo.absoluteFilePath());
}
//}
// Check data
if (!aMeshName.isEmpty())
CheckCase(false);
}
void SMESHGUI_HomardAdaptDlg::SetFileName()
@ -587,6 +593,7 @@ void SMESHGUI_HomardAdaptDlg::SetFileName()
// Input med file
QString fileName0 = myArgs->mySelectInMedFileLineEdit->text().trimmed();
QString fileName = SMESH_HOMARD_QT_COMMUN::PushNomFichier(false, QString("med"));
//SUIT_OverrideCursor aWaitCursor;
if (fileName.isEmpty()) {
fileName = fileName0;
if (fileName.isEmpty()) return;

View File

@ -25,9 +25,6 @@
#include "SMESH_File.hxx"
// TODO?
//#include "FrontTrack.hxx"
#include "utilities.h"
#include "Basics_Utils.hxx"
#include "Basics_DirUtils.hxx"
@ -1008,6 +1005,7 @@ CORBA::Long HOMARD_Gen_i::DeleteIteration(int numIter)
MESSAGE ("DeleteIteration : numIter = " << numIter);
if (numIter == 0) {
if (!CORBA::is_nil(myIteration1)) DeleteIteration(1);
myIteration0 = SMESHHOMARD::HOMARD_Iteration::_nil();
}
else {
@ -2070,16 +2068,18 @@ CORBA::Long HOMARD_Gen_i::ComputeCAO(SMESHHOMARD::HOMARD_Cas_var myCase,
MESSAGE (". theXaoFileName = " << theXaoFileName);
// B.5. Parallélisme
//bool theIsParallel = false;
bool theIsParallel = false;
// C. Lancement des projections
MESSAGE (". Lancement des projections");
// TODO?
//FrontTrack* myFrontTrack = new FrontTrack();
//myFrontTrack->track(theInputMedFile, theOutputMedFile, theInputNodeFiles, theXaoFileName, theIsParallel);
SMESHHOMARDImpl::FrontTrack* myFrontTrack = new SMESHHOMARDImpl::FrontTrack();
myFrontTrack->track(theInputMedFile, theOutputMedFile,
theInputNodeFiles, theXaoFileName, theIsParallel);
// D. Transfert des coordonnées modifiées dans le fichier historique de HOMARD
// On lance une exécution spéciale de HOMARD en attendant de savoir le faire avec MEDCoupling
// On lance une exécution spéciale de HOMARD en attendant
// de savoir le faire avec MEDCoupling
MESSAGE (". Transfert des coordonnées");
codret = ComputeCAObis(myIteration);