Salome HOME
yfr : Merge with v1.2
[modules/smesh.git] / src / SMESH / SMESH_Regular_1D.cxx
1 //  SMESH SMESH : implementaion of SMESH idl descriptions
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Regular_1D.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 using namespace std;
30 using namespace std;
31 #include "SMESH_Regular_1D.hxx"
32 #include "SMESH_Gen.hxx"
33 #include "SMESH_Mesh.hxx"
34
35 #include "SMESH_LocalLength.hxx"
36 #include "SMESH_NumberOfSegments.hxx"
37
38 #include "SMESHDS_ListOfPtrHypothesis.hxx"
39 #include "SMESHDS_ListIteratorOfListOfPtrHypothesis.hxx"
40 #include "SMDS_MeshElement.hxx"
41 #include "SMDS_MeshNode.hxx"
42 #include "SMDS_EdgePosition.hxx"
43
44 #include "utilities.h"
45
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <GeomAdaptor_Curve.hxx>
49 #include <BRep_Tool.hxx>
50 #include <GCPnts_AbscissaPoint.hxx>
51 #include <GCPnts_UniformAbscissa.hxx>
52
53 #include <string>
54 #include <algorithm>
55
56 //=============================================================================
57 /*!
58  *  
59  */
60 //=============================================================================
61
62 SMESH_Regular_1D::SMESH_Regular_1D(int hypId, int studyId, SMESH_Gen* gen)
63   : SMESH_1D_Algo(hypId, studyId, gen)
64 {
65   MESSAGE("SMESH_Regular_1D::SMESH_Regular_1D");
66   _name = "Regular_1D";
67   //  _shapeType = TopAbs_EDGE;
68   _shapeType = (1<<TopAbs_EDGE);
69   _compatibleHypothesis.push_back("LocalLength");
70   _compatibleHypothesis.push_back("NumberOfSegments");
71
72   _localLength = 0;
73   _numberOfSegments = 0;
74   _hypLocalLength = NULL;
75   _hypNumberOfSegments = NULL;
76 }
77
78 //=============================================================================
79 /*!
80  *  
81  */
82 //=============================================================================
83
84 SMESH_Regular_1D::~SMESH_Regular_1D()
85 {
86 }
87
88 //=============================================================================
89 /*!
90  *  
91  */
92 //=============================================================================
93
94 ostream & SMESH_Regular_1D::SaveTo(ostream & save)
95 {
96   return save << this;
97 }
98
99 //=============================================================================
100 /*!
101  *  
102  */
103 //=============================================================================
104
105 istream & SMESH_Regular_1D::LoadFrom(istream & load)
106 {
107   return load >> (*this);
108 }
109
110 //=============================================================================
111 /*!
112  *  
113  */
114 //=============================================================================
115
116 ostream& operator << (ostream & save, SMESH_Regular_1D & hyp)
117 {
118   return save;
119 }
120
121 //=============================================================================
122 /*!
123  *  
124  */
125 //=============================================================================
126
127 istream& operator >> (istream & load, SMESH_Regular_1D & hyp)
128 {
129   return load;
130 }
131
132 //=============================================================================
133 /*!
134  *  
135  */
136 //=============================================================================
137
138 bool SMESH_Regular_1D::CheckHypothesis(SMESH_Mesh& aMesh,
139                                        const TopoDS_Shape& aShape)
140 {
141   //MESSAGE("SMESH_Regular_1D::CheckHypothesis");
142
143   list<SMESHDS_Hypothesis*>::const_iterator itl;
144   SMESHDS_Hypothesis* theHyp;
145
146   const list<SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
147   int nbHyp = hyps.size();
148   if (nbHyp != 1) return false;  // only one compatible hypothesis allowed
149
150   itl = hyps.begin();
151   theHyp = (*itl);
152
153   string hypName = theHyp->GetName();
154   int hypId = theHyp->GetID();
155   //SCRUTE(hypName);
156
157   bool isOk = false;
158
159   if (hypName == "LocalLength")
160     {
161       _hypLocalLength = dynamic_cast<SMESH_LocalLength*> (theHyp);
162       ASSERT(_hypLocalLength);
163       _localLength = _hypLocalLength->GetLength();
164       _numberOfSegments = 0;
165       isOk =true;
166     }
167
168   if (hypName == "NumberOfSegments")
169     {
170       _hypNumberOfSegments = dynamic_cast<SMESH_NumberOfSegments*> (theHyp);
171       ASSERT(_hypNumberOfSegments);
172       _numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments();
173       _scaleFactor = _hypNumberOfSegments->GetScaleFactor();
174       _localLength = 0;
175       isOk = true;
176     }
177
178   //SCRUTE(_localLength);
179   //SCRUTE(_numberOfSegments);
180
181   return isOk;
182 }
183
184 //=============================================================================
185 /*!
186  *  
187  */
188 //=============================================================================
189
190 bool SMESH_Regular_1D::Compute(SMESH_Mesh& aMesh,
191                                const TopoDS_Shape& aShape)
192 {
193   //MESSAGE("SMESH_Regular_1D::Compute");
194
195   const Handle(SMESHDS_Mesh)& meshDS = aMesh.GetMeshDS();
196   SMESH_subMesh* theSubMesh = aMesh.GetSubMesh(aShape);
197
198   const TopoDS_Edge& EE = TopoDS::Edge(aShape);
199   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
200
201   double f,l;
202   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l); 
203
204   TopoDS_Vertex VFirst, VLast;
205   TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
206
207   double length = EdgeLength(E);
208   //SCRUTE(length);
209
210   double eltSize = 1;
211 //   if (_localLength > 0) eltSize = _localLength;
212   if (_localLength > 0)
213     {
214       double nbseg = ceil(length/_localLength); // integer sup
215       if (nbseg <=0) nbseg = 1;                 // degenerated edge
216       eltSize = length/nbseg;
217     }
218   else
219     {
220       ASSERT(_numberOfSegments> 0);
221       eltSize = length/_numberOfSegments;
222     }
223   
224   ASSERT(!VFirst.IsNull());
225   SMESH_subMesh* firstSubMesh = aMesh.GetSubMesh(VFirst);
226   const TColStd_ListOfInteger& lidf
227     = firstSubMesh->GetSubMeshDS()->GetIDNodes();
228   int idFirst= lidf.First();
229   //SCRUTE(idFirst);
230   
231   ASSERT(!VLast.IsNull());
232   SMESH_subMesh* lastSubMesh = aMesh.GetSubMesh(VLast);
233   const TColStd_ListOfInteger& lidl
234     = lastSubMesh->GetSubMeshDS()->GetIDNodes();
235   int idLast= lidl.First();
236   //SCRUTE(idLast);
237
238   if (!Curve.IsNull())
239     {
240       GeomAdaptor_Curve C3d(Curve);
241       GCPnts_UniformAbscissa Discret(C3d,eltSize,f,l);
242       int NbPoints = Discret.NbPoints();
243       //MESSAGE("nb points on edge : "<<NbPoints);
244
245       // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
246       // only internal nodes receive an edge position with param on curve
247
248       int idPrev = idFirst;
249       for (int i=2; i<NbPoints; i++)
250         {
251           double param = Discret.Parameter(i);
252
253           if(_numberOfSegments > 1)
254             {
255               double epsilon = 0.001;
256               if( fabs(_scaleFactor-1.0) > epsilon )
257                 {
258                   double alpha = pow(_scaleFactor, 1.0/(_numberOfSegments-1) );
259                   double d = length*(1-pow(alpha,i-1))/(1-pow(alpha,_numberOfSegments));
260                   param = d;
261                 }
262             }
263
264           gp_Pnt P = Curve->Value(param);
265       
266           //Add the Node in the DataStructure
267           int nodeId = meshDS->AddNode(P.X(), P.Y(), P.Z());
268           //MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
269           Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
270           Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
271           meshDS->SetNodeOnEdge(node, E);
272
273           // **** edgePosition associe au point = param. 
274 //        Handle (SMDS_EdgePosition) epos
275 //          = new SMDS_EdgePosition(theSubMesh->GetId(),param); // non, deja cree
276 //        node->SetPosition(epos);
277           Handle (SMDS_EdgePosition) epos
278             = Handle (SMDS_EdgePosition)::DownCast(node->GetPosition());
279           epos->SetUParameter(param);
280
281           int edgeId = meshDS->AddEdge(idPrev, nodeId);
282           elt = meshDS->FindElement(edgeId);
283           meshDS->SetMeshElementOnShape(elt, E);
284           idPrev = nodeId;
285         }
286       int edgeId = meshDS->AddEdge(idPrev, idLast);
287       Handle (SMDS_MeshElement) elt = meshDS->FindElement(edgeId);
288       meshDS->SetMeshElementOnShape(elt, E);
289     }
290   else
291     {
292 //       MESSAGE ("Edge Degeneree non traitee --- arret");
293 //       ASSERT(0);
294       if (BRep_Tool::Degenerated(E))
295         {
296           // Edge is a degenerated Edge : We put n = 5 points on the edge.
297           int NbPoints = 5;
298           BRep_Tool::Range(E,f,l);
299           double du = (l-f)/(NbPoints-1);
300           MESSAGE("************* Degenerated edge! *****************");
301       
302           TopoDS_Vertex V1,V2;
303           TopExp::Vertices (E,V1,V2);
304           gp_Pnt P = BRep_Tool::Pnt(V1);
305       
306           int idPrev = idFirst;
307           for (int i=2; i<NbPoints; i++)
308             {
309               double param = f + (i-1)*du;
310               //Add the Node in the DataStructure
311               int nodeId = meshDS->AddNode(P.X(), P.Y(), P.Z());
312               //MESSAGE("point "<<nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<" - "<<i<<" "<<param);
313
314               Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
315               Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
316               meshDS->SetNodeOnEdge(node, E);
317               
318 //            Handle (SMDS_EdgePosition) epos
319 //              = new SMDS_EdgePosition(theSubMesh->GetId(),param);
320 //            node->SetPosition(epos);
321               Handle (SMDS_EdgePosition) epos
322                 = Handle (SMDS_EdgePosition)::DownCast(node->GetPosition());
323               epos->SetUParameter(param);
324               
325               int edgeId = meshDS->AddEdge(idPrev, nodeId);
326               elt = meshDS->FindElement(edgeId);
327               meshDS->SetMeshElementOnShape(elt, E);
328               idPrev = nodeId;
329             }
330           int edgeId = meshDS->AddEdge(idPrev, idLast);
331           Handle (SMDS_MeshElement) elt = meshDS->FindElement(edgeId);
332           meshDS->SetMeshElementOnShape(elt, E);
333         }
334       else ASSERT(0);
335     }
336   return true;
337 }