Salome HOME
NRI : Change lGeometryClient by lGEOMClient.
[modules/smesh.git] / src / SMESH / SMESH_Regular_1D.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : SMESH_Regular_1D.cxx
4 // Created   : sam mai 18 08:11:58 CEST 2002
5 // Author    : Paul RASCLE, EDF
6 // Project   : SALOME
7 // Copyright : EDF 2002
8 // $Header$
9 //=============================================================================
10 using namespace std;
11
12 #include "SMESH_Regular_1D.hxx"
13 #include "SMESH_Gen.hxx"
14 #include "SMESH_Mesh.hxx"
15
16 #include "SMESH_LocalLength.hxx"
17 #include "SMESH_NumberOfSegments.hxx"
18
19 #include "SMESHDS_ListOfPtrHypothesis.hxx"
20 #include "SMESHDS_ListIteratorOfListOfPtrHypothesis.hxx"
21 #include "SMDS_MeshElement.hxx"
22 #include "SMDS_MeshNode.hxx"
23 #include "SMDS_EdgePosition.hxx"
24
25 #include "utilities.h"
26
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <BRep_Tool.hxx>
31 #include <GCPnts_AbscissaPoint.hxx>
32 #include <GCPnts_UniformAbscissa.hxx>
33
34 #include <string>
35 #include <algorithm>
36
37 //=============================================================================
38 /*!
39  *  
40  */
41 //=============================================================================
42
43 SMESH_Regular_1D::SMESH_Regular_1D(int hypId, int studyId, SMESH_Gen* gen)
44   : SMESH_1D_Algo(hypId, studyId, gen)
45 {
46   MESSAGE("SMESH_Regular_1D::SMESH_Regular_1D");
47   _name = "Regular_1D";
48   //  _shapeType = TopAbs_EDGE;
49   _shapeType = (1<<TopAbs_EDGE);
50   _compatibleHypothesis.push_back("LocalLength");
51   _compatibleHypothesis.push_back("NumberOfSegments");
52
53   _localLength = 0;
54   _numberOfSegments = 0;
55   _hypLocalLength = NULL;
56   _hypNumberOfSegments = NULL;
57 }
58
59 //=============================================================================
60 /*!
61  *  
62  */
63 //=============================================================================
64
65 SMESH_Regular_1D::~SMESH_Regular_1D()
66 {
67 }
68
69 //=============================================================================
70 /*!
71  *  
72  */
73 //=============================================================================
74
75 ostream & SMESH_Regular_1D::SaveTo(ostream & save)
76 {
77   return save << this;
78 }
79
80 //=============================================================================
81 /*!
82  *  
83  */
84 //=============================================================================
85
86 istream & SMESH_Regular_1D::LoadFrom(istream & load)
87 {
88   return load >> (*this);
89 }
90
91 //=============================================================================
92 /*!
93  *  
94  */
95 //=============================================================================
96
97 ostream& operator << (ostream & save, SMESH_Regular_1D & hyp)
98 {
99   return save;
100 }
101
102 //=============================================================================
103 /*!
104  *  
105  */
106 //=============================================================================
107
108 istream& operator >> (istream & load, SMESH_Regular_1D & hyp)
109 {
110   return load;
111 }
112
113 //=============================================================================
114 /*!
115  *  
116  */
117 //=============================================================================
118
119 bool SMESH_Regular_1D::CheckHypothesis(SMESH_Mesh& aMesh,
120                                        const TopoDS_Shape& aShape)
121 {
122   //MESSAGE("SMESH_Regular_1D::CheckHypothesis");
123
124   list<SMESHDS_Hypothesis*>::const_iterator itl;
125   SMESHDS_Hypothesis* theHyp;
126
127   const list<SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
128   int nbHyp = hyps.size();
129   if (nbHyp != 1) return false;  // only one compatible hypothesis allowed
130
131   itl = hyps.begin();
132   theHyp = (*itl);
133
134   string hypName = theHyp->GetName();
135   int hypId = theHyp->GetID();
136   //SCRUTE(hypName);
137
138   bool isOk = false;
139
140   if (hypName == "LocalLength")
141     {
142       _hypLocalLength = dynamic_cast<SMESH_LocalLength*> (theHyp);
143       ASSERT(_hypLocalLength);
144       _localLength = _hypLocalLength->GetLength();
145       _numberOfSegments = 0;
146       isOk =true;
147     }
148
149   if (hypName == "NumberOfSegments")
150     {
151       _hypNumberOfSegments = dynamic_cast<SMESH_NumberOfSegments*> (theHyp);
152       ASSERT(_hypNumberOfSegments);
153       _numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments();
154       _localLength = 0;
155       isOk = true;
156     }
157
158   //SCRUTE(_localLength);
159   //SCRUTE(_numberOfSegments);
160
161   return isOk;
162 }
163
164 //=============================================================================
165 /*!
166  *  
167  */
168 //=============================================================================
169
170 bool SMESH_Regular_1D::Compute(SMESH_Mesh& aMesh,
171                                const TopoDS_Shape& aShape)
172 {
173   //MESSAGE("SMESH_Regular_1D::Compute");
174
175   const Handle(SMESHDS_Mesh)& meshDS = aMesh.GetMeshDS();
176   SMESH_subMesh* theSubMesh = aMesh.GetSubMesh(aShape);
177
178   const TopoDS_Edge& EE = TopoDS::Edge(aShape);
179   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
180
181   double f,l;
182   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l); 
183
184   TopoDS_Vertex VFirst, VLast;
185   TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
186
187   double length = EdgeLength(E);
188   //SCRUTE(length);
189
190   double eltSize = 1;
191 //   if (_localLength > 0) eltSize = _localLength;
192   if (_localLength > 0)
193     {
194       double nbseg = ceil(length/_localLength); // integer sup
195       if (nbseg <=0) nbseg = 1;                 // degenerated edge
196       eltSize = length/nbseg;
197     }
198   else
199     {
200       ASSERT(_numberOfSegments> 0);
201       eltSize = length/_numberOfSegments;
202     }
203   
204   ASSERT(!VFirst.IsNull());
205   SMESH_subMesh* firstSubMesh = aMesh.GetSubMesh(VFirst);
206   const TColStd_ListOfInteger& lidf
207     = firstSubMesh->GetSubMeshDS()->GetIDNodes();
208   int idFirst= lidf.First();
209   //SCRUTE(idFirst);
210   
211   ASSERT(!VLast.IsNull());
212   SMESH_subMesh* lastSubMesh = aMesh.GetSubMesh(VLast);
213   const TColStd_ListOfInteger& lidl
214     = lastSubMesh->GetSubMeshDS()->GetIDNodes();
215   int idLast= lidl.First();
216   //SCRUTE(idLast);
217
218   if (!Curve.IsNull())
219     {
220       GeomAdaptor_Curve C3d(Curve);
221       GCPnts_UniformAbscissa Discret(C3d,eltSize,f,l);
222       int NbPoints = Discret.NbPoints();
223       //MESSAGE("nb points on edge : "<<NbPoints);
224
225       // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
226       // only internal nodes receive an edge position with param on curve
227
228       int idPrev = idFirst;
229       for (int i=2; i<NbPoints; i++)
230         {
231           double param = Discret.Parameter(i);
232           gp_Pnt P = Curve->Value(param);
233       
234           //Add the Node in the DataStructure
235           int nodeId = meshDS->AddNode(P.X(), P.Y(), P.Z());
236           //MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
237           Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
238           Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
239           meshDS->SetNodeOnEdge(node, E);
240
241           // **** edgePosition associe au point = param. 
242 //        Handle (SMDS_EdgePosition) epos
243 //          = new SMDS_EdgePosition(theSubMesh->GetId(),param); // non, deja cree
244 //        node->SetPosition(epos);
245           Handle (SMDS_EdgePosition) epos
246             = Handle (SMDS_EdgePosition)::DownCast(node->GetPosition());
247           epos->SetUParameter(param);
248
249           int edgeId = meshDS->AddEdge(idPrev, nodeId);
250           elt = meshDS->FindElement(edgeId);
251           meshDS->SetMeshElementOnShape(elt, E);
252           idPrev = nodeId;
253         }
254       int edgeId = meshDS->AddEdge(idPrev, idLast);
255       Handle (SMDS_MeshElement) elt = meshDS->FindElement(edgeId);
256       meshDS->SetMeshElementOnShape(elt, E);
257     }
258   else
259     {
260 //       MESSAGE ("Edge Degeneree non traitee --- arret");
261 //       ASSERT(0);
262       if (BRep_Tool::Degenerated(E))
263         {
264           // Edge is a degenerated Edge : We put n = 5 points on the edge.
265           int NbPoints = 5;
266           BRep_Tool::Range(E,f,l);
267           double du = (l-f)/(NbPoints-1);
268           MESSAGE("************* Degenerated edge! *****************");
269       
270           TopoDS_Vertex V1,V2;
271           TopExp::Vertices (E,V1,V2);
272           gp_Pnt P = BRep_Tool::Pnt(V1);
273       
274           int idPrev = idFirst;
275           for (int i=2; i<NbPoints; i++)
276             {
277               double param = f + (i-1)*du;
278               //Add the Node in the DataStructure
279               int nodeId = meshDS->AddNode(P.X(), P.Y(), P.Z());
280               //MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
281
282               Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
283               Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
284               meshDS->SetNodeOnEdge(node, E);
285               
286 //            Handle (SMDS_EdgePosition) epos
287 //              = new SMDS_EdgePosition(theSubMesh->GetId(),param);
288 //            node->SetPosition(epos);
289               Handle (SMDS_EdgePosition) epos
290                 = Handle (SMDS_EdgePosition)::DownCast(node->GetPosition());
291               epos->SetUParameter(param);
292               
293               int edgeId = meshDS->AddEdge(idPrev, nodeId);
294               elt = meshDS->FindElement(edgeId);
295               meshDS->SetMeshElementOnShape(elt, E);
296               idPrev = nodeId;
297             }
298           int edgeId = meshDS->AddEdge(idPrev, idLast);
299           Handle (SMDS_MeshElement) elt = meshDS->FindElement(edgeId);
300           meshDS->SetMeshElementOnShape(elt, E);
301         }
302       else ASSERT(0);
303     }
304   return true;
305 }