Salome HOME
SALOME PAL V1_4_1
[modules/smesh.git] / src / StdMeshers / StdMeshers_Regular_1D.cxx
diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx
new file mode 100644 (file)
index 0000000..aa069ff
--- /dev/null
@@ -0,0 +1,331 @@
+//  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 );
+}