mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-09-29 22:22:51 +05:00
332 lines
9.3 KiB
C++
332 lines
9.3 KiB
C++
|
// 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_Regular_1D.cxx
|
||
|
// Moved here from SMESH_Regular_1D.cxx
|
||
|
// Author : Paul RASCLE, EDF
|
||
|
// Module : SMESH
|
||
|
// $Header$
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
#include "StdMeshers_Regular_1D.hxx"
|
||
|
#include "SMESH_Gen.hxx"
|
||
|
#include "SMESH_Mesh.hxx"
|
||
|
|
||
|
#include "StdMeshers_LocalLength.hxx"
|
||
|
#include "StdMeshers_NumberOfSegments.hxx"
|
||
|
|
||
|
#include "SMDS_MeshElement.hxx"
|
||
|
#include "SMDS_MeshNode.hxx"
|
||
|
#include "SMDS_EdgePosition.hxx"
|
||
|
|
||
|
#include "utilities.h"
|
||
|
|
||
|
#include <TopoDS_Edge.hxx>
|
||
|
#include <TopoDS_Shape.hxx>
|
||
|
#include <GeomAdaptor_Curve.hxx>
|
||
|
#include <BRep_Tool.hxx>
|
||
|
#include <GCPnts_AbscissaPoint.hxx>
|
||
|
#include <GCPnts_UniformAbscissa.hxx>
|
||
|
|
||
|
#include <string>
|
||
|
#include <algorithm>
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
|
||
|
SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
|
||
|
{
|
||
|
MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
|
||
|
_name = "Regular_1D";
|
||
|
// _shapeType = TopAbs_EDGE;
|
||
|
_shapeType = (1 << TopAbs_EDGE);
|
||
|
_compatibleHypothesis.push_back("LocalLength");
|
||
|
_compatibleHypothesis.push_back("NumberOfSegments");
|
||
|
|
||
|
_localLength = 0;
|
||
|
_numberOfSegments = 0;
|
||
|
_hypLocalLength = NULL;
|
||
|
_hypNumberOfSegments = NULL;
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
bool StdMeshers_Regular_1D::CheckHypothesis
|
||
|
(SMESH_Mesh& aMesh,
|
||
|
const TopoDS_Shape& aShape,
|
||
|
SMESH_Hypothesis::Hypothesis_Status& aStatus)
|
||
|
{
|
||
|
//MESSAGE("StdMeshers_Regular_1D::CheckHypothesis");
|
||
|
|
||
|
list <const SMESHDS_Hypothesis * >::const_iterator itl;
|
||
|
const SMESHDS_Hypothesis *theHyp;
|
||
|
|
||
|
const list <const SMESHDS_Hypothesis * >&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 == "LocalLength")
|
||
|
{
|
||
|
_hypLocalLength = dynamic_cast <const StdMeshers_LocalLength * >(theHyp);
|
||
|
ASSERT(_hypLocalLength);
|
||
|
_localLength = _hypLocalLength->GetLength();
|
||
|
_numberOfSegments = 0;
|
||
|
isOk = true;
|
||
|
aStatus = SMESH_Hypothesis::HYP_OK;
|
||
|
}
|
||
|
|
||
|
else if (hypName == "NumberOfSegments")
|
||
|
{
|
||
|
_hypNumberOfSegments =
|
||
|
dynamic_cast <const StdMeshers_NumberOfSegments * >(theHyp);
|
||
|
ASSERT(_hypNumberOfSegments);
|
||
|
_numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments();
|
||
|
_scaleFactor = _hypNumberOfSegments->GetScaleFactor();
|
||
|
_localLength = 0;
|
||
|
isOk = true;
|
||
|
aStatus = SMESH_Hypothesis::HYP_OK;
|
||
|
}
|
||
|
else
|
||
|
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
|
||
|
|
||
|
//SCRUTE(_localLength);
|
||
|
//SCRUTE(_numberOfSegments);
|
||
|
|
||
|
return isOk;
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
|
||
|
{
|
||
|
MESSAGE("StdMeshers_Regular_1D::Compute");
|
||
|
|
||
|
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
|
||
|
SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
|
||
|
|
||
|
const TopoDS_Edge & EE = TopoDS::Edge(aShape);
|
||
|
TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
|
||
|
|
||
|
double f, l;
|
||
|
Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
|
||
|
|
||
|
TopoDS_Vertex VFirst, VLast;
|
||
|
TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
|
||
|
|
||
|
double length = EdgeLength(E);
|
||
|
//SCRUTE(length);
|
||
|
|
||
|
double eltSize = 1;
|
||
|
// if (_localLength > 0) eltSize = _localLength;
|
||
|
if (_localLength > 0)
|
||
|
{
|
||
|
double nbseg = ceil(length / _localLength); // integer sup
|
||
|
if (nbseg <= 0)
|
||
|
nbseg = 1; // degenerated edge
|
||
|
eltSize = length / nbseg;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(_numberOfSegments > 0);
|
||
|
eltSize = length / _numberOfSegments;
|
||
|
}
|
||
|
|
||
|
ASSERT(!VFirst.IsNull());
|
||
|
SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
|
||
|
const SMDS_MeshNode * idFirst = lid->next();
|
||
|
|
||
|
ASSERT(!VLast.IsNull());
|
||
|
lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
|
||
|
const SMDS_MeshNode * idLast = lid->next();
|
||
|
|
||
|
if (!Curve.IsNull())
|
||
|
{
|
||
|
GeomAdaptor_Curve C3d(Curve);
|
||
|
GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l);
|
||
|
int NbPoints = Discret.NbPoints();
|
||
|
//MESSAGE("nb points on edge : "<<NbPoints);
|
||
|
|
||
|
// edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
|
||
|
// only internal nodes receive an edge position with param on curve
|
||
|
|
||
|
const SMDS_MeshNode * idPrev = idFirst;
|
||
|
for (int i = 2; i < NbPoints; i++)
|
||
|
{
|
||
|
double param = Discret.Parameter(i);
|
||
|
|
||
|
if (_numberOfSegments > 1)
|
||
|
{
|
||
|
double epsilon = 0.001;
|
||
|
if (fabs(_scaleFactor - 1.0) > epsilon)
|
||
|
{
|
||
|
double alpha =
|
||
|
pow(_scaleFactor, 1.0 / (_numberOfSegments - 1));
|
||
|
double d =
|
||
|
length * (1 - pow(alpha, i - 1)) / (1 - pow(alpha,
|
||
|
_numberOfSegments));
|
||
|
param = d;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gp_Pnt P = Curve->Value(param);
|
||
|
|
||
|
//Add the Node in the DataStructure
|
||
|
//MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
|
||
|
SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
|
||
|
meshDS->SetNodeOnEdge(node, E);
|
||
|
|
||
|
// **** edgePosition associe au point = param.
|
||
|
SMDS_EdgePosition* epos =
|
||
|
dynamic_cast<SMDS_EdgePosition *>(node->GetPosition().get());
|
||
|
epos->SetUParameter(param);
|
||
|
|
||
|
SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
|
||
|
meshDS->SetMeshElementOnShape(edge, E);
|
||
|
idPrev = node;
|
||
|
}
|
||
|
SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
|
||
|
meshDS->SetMeshElementOnShape(edge, E);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// MESSAGE ("Edge Degeneree non traitee --- arret");
|
||
|
// ASSERT(0);
|
||
|
if (BRep_Tool::Degenerated(E))
|
||
|
{
|
||
|
// Edge is a degenerated Edge : We put n = 5 points on the edge.
|
||
|
int NbPoints = 5;
|
||
|
BRep_Tool::Range(E, f, l);
|
||
|
double du = (l - f) / (NbPoints - 1);
|
||
|
MESSAGE("************* Degenerated edge! *****************");
|
||
|
|
||
|
TopoDS_Vertex V1, V2;
|
||
|
TopExp::Vertices(E, V1, V2);
|
||
|
gp_Pnt P = BRep_Tool::Pnt(V1);
|
||
|
|
||
|
const SMDS_MeshNode * idPrev = idFirst;
|
||
|
for (int i = 2; i < NbPoints; i++)
|
||
|
{
|
||
|
double param = f + (i - 1) * du;
|
||
|
SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
|
||
|
meshDS->SetNodeOnEdge(node, E);
|
||
|
|
||
|
// Handle (SMDS_EdgePosition) epos
|
||
|
// = new SMDS_EdgePosition(theSubMesh->GetId(),param);
|
||
|
// node->SetPosition(epos);
|
||
|
SMDS_EdgePosition* epos =
|
||
|
dynamic_cast<SMDS_EdgePosition*>(node->GetPosition().get());
|
||
|
epos->SetUParameter(param);
|
||
|
|
||
|
SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
|
||
|
meshDS->SetMeshElementOnShape(edge, E);
|
||
|
idPrev = node;
|
||
|
}
|
||
|
SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
|
||
|
meshDS->SetMeshElementOnShape(edge, E);
|
||
|
}
|
||
|
else
|
||
|
ASSERT(0);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
ostream & StdMeshers_Regular_1D::SaveTo(ostream & save)
|
||
|
{
|
||
|
return save;
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
istream & StdMeshers_Regular_1D::LoadFrom(istream & load)
|
||
|
{
|
||
|
return load;
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp)
|
||
|
{
|
||
|
return hyp.SaveTo( save );
|
||
|
}
|
||
|
|
||
|
//=============================================================================
|
||
|
/*!
|
||
|
*
|
||
|
*/
|
||
|
//=============================================================================
|
||
|
|
||
|
istream & operator >>(istream & load, StdMeshers_Regular_1D & hyp)
|
||
|
{
|
||
|
return hyp.LoadFrom( load );
|
||
|
}
|