X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_MEFISTO_2D.cxx;fp=src%2FStdMeshers%2FStdMeshers_MEFISTO_2D.cxx;h=6229e4c6d0148b058fdf875ee9576667c820a014;hb=143d55f45ff65cc53f4e45a03bd136c65df46219;hp=0000000000000000000000000000000000000000;hpb=0b9bd142d356bc7c26e5980bb1683e7acdf13b99;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx new file mode 100644 index 000000000..6229e4c6d --- /dev/null +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -0,0 +1,643 @@ +// 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_MEFISTO_2D.cxx +// Moved here from SMESH_MEFISTO_2D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MEFISTO_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "StdMeshers_MaxElementArea.hxx" +#include "StdMeshers_LengthFromEdges.hxx" + +#include "Rn.h" +#include "aptrte.h" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); + _name = "MEFISTO_2D"; +// _shapeType = TopAbs_FACE; + _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("MaxElementArea"); + _compatibleHypothesis.push_back("LengthFromEdges"); + + _edgeLength = 0; + _maxElementArea = 0; + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() +{ + MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis"); + + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; + + list ::const_iterator itl; + const SMESHDS_Hypothesis *theHyp; + + const list &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 == "MaxElementArea") + { + _hypMaxElementArea = static_cast(theHyp); + ASSERT(_hypMaxElementArea); + _maxElementArea = _hypMaxElementArea->GetMaxArea(); + _edgeLength = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "LengthFromEdges") + { + _hypLengthFromEdges = static_cast(theHyp); + ASSERT(_hypLengthFromEdges); + _edgeLength = 0; + _maxElementArea = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + + if (isOk) + { + isOk = false; + if (_maxElementArea > 0) + { + _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant + isOk = true; + } + else + isOk = (_hypLengthFromEdges != NULL); // **** check mode + if (!isOk) + aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; + } + + //SCRUTE(_edgeLength); + //SCRUTE(_maxElementArea); + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_MEFISTO_2D::Compute"); + + if (_hypLengthFromEdges) + _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + + bool isOk = false; + const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + Z nblf; //nombre de lignes fermees (enveloppe en tete) + Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee + R2 *uvslf = NULL; + Z nbpti = 0; //nombre points internes futurs sommets de la triangulation + R2 *uvpti = NULL; + + Z nbst; + R2 *uvst = NULL; + Z nbt; + Z *nust = NULL; + Z ierr = 0; + + Z nutysu = 1; // 1: il existe un fonction areteideale_() + // Z nutysu=0; // 0: on utilise aretmx + R aretmx = _edgeLength; // longueur max aretes future triangulation + //SCRUTE(aretmx); + + nblf = NumberOfWires(F); + //SCRUTE(nblf); + + nudslf = new Z[1 + nblf]; + nudslf[0] = 0; + int iw = 1; + int nbpnt = 0; + + const TopoDS_Wire OW1 = BRepTools::OuterWire(F); + nbpnt += NumberOfPoints(aMesh, OW1); + nudslf[iw++] = nbpnt; + //SCRUTE(nbpnt); + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!OW1.IsSame(W)) + { + nbpnt += NumberOfPoints(aMesh, W); + nudslf[iw++] = nbpnt; + //SCRUTE(nbpnt); + } + } + + uvslf = new R2[nudslf[nblf]]; + //SCRUTE(nudslf[nblf]); + int m = 0; + + map mefistoToDS; // correspondence mefisto index--> points IDNodes + TopoDS_Wire OW = BRepTools::OuterWire(F); + LoadPoints(aMesh, F, OW, uvslf, m, mefistoToDS); + //SCRUTE(m); + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!OW.IsSame(W)) + { + LoadPoints(aMesh, F, W, uvslf, m, mefistoToDS); + //SCRUTE(m); + } + } +// SCRUTE(nudslf[nblf]); +// for (int i=0; i<=nblf; i++) +// { +// MESSAGE(" -+- " <&mefistoToDS) +{ + MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints"); + + SMDS_Mesh * meshDS = aMesh.GetMeshDS(); + + double scalex; + double scaley; + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + ComputeScaleOnFace(aMesh, F, scalex, scaley); + + TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD)); + BRepTools_WireExplorer wexp(W, F); + for (wexp.Init(W, F); wexp.More(); wexp.Next()) + { + const TopoDS_Edge & E = wexp.Current(); + + // --- IDNodes of first and last Vertex + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + + 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(); + + // --- edge internal IDNodes (relies on good order storage, not checked) + + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + //SCRUTE(nbPoints); + + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + + SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + + bool isForward = (E.Orientation() == TopAbs_FORWARD); + map params; + + while(ite->more()) + { + const SMDS_MeshNode * node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + // --- load 2D values into MEFISTO structure, + // add IDNodes in mefistoToDS map + + if (E.Orientation() == TopAbs_FORWARD) + { + gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = idFirst; + //MESSAGE(" "<::iterator itp = params.begin(); + for (int i = 1; i <= nbPoints; i++) // nbPoints internal + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = (*itp).second; +// MESSAGE(" "<Value(l); // last point = Vertex Reversed + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = idLast; +// MESSAGE(" "<::reverse_iterator itp = params.rbegin(); + for (int i = nbPoints; i >= 1; i--) + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = (*itp).second; +// MESSAGE(" "<Value(param); + if (p.X() < xmin) + xmin = p.X(); + if (p.X() > xmax) + xmax = p.X(); + if (p.Y() < ymin) + ymin = p.Y(); + if (p.Y() > ymax) + ymax = p.Y(); +// MESSAGE(" "<< f<<" "<Value(xmin, ymoy); + gp_Pnt PY0 = S->Value(xmoy, ymin); + for (int i = 1; i <= nbp; i++) + { + double x = xmin + (double (i) / double (nbp))*(xmax - xmin); + gp_Pnt PX = S->Value(x, ymoy); + double y = ymin + (double (i) / double (nbp))*(ymax - ymin); + gp_Pnt PY = S->Value(xmoy, y); + length_x += PX.Distance(PX0); + length_y += PY.Distance(PY0); + PX0.SetCoord(PX.X(), PX.Y(), PX.Z()); + PY0.SetCoord(PY.X(), PY.Y(), PY.Z()); + } +// SCRUTE(length_x); +// SCRUTE(length_y); + scalex = length_x / (xmax - xmin); + scaley = length_y / (ymax - ymin); +// SCRUTE(scalex); +// SCRUTE(scaley); + ASSERT(scalex); + ASSERT(scaley); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh, + Z nbst, R2 * uvst, Z nbt, Z * nust, + const TopoDS_Face & F, bool faceIsForward, + map&mefistoToDS) +{ + double scalex; + double scaley; + ComputeScaleOnFace(aMesh, F, scalex, scaley); + + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + + Z n, m; + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + for (n = 0; n < nbst; n++) + { + double u = uvst[n][0] / scalex; + double v = uvst[n][1] / scaley; + gp_Pnt P = S->Value(u, v); + + if (mefistoToDS.find(n + 1) == mefistoToDS.end()) + { + SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(node, F); + + //MESSAGE(nodeId<<" "<(node->GetPosition().get()); + fpos->SetUParameter(u); + fpos->SetVParameter(v); + } + } + + m = 0; + int mt = 0; + + //SCRUTE(faceIsForward); + for (n = 1; n <= nbt; n++) + { + int inode1 = nust[m++]; + int inode2 = nust[m++]; + int inode3 = nust[m++]; + + const SMDS_MeshNode *n1, *n2, *n3; + n1 = mefistoToDS[inode1]; + n2 = mefistoToDS[inode2]; + n3 = mefistoToDS[inode3]; + //MESSAGE("-- "<AddFace(n1, n2, n3); + else + elt = meshDS->AddFace(n1, n3, n2); + + meshDS->SetMeshElementOnShape(elt, F); + m++; + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength"); + // **** a mettre dans SMESH_2D_Algo ? + + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + double meanElementLength = 100; + double wireLength = 0; + int wireElementsNumber = 0; + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next()) + { + const TopoDS_Edge & E = TopoDS::Edge(expe.Current()); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + double length = EdgeLength(E); + wireLength += length; + wireElementsNumber += nb; + } + } + if (wireElementsNumber) + meanElementLength = wireLength / wireElementsNumber; + //SCRUTE(meanElementLength); + return meanElementLength; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.LoadFrom( load ); +}