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.
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.
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
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include <HYDROData_PolylineOperator.h>
20 #include <HYDROData_Document.h>
21 #include <BRepBuilderAPI_MakeEdge2d.hxx>
22 #include <BRepBuilderAPI_MakeWire.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Wire.hxx>
26 #include <TopExp_Explorer.hxx>
29 template<class T> void append( std::vector<T>& theList, const std::vector<T>& theList2 )
31 int aSize = theList.size();
32 int aNewSize = aSize + theList2.size();
37 theList.resize( aNewSize );
38 for( int i=aSize, j=0; i<aNewSize; i++, j++ )
39 theList[i] = theList2[j];
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
47 std::vector<gp_Pnt2d> aPointsList( 1 );
48 aPointsList[0] = thePoint;
49 std::vector<TopoDS_Wire> aCurves = GetWires( thePolyline );
51 for( int i=0, n=aCurves.size(); i<n; i++ )
53 std::vector<TopoDS_Shape> aCurvesList = Split( aCurves[i], thePoint, theTolerance );
54 bool isLocalOK = CreatePolylines( theDoc, thePolyline->GetName(), aCurvesList, true );
55 isOK = isOK && isLocalOK;
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
65 HYDROData_SequenceOfObjects aSeq;
66 aSeq.Append( theTool );
67 return split( theDoc, thePolyline, aSeq, theTolerance, -1 );
70 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
71 const HYDROData_SequenceOfObjects& thePolylines,
74 int f = thePolylines.Lower(), l = thePolylines.Upper();
75 for( int i=f; i<=l; i++ )
77 Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) );
78 if( !split( theDoc, aPolyline, thePolylines, theTolerance, i ) )
84 bool HYDROData_PolylineOperator::Merge( const Handle( HYDROData_Document )& theDoc,
85 const QString& theName,
86 const HYDROData_SequenceOfObjects& thePolylines,
87 bool isConnectByNewSegment,
90 TopoDS_Shape aMergedPolyline;
92 int f = thePolylines.Lower(), l = thePolylines.Upper();
93 for( int i=f; i<=l; i++ )
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 ) )
102 std::vector<TopoDS_Shape> aShapes( 1 );
103 aShapes[0] = aMergedPolyline;
104 CreatePolylines( theDoc, theName, aShapes, false );
109 bool HYDROData_PolylineOperator::Merge( TopoDS_Shape& theShape, const TopoDS_Wire& theWire,
110 bool isConnectByNewSegment, double theTolerance )
116 bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theDoc,
117 const Handle( HYDROData_PolylineXY )& thePolyline,
118 const HYDROData_SequenceOfObjects& theTools,
120 int theIgnoreIndex ) const
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 )
127 Handle( HYDROData_PolylineXY ) aToolPolyline =
128 Handle( HYDROData_PolylineXY )::DownCast( theTools.Value( i ) );
129 append( aToolCurves, GetWires( aToolPolyline ) );
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];
139 for( int j=0, m=aToolCurves.size(); j<m; j++ )
141 std::vector<TopoDS_Shape> aNewResults;
142 for( int k=0, q=aResults.size(); k<q; k++ )
144 std::vector<TopoDS_Shape> aCurvesList = Split( TopoDS::Wire( aResults[k] ), aToolCurves[j], theTolerance );
145 append( aNewResults, aCurvesList );
147 aResults = aNewResults;
150 CreatePolylines( theDoc, thePolyline->GetName(), aResults, true );
155 std::vector<TopoDS_Wire> HYDROData_PolylineOperator::GetWires( const Handle( HYDROData_PolylineXY )& thePolyline )
157 std::vector<TopoDS_Wire> aResult;
159 TopoDS_Shape aShape = thePolyline->GetShape();
161 if( aShape.ShapeType()==TopAbs_WIRE )
163 aResult.push_back( TopoDS::Wire( aShape ) );
167 TopExp_Explorer anExp( aShape, TopAbs_WIRE );
168 for( ; anExp.More(); anExp.Next() )
170 aResult.push_back( TopoDS::Wire( anExp.Current() ) );
176 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
177 const gp_Pnt2d& thePoint,
178 double theTolerance )
180 std::vector<TopoDS_Shape> aResult;
185 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
186 const TopoDS_Wire& theTool,
187 double theTolerance )
189 std::vector<TopoDS_Shape> aResult;
194 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const std::vector<TopoDS_Wire>& theWires,
195 double theTolerance )
197 std::vector<TopoDS_Shape> aResult;
202 bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc,
203 const QString& theNamePrefix,
204 const std::vector<TopoDS_Shape>& theShapes,
207 if( theDoc.IsNull() )
210 int n = theShapes.size();
212 for( int i=0; i<n; i++ )
214 Handle( HYDROData_PolylineXY ) aPolyline =
215 Handle( HYDROData_PolylineXY )::DownCast( theDoc->CreateObject( KIND_POLYLINEXY ) );
216 if( aPolyline.IsNull() )
219 aPolyline->SetShape( theShapes[i] );
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 );
230 aPolyline->SetName( theNamePrefix );