1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <HYDROData_Polyline.h>
24 #include <HYDROData_Iterator.h>
26 #include <HYDROData_BSplineOperation.h>
28 #include <ImageComposer_MetaTypes.h>
30 #include <BRepBuilderAPI_MakeEdge.hxx>
31 #include <BRepBuilderAPI_MakeWire.hxx>
33 #include <TDataStd_Name.hxx>
34 #include <TDataStd_Integer.hxx>
35 #include <TDataStd_ByteArray.hxx>
36 #include <TDataStd_BooleanArray.hxx>
37 #include <TDataStd_IntegerArray.hxx>
38 #include <TDataStd_Real.hxx>
39 #include <TDataStd_RealArray.hxx>
40 #include <TDataStd_ExtStringArray.hxx>
41 #include <TDataStd_UAttribute.hxx>
42 #include <TDF_ListIteratorOfLabelList.hxx>
43 #include <TNaming_Builder.hxx>
44 #include <TNaming_NamedShape.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Wire.hxx>
48 #include <BRep_Builder.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <QStringList>
53 #define PYTHON_POLYLINE_ID "KIND_POLYLINE"
55 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
56 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
58 HYDROData_Polyline::HYDROData_Polyline()
63 HYDROData_Polyline::~HYDROData_Polyline()
67 TopoDS_Shape HYDROData_Polyline::GetTopShape() const
73 TopoDS_Shape HYDROData_Polyline::GetShape3D() const
80 * Dump object to Python script representation.
82 QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
86 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
87 if ( aDocument.IsNull() )
90 QString aDocName = aDocument->GetDocPyName();
91 QString aPolylineName = GetName();
93 aResList << QString( "%1 = %2.CreateObject( %3 );" )
94 .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
95 aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
97 // Set polilyne dimension
99 aResList << QString( "" );
101 int aDim = GetDimension();
102 aResList << QString( "%1.SetDimension( %2 );" )
103 .arg( aPolylineName ).arg( aDim );
107 PolylineData aPolylineData = GetPolylineData();
108 if ( !aPolylineData.isEmpty() )
110 QString aPolylineDataName = "polyline_data";
112 aResList << QString( "" );
113 aResList << QString( "%1 = [];" ).arg( aPolylineDataName );
115 PolylineData::const_iterator aDataIt = aPolylineData.constBegin();
116 for ( ; aDataIt != aPolylineData.constEnd(); ++aDataIt )
118 const PolylineSection& aSection = *aDataIt;
120 QString aPolylineSectName = "polyline_section";
122 aResList << QString( "" );
123 aResList << QString( "%1 = PolylineSection();" ).arg( aPolylineSectName );
126 foreach( const double& aCoordVal, aSection.myCoords )
127 aCoordsStr += QString::number( aCoordVal ) + ", ";
128 aCoordsStr.remove( aCoordsStr.length() - 2, 2 );
130 aResList << QString( "" );
132 aResList << QString( "%1.mySectionName = \"%2\";" )
133 .arg( aPolylineSectName )
134 .arg( TCollection_AsciiString( aSection.mySectionName ).ToCString() );
135 aResList << QString( "%1.myType = %2;" )
136 .arg( aPolylineSectName ).arg( aSection.myType );
137 aResList << QString( "%1.myIsClosed = %2;" )
138 .arg( aPolylineSectName ).arg( aSection.myIsClosed );
139 aResList << QString( "%1.myCoords = [ %2 ];" )
140 .arg( aPolylineSectName ).arg( aCoordsStr );
142 aResList << QString( "%1.append( %2 );" )
143 .arg( aPolylineDataName ).arg( aPolylineSectName );
145 aResList << QString( "" );
147 aResList << QString( "%1.SetPolylineData( %2 );" )
148 .arg( aPolylineName ).arg( aPolylineDataName );
154 QVariant HYDROData_Polyline::GetDataVariant()
156 QPainterPath aPath = GetPainterPath();
159 aVarData.setValue<QPainterPath>( aPath );
165 * Replace current polyline data by new sections list
166 * \param theSections the sections list
168 void HYDROData_Polyline::SetPolylineData( const PolylineData& theSections )
171 int aDim = GetDimension();
177 if( theSections.size() == 0 )
179 int aSectionsSize = theSections.size();
183 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
184 Handle(TDataStd_ExtStringArray) aSectsNameArray;
185 aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
187 TDF_Label aSizeLab = myLab.FindChild(DataTag_SectionsSize);
188 Handle(TDataStd_IntegerArray) aSizeArray;
189 aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
191 TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed);
192 Handle(TDataStd_BooleanArray) aClosedArray;
193 aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
195 TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType);
196 Handle(TDataStd_ByteArray) aTypeArray;
197 aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
199 //Extract sections parameters and count points
200 for( int i = 0 ; i < theSections.size() ; i++ ){
201 int aSectSize = theSections[i].myCoords.size();
202 aSectsNameArray->SetValue( i, theSections[i].mySectionName );
203 aSizeArray->SetValue( i, aSectSize );
204 aClosedArray->SetValue( i, theSections[i].myIsClosed );
205 char aType = (char)theSections[i].myType;
206 aTypeArray->SetValue( i, aType );
207 aPointsCnt += aSectSize;
209 //Don't create a points array
210 if( aPointsCnt == 0 )
213 Handle(TDataStd_RealArray) anArray;
214 anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
216 for( int i = 0 ; i < theSections.size() ; i++ ){
217 for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
218 anArray->SetValue(aPtr, theSections[i].myCoords[j]);
223 UpdateWire( theSections );
227 * Return polyline data
228 * \return polyline section list
230 HYDROData_Polyline::PolylineData HYDROData_Polyline::GetPolylineData() const
234 //Get sections size array handle
235 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
236 Handle(TDataStd_IntegerArray) aSizeArray;
237 if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
238 return aRes; // return empty if no array
239 aSectCnt = aSizeArray->Length();
242 //Get section type array handle
243 aLab = myLab.FindChild( DataTag_SectionsType );
244 Handle(TDataStd_ByteArray) aTypeArray;
245 if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
247 int aLen = aTypeArray->Length();
248 if( aLen != aSectCnt )
250 //Get section closed array handle
251 aLab = myLab.FindChild( DataTag_SectionsClosed );
252 Handle(TDataStd_BooleanArray) aClosedArray;
253 if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
255 aLen = aClosedArray->Length();
256 if( aLen != aSectCnt )
259 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
260 Handle(TDataStd_ExtStringArray) aSectNamesArray;
261 if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
263 aLen = aSectNamesArray->Length();
264 if( aLen != aSectCnt )
266 //Get coordinates array
267 Handle(TDataStd_RealArray) aCoordsArray;
268 myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
271 for( int i = 0 ; i < aSectCnt ; i++ ){
272 PolylineSection aSect;
273 aSect.myIsClosed = aClosedArray->Value(i);
274 aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
275 aSect.mySectionName = aSectNamesArray->Value(i);
276 int aSectSize = aSizeArray->Value(i);
277 for( int j = 0 ; j < aSectSize ; j++ ){
278 double aCoord = aCoordsArray->Value(aCoordPtr);
279 aSect.myCoords << aCoord;
288 * Returns true if polyline is closed
290 bool HYDROData_Polyline::IsClosed() const
292 int aDim = GetDimension();
293 PolylineData aPolylineData = GetPolylineData();
295 if ( aDim == 0 || aPolylineData.isEmpty() )
298 PolylineData::const_iterator anIt = aPolylineData.constBegin();
299 for ( ; anIt != aPolylineData.constEnd(); ++anIt )
301 const PolylineSection& aSection = *anIt;
302 if ( !aSection.myIsClosed )
310 * Return polyline dimension
311 * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
313 int HYDROData_Polyline::GetDimension() const
315 Handle(TDataStd_Integer) aDim;
316 if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
322 * Set polyline dimension. Should be 2 or 3.
323 * \param theDimension the polyline dimension
325 void HYDROData_Polyline::SetDimension( int theDimension )
329 if( theDimension == 2 || theDimension == 3){
332 TDataStd_Integer::Set(myLab, aDim);
336 * Remove all polyline attributes except dimension.
338 void HYDROData_Polyline::RemoveAll()
340 //Remove only section data
341 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
342 aLab.ForgetAllAttributes();
344 aLab = myLab.FindChild( DataTag_SectionsType );
345 aLab.ForgetAllAttributes();
347 aLab = myLab.FindChild( DataTag_SectionsClosed );
348 aLab.ForgetAllAttributes();
350 myLab.ForgetAttribute(TDataStd_RealArray::GetID());
355 * Returns the painter path.
356 * Note: currently only the first section of the polyline data is taken into account.
357 * \return polyline painter path.
359 QPainterPath HYDROData_Polyline::GetPainterPath() const
362 int aDim = GetDimension();
363 if( aDim != 2 && aDim != 3 )
366 PolylineData aSects = GetPolylineData();
367 if( aSects.isEmpty() )
370 PolylineSection aSection = aSects.first();
371 int aPntCount = aSection.myCoords.size() / aDim;
372 PolylineSection::SectionType aSectionType = aSection.myType;
373 bool anIsSectionClosed = aSection.myIsClosed;
374 if( aSectionType == PolylineSection::SECTION_POLYLINE )
377 aPath.moveTo( aSection.myCoords[0], aSection.myCoords[1] );
378 for( int i = 1; i < aPntCount; i++ )
380 int anIndex = i * aDim;
381 aPath.lineTo( aSection.myCoords[ anIndex ], aSection.myCoords[ anIndex + 1 ] );
383 if( anIsSectionClosed )
384 aPath.closeSubpath();
386 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
388 QList<double> aPoints;
389 for( int i = 0; i < aPntCount; i++ )
391 int anIndex = i * aDim;
392 aPoints << aSection.myCoords[ anIndex ] << aSection.myCoords[ anIndex + 1 ];
394 HYDROData_BSplineOperation aBSpline( aPoints, 0, anIsSectionClosed );
395 aPath = aBSpline.ComputePath();
400 void HYDROData_Polyline::SetZValue( const double theZValue )
402 TDataStd_Real::Set(myLab.FindChild(DataTag_ZValue), theZValue);
405 double HYDROData_Polyline::ZValue() const
407 Handle(TDataStd_Real) aZValue;
408 if(myLab.FindChild(DataTag_ZValue).FindAttribute(TDataStd_Real::GetID(), aZValue))
409 return aZValue->Get();
413 void HYDROData_Polyline::UpdateWire( const PolylineData& theSections )
415 BRepBuilderAPI_MakeWire aMakeWire;
417 int aDim = GetDimension();
419 double aZValue = ZValue();
421 TopTools_ListOfShape aSectionWiresList;
423 int aSectionCount = theSections.size();
424 for( int aSectionId = 0; aSectionId < aSectionCount; aSectionId++ )
426 const PolylineSection& aSection = theSections[ aSectionId ];
427 PolylineSection::SectionType aSectionType = aSection.myType;
428 bool anIsSectionClosed = aSection.myIsClosed;
429 int aPointCount = aSection.myCoords.size() / aDim;
430 if( aPointCount > 1 )
432 BRepBuilderAPI_MakeWire aMakeSectionWire;
433 if( aSectionType == PolylineSection::SECTION_POLYLINE )
435 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
437 int anId1 = aDim * aPointId;
438 int anId2 = aDim * ( aPointId + 1 );
439 if( aPointId == aPointCount - 1 )
441 if( anIsSectionClosed )
447 gp_Pnt aPnt1( aSection.myCoords[ anId1 ], aSection.myCoords[ anId1 + 1 ], aZValue );
448 gp_Pnt aPnt2( aSection.myCoords[ anId2 ], aSection.myCoords[ anId2 + 1 ], aZValue );
450 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
451 aMakeSectionWire.Add( anEdge );
454 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
456 QList<double> aPoints;
457 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
459 int anId = aPointId * aDim;
460 double x = aSection.myCoords[ anId ];
461 double y = aSection.myCoords[ anId+1 ];
465 HYDROData_BSplineOperation aBSpline( aPoints, aZValue, anIsSectionClosed );
466 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSpline.Curve() ).Edge();
467 aMakeSectionWire.Add( anEdge );
469 TopoDS_Wire aSectionWire = aMakeSectionWire.Wire();
470 aSectionWiresList.Append( aSectionWire );
471 aMakeWire.Add( aSectionWire );
476 if ( aMakeWire.IsDone() ) {
477 aShape = aMakeWire.Shape();
480 TopoDS_Compound aCompound;
481 BRep_Builder aBuilder;
482 aBuilder.MakeCompound( aCompound );
483 TopTools_ListIteratorOfListOfShape anIter( aSectionWiresList );
484 for ( ; anIter.More(); anIter.Next() ) {
485 aBuilder.Add( aCompound, anIter.Value() );
490 SetTopShape( aShape );