Salome HOME
Merge from OCC_development_generic_2006
[modules/smesh.git] / src / StdMeshers / StdMeshers_LocalLength.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   : StdMeshers_LocalLength.cxx
25 //           Moved here from SMESH_LocalLength.cxx
26 //  Author : Paul RASCLE, EDF
27 //  Module : SMESH
28 //  $Header$
29
30 #include "StdMeshers_LocalLength.hxx"
31
32 #include "SMESH_Mesh.hxx"
33 #include "SMESH_Algo.hxx"
34
35 #include "utilities.h"
36
37 #include <BRep_Tool.hxx>
38 #include <GCPnts_AbscissaPoint.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <Geom_Curve.hxx>
41 #include <TopExp.hxx>
42 #include <TopLoc_Location.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Edge.hxx>
46
47 using namespace std;
48
49 //=============================================================================
50 /*!
51  *  
52  */
53 //=============================================================================
54
55 StdMeshers_LocalLength::StdMeshers_LocalLength(int hypId, int studyId, SMESH_Gen * gen)
56   :SMESH_Hypothesis(hypId, studyId, gen)
57 {
58   _length = 1.;
59   _name = "LocalLength";
60   _param_algo_dim = 1; // is used by SMESH_Regular_1D
61 }
62
63 //=============================================================================
64 /*!
65  *  
66  */
67 //=============================================================================
68
69 StdMeshers_LocalLength::~StdMeshers_LocalLength()
70 {
71 }
72
73 //=============================================================================
74 /*!
75  *  
76  */
77 //=============================================================================
78
79 void StdMeshers_LocalLength::SetLength(double length) throw(SALOME_Exception)
80 {
81         double oldLength = _length;
82         if (length <= 0)
83                 throw SALOME_Exception(LOCALIZED("length must be positive"));
84         _length = length;
85         if (oldLength != _length)
86                 NotifySubMeshesHypothesisModification();
87 }
88
89 //=============================================================================
90 /*!
91  *  
92  */
93 //=============================================================================
94
95 double StdMeshers_LocalLength::GetLength() const
96 {
97         return _length;
98 }
99
100 //=============================================================================
101 /*!
102  *  
103  */
104 //=============================================================================
105
106 ostream & StdMeshers_LocalLength::SaveTo(ostream & save)
107 {
108   save << this->_length;
109   return save;
110 }
111
112 //=============================================================================
113 /*!
114  *  
115  */
116 //=============================================================================
117
118 istream & StdMeshers_LocalLength::LoadFrom(istream & load)
119 {
120   bool isOK = true;
121   double a;
122   isOK = (load >> a);
123   if (isOK)
124     this->_length = a;
125   else
126     load.clear(ios::badbit | load.rdstate());
127   return load;
128 }
129
130 //=============================================================================
131 /*!
132  *  
133  */
134 //=============================================================================
135
136 ostream & operator <<(ostream & save, StdMeshers_LocalLength & hyp)
137 {
138   return hyp.SaveTo( save );
139 }
140
141 //=============================================================================
142 /*!
143  *  
144  */
145 //=============================================================================
146
147 istream & operator >>(istream & load, StdMeshers_LocalLength & hyp)
148 {
149   return hyp.LoadFrom( load );
150 }
151
152 //================================================================================
153 /*!
154  * \brief Initialize segment length by the mesh built on the geometry
155  * \param theMesh - the built mesh
156  * \param theShape - the geometry of interest
157  * \retval bool - true if parameter values have been successfully defined
158  */
159 //================================================================================
160
161 bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
162                                                  const TopoDS_Shape& theShape)
163 {
164   if ( !theMesh || theShape.IsNull() )
165     return false;
166
167   _length = 0.;
168
169   Standard_Real UMin, UMax;
170   TopLoc_Location L;
171
172   int nbEdges = 0;
173   TopTools_IndexedMapOfShape edgeMap;
174   TopExp::MapShapes( theShape, TopAbs_EDGE, edgeMap );
175   for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
176   {
177     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
178     Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax );
179     GeomAdaptor_Curve AdaptCurve(C);
180
181     vector< double > params;
182     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
183     if ( SMESH_Algo::GetNodeParamOnEdge( aMeshDS, edge, params ))
184     {
185       for ( int i = 1; i < params.size(); ++i )
186         _length += GCPnts_AbscissaPoint::Length( AdaptCurve, params[ i-1 ], params[ i ]);
187       nbEdges += params.size() - 1;
188     }
189   }
190   if ( nbEdges )
191     _length /= nbEdges;
192
193   return nbEdges;
194 }