1 #include <HYDROData_Polyline.h>
2 #include <HYDROData_Iterator.h>
4 #include <HYDROData_BSplineOperation.h>
6 #include <ImageComposer_MetaTypes.h>
8 #include <BRepBuilderAPI_MakeEdge.hxx>
9 #include <BRepBuilderAPI_MakeWire.hxx>
11 #include <TDataStd_Name.hxx>
12 #include <TDataStd_Integer.hxx>
13 #include <TDataStd_ByteArray.hxx>
14 #include <TDataStd_BooleanArray.hxx>
15 #include <TDataStd_IntegerArray.hxx>
16 #include <TDataStd_Real.hxx>
17 #include <TDataStd_RealArray.hxx>
18 #include <TDataStd_ExtStringArray.hxx>
19 #include <TDataStd_UAttribute.hxx>
20 #include <TDF_ListIteratorOfLabelList.hxx>
21 #include <TNaming_Builder.hxx>
22 #include <TNaming_NamedShape.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Wire.hxx>
26 #include <BRep_Builder.hxx>
27 #include <TopTools_ListIteratorOfListOfShape.hxx>
29 #include <QStringList>
31 // tage of the child of my label that contains information about the operator
32 static const Standard_GUID GUID_MUST_BE_UPDATED("6647e1f7-1971-4c5a-86c7-11ff0291452d");
34 #define PYTHON_POLYLINE_ID "KIND_POLYLINE"
36 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
37 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
39 HYDROData_Polyline::HYDROData_Polyline()
44 HYDROData_Polyline::~HYDROData_Polyline()
48 TopoDS_Shape HYDROData_Polyline::GetTopShape() const
54 TopoDS_Shape HYDROData_Polyline::GetShape3D() const
61 * Dump object to Python script representation.
63 QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
67 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
68 if ( aDocument.IsNull() )
71 QString aDocName = aDocument->GetDocPyName();
72 QString aPolylineName = GetName();
74 aResList << QString( "%1 = %2.CreateObject( %3 );" )
75 .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
76 aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
78 // Set polilyne dimension
80 aResList << QString( "" );
82 int aDim = GetDimension();
83 aResList << QString( "%1.SetDimension( %2 );" )
84 .arg( aPolylineName ).arg( aDim );
88 PolylineData aPolylineData = GetPolylineData();
89 if ( !aPolylineData.isEmpty() )
91 QString aPolylineDataName = "polyline_data";
93 aResList << QString( "" );
94 aResList << QString( "%1 = [];" ).arg( aPolylineDataName );
96 PolylineData::const_iterator aDataIt = aPolylineData.constBegin();
97 for ( ; aDataIt != aPolylineData.constEnd(); ++aDataIt )
99 const PolylineSection& aSection = *aDataIt;
101 QString aPolylineSectName = "polyline_section";
103 aResList << QString( "" );
104 aResList << QString( "%1 = PolylineSection();" ).arg( aPolylineSectName );
107 foreach( const double& aCoordVal, aSection.myCoords )
108 aCoordsStr += QString::number( aCoordVal ) + ", ";
109 aCoordsStr.remove( aCoordsStr.length() - 2, 2 );
111 aResList << QString( "" );
113 aResList << QString( "%1.mySectionName = \"%2\";" )
114 .arg( aPolylineSectName )
115 .arg( TCollection_AsciiString( aSection.mySectionName ).ToCString() );
116 aResList << QString( "%1.myType = %2;" )
117 .arg( aPolylineSectName ).arg( aSection.myType );
118 aResList << QString( "%1.myIsClosed = %2;" )
119 .arg( aPolylineSectName ).arg( aSection.myIsClosed );
120 aResList << QString( "%1.myCoords = [ %2 ];" )
121 .arg( aPolylineSectName ).arg( aCoordsStr );
123 aResList << QString( "%1.append( %2 );" )
124 .arg( aPolylineDataName ).arg( aPolylineSectName );
126 aResList << QString( "" );
128 aResList << QString( "%1.SetPolylineData( %2 );" )
129 .arg( aPolylineName ).arg( aPolylineDataName );
135 QVariant HYDROData_Polyline::GetDataVariant()
137 QPainterPath aPath = GetPainterPath();
140 aVarData.setValue<QPainterPath>( aPath );
146 * Replace current polyline data by new sections list
147 * \param theSections the sections list
149 void HYDROData_Polyline::SetPolylineData( const PolylineData& theSections )
152 int aDim = GetDimension();
158 if( theSections.size() == 0 )
160 int aSectionsSize = theSections.size();
164 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
165 Handle(TDataStd_ExtStringArray) aSectsNameArray;
166 aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
168 TDF_Label aSizeLab = myLab.FindChild(DataTag_SectionsSize);
169 Handle(TDataStd_IntegerArray) aSizeArray;
170 aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
172 TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed);
173 Handle(TDataStd_BooleanArray) aClosedArray;
174 aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
176 TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType);
177 Handle(TDataStd_ByteArray) aTypeArray;
178 aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
180 //Extract sections parameters and count points
181 for( int i = 0 ; i < theSections.size() ; i++ ){
182 int aSectSize = theSections[i].myCoords.size();
183 aSectsNameArray->SetValue( i, theSections[i].mySectionName );
184 aSizeArray->SetValue( i, aSectSize );
185 aClosedArray->SetValue( i, theSections[i].myIsClosed );
186 char aType = (char)theSections[i].myType;
187 aTypeArray->SetValue( i, aType );
188 aPointsCnt += aSectSize;
190 //Don't create a points array
191 if( aPointsCnt == 0 )
194 Handle(TDataStd_RealArray) anArray;
195 anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
197 for( int i = 0 ; i < theSections.size() ; i++ ){
198 for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
199 anArray->SetValue(aPtr, theSections[i].myCoords[j]);
204 UpdateWire( theSections );
208 * Return polyline data
209 * \return polyline section list
211 HYDROData_Polyline::PolylineData HYDROData_Polyline::GetPolylineData() const
215 //Get sections size array handle
216 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
217 Handle(TDataStd_IntegerArray) aSizeArray;
218 if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
219 return aRes; // return empty if no array
220 aSectCnt = aSizeArray->Length();
223 //Get section type array handle
224 aLab = myLab.FindChild( DataTag_SectionsType );
225 Handle(TDataStd_ByteArray) aTypeArray;
226 if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
228 int aLen = aTypeArray->Length();
229 if( aLen != aSectCnt )
231 //Get section closed array handle
232 aLab = myLab.FindChild( DataTag_SectionsClosed );
233 Handle(TDataStd_BooleanArray) aClosedArray;
234 if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
236 aLen = aClosedArray->Length();
237 if( aLen != aSectCnt )
240 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
241 Handle(TDataStd_ExtStringArray) aSectNamesArray;
242 if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
244 aLen = aSectNamesArray->Length();
245 if( aLen != aSectCnt )
247 //Get coordinates array
248 Handle(TDataStd_RealArray) aCoordsArray;
249 myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
252 for( int i = 0 ; i < aSectCnt ; i++ ){
253 PolylineSection aSect;
254 aSect.myIsClosed = aClosedArray->Value(i);
255 aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
256 aSect.mySectionName = aSectNamesArray->Value(i);
257 int aSectSize = aSizeArray->Value(i);
258 for( int j = 0 ; j < aSectSize ; j++ ){
259 double aCoord = aCoordsArray->Value(aCoordPtr);
260 aSect.myCoords << aCoord;
269 * Returns true if polyline is closed
271 bool HYDROData_Polyline::IsClosed() const
273 int aDim = GetDimension();
274 PolylineData aPolylineData = GetPolylineData();
276 if ( aDim == 0 || aPolylineData.isEmpty() )
279 PolylineData::const_iterator anIt = aPolylineData.constBegin();
280 for ( ; anIt != aPolylineData.constEnd(); ++anIt )
282 const PolylineSection& aSection = *anIt;
283 if ( !aSection.myIsClosed )
291 * Return polyline dimension
292 * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
294 int HYDROData_Polyline::GetDimension() const
296 Handle(TDataStd_Integer) aDim;
297 if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
303 * Set polyline dimension. Should be 2 or 3.
304 * \param theDimension the polyline dimension
306 void HYDROData_Polyline::SetDimension( int theDimension )
310 if( theDimension == 2 || theDimension == 3){
313 TDataStd_Integer::Set(myLab, aDim);
317 * Remove all polyline attributes except dimension.
319 void HYDROData_Polyline::RemoveAll()
321 //Remove only section data
322 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
323 aLab.ForgetAllAttributes();
325 aLab = myLab.FindChild( DataTag_SectionsType );
326 aLab.ForgetAllAttributes();
328 aLab = myLab.FindChild( DataTag_SectionsClosed );
329 aLab.ForgetAllAttributes();
331 myLab.ForgetAttribute(TDataStd_RealArray::GetID());
336 * Returns the painter path.
337 * Note: currently only the first section of the polyline data is taken into account.
338 * \return polyline painter path.
340 QPainterPath HYDROData_Polyline::GetPainterPath() const
343 int aDim = GetDimension();
344 if( aDim != 2 && aDim != 3 )
347 PolylineData aSects = GetPolylineData();
348 if( aSects.isEmpty() )
351 PolylineSection aSection = aSects.first();
352 int aPntCount = aSection.myCoords.size() / aDim;
353 PolylineSection::SectionType aSectionType = aSection.myType;
354 bool anIsSectionClosed = aSection.myIsClosed;
355 if( aSectionType == PolylineSection::SECTION_POLYLINE )
358 aPath.moveTo( aSection.myCoords[0], aSection.myCoords[1] );
359 for( int i = 1; i < aPntCount; i++ )
361 int anIndex = i * aDim;
362 aPath.lineTo( aSection.myCoords[ anIndex ], aSection.myCoords[ anIndex + 1 ] );
364 if( anIsSectionClosed )
365 aPath.closeSubpath();
367 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
369 QList<double> aPoints;
370 for( int i = 0; i < aPntCount; i++ )
372 int anIndex = i * aDim;
373 aPoints << aSection.myCoords[ anIndex ] << aSection.myCoords[ anIndex + 1 ];
375 HYDROData_BSplineOperation aBSpline( aPoints, 0, anIsSectionClosed );
376 aPath = aBSpline.ComputePath();
381 void HYDROData_Polyline::SetZValue( const double theZValue )
383 TDataStd_Real::Set(myLab.FindChild(DataTag_ZValue), theZValue);
386 double HYDROData_Polyline::ZValue() const
388 Handle(TDataStd_Real) aZValue;
389 if(myLab.FindChild(DataTag_ZValue).FindAttribute(TDataStd_Real::GetID(), aZValue))
390 return aZValue->Get();
394 void HYDROData_Polyline::UpdateWire( const PolylineData& theSections )
396 BRepBuilderAPI_MakeWire aMakeWire;
398 int aDim = GetDimension();
400 double aZValue = ZValue();
402 TopTools_ListOfShape aSectionWiresList;
404 int aSectionCount = theSections.size();
405 for( int aSectionId = 0; aSectionId < aSectionCount; aSectionId++ )
407 const PolylineSection& aSection = theSections[ aSectionId ];
408 PolylineSection::SectionType aSectionType = aSection.myType;
409 bool anIsSectionClosed = aSection.myIsClosed;
410 int aPointCount = aSection.myCoords.size() / aDim;
411 if( aPointCount > 1 )
413 BRepBuilderAPI_MakeWire aMakeSectionWire;
414 if( aSectionType == PolylineSection::SECTION_POLYLINE )
416 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
418 int anId1 = aDim * aPointId;
419 int anId2 = aDim * ( aPointId + 1 );
420 if( aPointId == aPointCount - 1 )
422 if( anIsSectionClosed )
428 gp_Pnt aPnt1( aSection.myCoords[ anId1 ], aSection.myCoords[ anId1 + 1 ], aZValue );
429 gp_Pnt aPnt2( aSection.myCoords[ anId2 ], aSection.myCoords[ anId2 + 1 ], aZValue );
431 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
432 aMakeSectionWire.Add( anEdge );
435 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
437 QList<double> aPoints;
438 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
440 int anId = aPointId * aDim;
441 double x = aSection.myCoords[ anId ];
442 double y = aSection.myCoords[ anId+1 ];
446 HYDROData_BSplineOperation aBSpline( aPoints, aZValue, anIsSectionClosed );
447 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSpline.Curve() ).Edge();
448 aMakeSectionWire.Add( anEdge );
450 TopoDS_Wire aSectionWire = aMakeSectionWire.Wire();
451 aSectionWiresList.Append( aSectionWire );
452 aMakeWire.Add( aSectionWire );
457 if ( aMakeWire.IsDone() ) {
458 aShape = aMakeWire.Shape();
461 TopoDS_Compound aCompound;
462 BRep_Builder aBuilder;
463 aBuilder.MakeCompound( aCompound );
464 TopTools_ListIteratorOfListOfShape anIter( aSectionWiresList );
465 for ( ; anIter.More(); anIter.Next() ) {
466 aBuilder.Add( aCompound, anIter.Value() );
471 SetTopShape( aShape );