Salome HOME
Merge branch 'BR_v14_rc' of ssh://git.salome-platform.org/modules/hydro into BR_v14_rc
[modules/hydro.git] / src / HYDROData / HYDROData_PolylineOperator.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROData_PolylineOperator.h>
20 #include <HYDROData_Document.h>
21 #include <BRepBuilderAPI_MakeEdge2d.hxx>
22 #include <BRepBuilderAPI_MakeWire.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Wire.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <QString>
28
29 template<class T> void append( std::vector<T>& theList, const std::vector<T>& theList2 )
30 {
31   int aSize = theList.size();
32   int aNewSize = aSize + theList2.size();
33
34   if( aSize==aNewSize )
35     return;
36
37   theList.resize( aNewSize );
38   for( int i=aSize, j=0; i<aNewSize; i++, j++ )
39     theList[i] = theList2[j];
40 }
41
42 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
43                                         const Handle( HYDROData_PolylineXY )& thePolyline,
44                                         const gp_Pnt2d& thePoint,
45                                         double theTolerance ) const
46 {
47   std::vector<gp_Pnt2d> aPointsList( 1 );
48   aPointsList[0] = thePoint;
49   std::vector<TopoDS_Wire> aCurves = GetWires( thePolyline );
50   bool isOK = true;
51   for( int i=0, n=aCurves.size(); i<n; i++ )
52   {
53     std::vector<TopoDS_Shape> aCurvesList = Split( aCurves[i], thePoint, theTolerance );
54     bool isLocalOK = CreatePolylines( theDoc, thePolyline->GetName(), aCurvesList, true );
55     isOK = isOK && isLocalOK;
56   }
57   return isOK;
58 }
59
60 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
61               const Handle( HYDROData_PolylineXY )& thePolyline,
62               const Handle( HYDROData_PolylineXY )& theTool,
63               double theTolerance ) const
64 {
65   HYDROData_SequenceOfObjects aSeq;
66   aSeq.Append( theTool );
67   return split( theDoc, thePolyline, aSeq, theTolerance, -1 );
68 }
69
70 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
71                                         const HYDROData_SequenceOfObjects& thePolylines,
72                                         double theTolerance )
73 {
74   int f = thePolylines.Lower(), l = thePolylines.Upper();
75   for( int i=f; i<=l; i++ )
76   {
77     Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) );
78     if( !split( theDoc, aPolyline, thePolylines, theTolerance, i ) )
79       return false;
80   }
81   return true;
82 }
83
84 bool HYDROData_PolylineOperator::Merge( const Handle( HYDROData_Document )& theDoc,
85                                         const QString& theName,
86                                         const HYDROData_SequenceOfObjects& thePolylines,
87                                         bool isConnectByNewSegment,
88                                         double theTolerance )
89 {
90   TopoDS_Shape aMergedPolyline;
91
92   int f = thePolylines.Lower(), l = thePolylines.Upper();
93   for( int i=f; i<=l; i++ )
94   {
95     Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) );
96     std::vector<TopoDS_Wire> aCurves = GetWires( aPolyline );
97     for( int j=0, m=aCurves.size(); j<m; j++ )
98       if( !Merge( aMergedPolyline, aCurves[j], isConnectByNewSegment, theTolerance ) )
99         return false;
100   }
101
102   std::vector<TopoDS_Shape> aShapes( 1 );
103   aShapes[0] = aMergedPolyline;
104   CreatePolylines( theDoc, theName, aShapes, false );
105
106   return true;
107 }
108
109 bool HYDROData_PolylineOperator::Merge( TopoDS_Shape& theShape, const TopoDS_Wire& theWire, 
110                                         bool isConnectByNewSegment, double theTolerance )
111 {
112   //TODO
113   return true;
114 }
115
116 bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theDoc,
117                                         const Handle( HYDROData_PolylineXY )& thePolyline,
118                                         const HYDROData_SequenceOfObjects& theTools,
119                                         double theTolerance,
120                                         int theIgnoreIndex ) const
121 {
122   std::vector<TopoDS_Wire> aCurves = GetWires( thePolyline );
123   std::vector<TopoDS_Wire> aToolCurves;
124   for( int i=theTools.Lower(), n=theTools.Upper(); i<=n; i++ )
125     if( i!=theIgnoreIndex )
126     {
127       Handle( HYDROData_PolylineXY ) aToolPolyline = 
128         Handle( HYDROData_PolylineXY )::DownCast( theTools.Value( i ) );
129       append( aToolCurves, GetWires( aToolPolyline ) );
130     }
131
132   bool isOK = true;
133
134   int n = aCurves.size();
135   std::vector<TopoDS_Shape> aResults( n );
136   for( int i=0; i<n; i++ )
137     aResults[i] = aCurves[i];
138
139   for( int j=0, m=aToolCurves.size(); j<m; j++ )
140   {
141     std::vector<TopoDS_Shape> aNewResults;
142     for( int k=0, q=aResults.size(); k<q; k++ )
143     {
144       std::vector<TopoDS_Shape> aCurvesList = Split( TopoDS::Wire( aResults[k] ), aToolCurves[j], theTolerance );
145       append( aNewResults, aCurvesList );
146     }
147     aResults = aNewResults;
148   }
149
150   CreatePolylines( theDoc, thePolyline->GetName(), aResults, true );
151
152   return isOK;
153 }
154
155 std::vector<TopoDS_Wire> HYDROData_PolylineOperator::GetWires( const Handle( HYDROData_PolylineXY )& thePolyline )
156 {
157   std::vector<TopoDS_Wire> aResult;
158
159   TopoDS_Shape aShape = thePolyline->GetShape();
160
161   if( aShape.ShapeType()==TopAbs_WIRE )
162   {
163     aResult.push_back( TopoDS::Wire( aShape ) );
164   }
165   else
166   {
167     TopExp_Explorer anExp( aShape, TopAbs_WIRE );
168     for( ; anExp.More(); anExp.Next() )
169     {
170       aResult.push_back( TopoDS::Wire( anExp.Current() ) );
171     }
172   }
173   return aResult;
174 }
175
176 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
177                                                              const gp_Pnt2d& thePoint,
178                                                              double theTolerance )
179 {
180   std::vector<TopoDS_Shape> aResult;
181   //TODO
182   return aResult;
183 }
184
185 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
186                                                              const TopoDS_Wire& theTool,
187                                                              double theTolerance )
188 {
189   std::vector<TopoDS_Shape> aResult;
190   //TODO
191   return aResult;
192 }
193
194 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const std::vector<TopoDS_Wire>& theWires,
195                                                              double theTolerance )
196 {
197   std::vector<TopoDS_Shape> aResult;
198   //TODO
199   return aResult;
200 }
201
202 bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc,
203                                                   const QString& theNamePrefix,
204                                                   const std::vector<TopoDS_Shape>& theShapes,
205                                                   bool isUseIndices )
206 {
207   if( theDoc.IsNull() )
208     return false;
209
210   int n = theShapes.size();
211   int anIndex = 1;
212   for( int i=0; i<n; i++ )
213   {
214     Handle( HYDROData_PolylineXY ) aPolyline = 
215       Handle( HYDROData_PolylineXY )::DownCast( theDoc->CreateObject( KIND_POLYLINEXY ) );
216     if( aPolyline.IsNull() )
217       return false;
218
219     aPolyline->SetShape( theShapes[i] );
220
221     if( isUseIndices )
222     {
223       QString aNewName = theNamePrefix + "_" + QString::number( anIndex );
224       if( theDoc->FindObjectByName( aNewName ).IsNull() )  // the object with such a name is not found
225         aPolyline->SetName( aNewName );
226       anIndex++;
227     }
228     else
229     {
230       aPolyline->SetName( theNamePrefix );
231     }
232   }
233   return true;
234 }