smesh/src/StdMeshers/StdMeshers_Regular_1D.cxx

332 lines
9.3 KiB
C++
Raw Normal View History

2004-06-18 14:34:31 +06:00
// 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 );
}