1 #include <HYDROData_Polyline.h>
2 #include <HYDROData_Iterator.h>
4 #include <HYDROOperations_BSpline.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_RealArray.hxx>
17 #include <TDataStd_ExtStringArray.hxx>
18 #include <TDataStd_UAttribute.hxx>
19 #include <TDF_ListIteratorOfLabelList.hxx>
20 #include <TNaming_Builder.hxx>
21 #include <TNaming_NamedShape.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Wire.hxx>
26 #include <QStringList>
28 // tage of the child of my label that contains information about the operator
29 static const Standard_GUID GUID_MUST_BE_UPDATED("6647e1f7-1971-4c5a-86c7-11ff0291452d");
31 #define PYTHON_POLYLINE_ID "KIND_POLYLINE"
33 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
34 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
36 HYDROData_Polyline::HYDROData_Polyline()
40 HYDROData_Polyline::~HYDROData_Polyline()
45 * Dump object to Python script representation.
47 QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
51 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( this );
52 if ( aDocument.IsNull() )
55 QString aDocName = aDocument->GetDocPyName();
56 QString aPolylineName = GetName();
58 aResList << QString( "%1 = %2.CreateObject( %3 );" )
59 .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
60 aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
62 // Set polilyne dimension
64 aResList << QString( "" );
66 int aDim = getDimension();
67 aResList << QString( "%1.setDimension( %2 );" )
68 .arg( aPolylineName ).arg( aDim );
72 PolylineData aPolylineData = getPolylineData();
73 if ( !aPolylineData.isEmpty() )
75 QString aPolylineDataName = "polyline_data";
77 aResList << QString( "" );
78 aResList << QString( "%1 = [];" ).arg( aPolylineDataName );
80 PolylineData::const_iterator aDataIt = aPolylineData.constBegin();
81 for ( ; aDataIt != aPolylineData.constEnd(); ++aDataIt )
83 const PolylineSection& aSection = *aDataIt;
85 QString aPolylineSectName = "polyline_section";
87 aResList << QString( "" );
88 aResList << QString( "%1 = PolylineSection();" ).arg( aPolylineSectName );
91 foreach( const double& aCoordVal, aSection.myCoords )
92 aCoordsStr += QString::number( aCoordVal ) + ", ";
93 aCoordsStr.remove( aCoordsStr.length() - 2, 2 );
95 aResList << QString( "" );
97 aResList << QString( "%1.mySectionName = \"%2\";" )
98 .arg( aPolylineSectName )
99 .arg( TCollection_AsciiString( aSection.mySectionName ).ToCString() );
100 aResList << QString( "%1.myType = %2;" )
101 .arg( aPolylineSectName ).arg( aSection.myType );
102 aResList << QString( "%1.myIsClosed = %2;" )
103 .arg( aPolylineSectName ).arg( aSection.myIsClosed );
104 aResList << QString( "%1.myCoords = [ %2 ];" )
105 .arg( aPolylineSectName ).arg( aCoordsStr );
107 aResList << QString( "%1.append( %2 );" )
108 .arg( aPolylineDataName ).arg( aPolylineSectName );
111 aResList << QString( "%1.setPolylineData( %2 );" )
112 .arg( aPolylineName ).arg( aPolylineDataName );
118 QVariant HYDROData_Polyline::GetDataVariant()
120 QPainterPath aPath = painterPath();
123 aVarData.setValue<QPainterPath>( aPath );
129 * Return polyline dimension
130 * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
132 int HYDROData_Polyline::getDimension() const
134 Handle(TDataStd_Integer) aDim;
135 if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
141 * Set polyline dimension. Should be 2 or 3.
142 * \param theDimension the polyline dimension
144 void HYDROData_Polyline::setDimension( int theDimension )
148 if( theDimension == 2 || theDimension == 3){
151 TDataStd_Integer::Set(myLab, aDim);
155 * Replace current polyline data by new sections list
156 * \param theSections the sections list
158 void HYDROData_Polyline::setPolylineData( const PolylineData& theSections )
161 int aDim = getDimension();
167 if( theSections.size() == 0 )
169 int aSectionsSize = theSections.size();
173 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
174 Handle(TDataStd_ExtStringArray) aSectsNameArray;
175 aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
177 TDF_Label aSizeLab = myLab.FindChild(DataTag_SectionsSize);
178 Handle(TDataStd_IntegerArray) aSizeArray;
179 aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
181 TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed);
182 Handle(TDataStd_BooleanArray) aClosedArray;
183 aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
185 TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType);
186 Handle(TDataStd_ByteArray) aTypeArray;
187 aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
189 //Extract sections parameters and count points
190 for( int i = 0 ; i < theSections.size() ; i++ ){
191 int aSectSize = theSections[i].myCoords.size();
192 aSectsNameArray->SetValue( i, theSections[i].mySectionName );
193 aSizeArray->SetValue( i, aSectSize );
194 aClosedArray->SetValue( i, theSections[i].myIsClosed );
195 char aType = (char)theSections[i].myType;
196 aTypeArray->SetValue( i, aType );
197 aPointsCnt += aSectSize;
199 //Don't create a points array
200 if( aPointsCnt == 0 )
203 Handle(TDataStd_RealArray) anArray;
204 anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
206 for( int i = 0 ; i < theSections.size() ; i++ ){
207 for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
208 anArray->SetValue(aPtr, theSections[i].myCoords[j]);
213 UpdateWire( theSections );
217 * Return polyline data
218 * \return polyline section list
220 HYDROData_Polyline::PolylineData HYDROData_Polyline::getPolylineData() const
224 //Get sections size array handle
225 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
226 Handle(TDataStd_IntegerArray) aSizeArray;
227 if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
228 return aRes; // return empty if no array
229 aSectCnt = aSizeArray->Length();
232 //Get section type array handle
233 aLab = myLab.FindChild( DataTag_SectionsType );
234 Handle(TDataStd_ByteArray) aTypeArray;
235 if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
237 int aLen = aTypeArray->Length();
238 if( aLen != aSectCnt )
240 //Get section closed array handle
241 aLab = myLab.FindChild( DataTag_SectionsClosed );
242 Handle(TDataStd_BooleanArray) aClosedArray;
243 if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
245 aLen = aClosedArray->Length();
246 if( aLen != aSectCnt )
249 TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
250 Handle(TDataStd_ExtStringArray) aSectNamesArray;
251 if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
253 aLen = aSectNamesArray->Length();
254 if( aLen != aSectCnt )
256 //Get coordinates array
257 Handle(TDataStd_RealArray) aCoordsArray;
258 myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
261 for( int i = 0 ; i < aSectCnt ; i++ ){
262 PolylineSection aSect;
263 aSect.myIsClosed = aClosedArray->Value(i);
264 aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
265 aSect.mySectionName = aSectNamesArray->Value(i);
266 int aSectSize = aSizeArray->Value(i);
267 for( int j = 0 ; j < aSectSize ; j++ ){
268 double aCoord = aCoordsArray->Value(aCoordPtr);
269 aSect.myCoords << aCoord;
278 * Returns true if polyline is closed
280 bool HYDROData_Polyline::isClosed() const
282 int aDim = getDimension();
283 PolylineData aPolylineData = getPolylineData();
285 if ( aDim == 0 || aPolylineData.isEmpty() )
288 PolylineData::const_iterator anIt = aPolylineData.constBegin();
289 for ( ; anIt != aPolylineData.constEnd(); ++anIt )
291 const PolylineSection& aSection = *anIt;
292 if ( !aSection.myIsClosed )
300 * Remove all polyline attributes except dimension.
302 void HYDROData_Polyline::removeAll()
304 //Remove only section data
305 TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
306 aLab.ForgetAllAttributes();
308 aLab = myLab.FindChild( DataTag_SectionsType );
309 aLab.ForgetAllAttributes();
311 aLab = myLab.FindChild( DataTag_SectionsClosed );
312 aLab.ForgetAllAttributes();
314 myLab.ForgetAttribute(TDataStd_RealArray::GetID());
319 * Returns the painter path.
320 * Note: currently only the first section of the polyline data is taken into account.
321 * \return polyline painter path.
323 QPainterPath HYDROData_Polyline::painterPath() const
326 int aDim = getDimension();
327 if( aDim != 2 && aDim != 3 )
330 PolylineData aSects = getPolylineData();
331 if( aSects.isEmpty() )
334 PolylineSection aSection = aSects.first();
335 int aPntCount = aSection.myCoords.size() / aDim;
336 PolylineSection::SectionType aSectionType = aSection.myType;
337 bool anIsSectionClosed = aSection.myIsClosed;
338 if( aSectionType == PolylineSection::SECTION_POLYLINE )
341 aPath.moveTo( aSection.myCoords[0], aSection.myCoords[1] );
342 for( int i = 1; i < aPntCount; i++ )
344 int anIndex = i * aDim;
345 aPath.lineTo( aSection.myCoords[ anIndex ], aSection.myCoords[ anIndex + 1 ] );
347 if( anIsSectionClosed )
348 aPath.closeSubpath();
350 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
352 QList<double> aPoints;
353 for( int i = 0; i < aPntCount; i++ )
355 int anIndex = i * aDim;
356 aPoints << aSection.myCoords[ anIndex ] << aSection.myCoords[ anIndex + 1 ];
358 HYDROOperations_BSpline aBSpline( aPoints, anIsSectionClosed );
359 aPath = aBSpline.ComputePath();
364 void HYDROData_Polyline::SetWire( const TopoDS_Wire& theWire )
366 TNaming_Builder aBuilder( myLab );
367 aBuilder.Generated( theWire );
370 TopoDS_Wire HYDROData_Polyline::Wire() const
372 Handle(TNaming_NamedShape) aNamedShape;
373 if( myLab.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) )
374 return TopoDS::Wire( aNamedShape->Get() );
375 return TopoDS_Wire();
378 void HYDROData_Polyline::UpdateWire( const PolylineData& theSections )
380 BRepBuilderAPI_MakeWire aMakeWire;
382 int aDim = getDimension();
384 int aSectionCount = theSections.size();
385 for( int aSectionId = 0; aSectionId < aSectionCount; aSectionId++ )
387 const PolylineSection& aSection = theSections[ aSectionId ];
388 PolylineSection::SectionType aSectionType = aSection.myType;
389 bool anIsSectionClosed = aSection.myIsClosed;
390 int aPointCount = aSection.myCoords.size() / aDim;
391 if( aPointCount > 1 )
393 BRepBuilderAPI_MakeWire aMakeSectionWire;
394 if( aSectionType == PolylineSection::SECTION_POLYLINE )
396 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
398 int anId1 = aDim * aPointId;
399 int anId2 = aDim * ( aPointId + 1 );
400 if( aPointId == aPointCount - 1 )
402 if( anIsSectionClosed )
408 gp_Pnt aPnt1( aSection.myCoords[ anId1 ], aSection.myCoords[ anId1 + 1 ], 0 );
409 gp_Pnt aPnt2( aSection.myCoords[ anId2 ], aSection.myCoords[ anId2 + 1 ], 0 );
411 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
412 aMakeSectionWire.Add( anEdge );
415 else //if( aSectionType == PolylineSection::SECTION_SPLINE )
417 QList<double> aPoints;
418 for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
420 int anId = aPointId * aDim;
421 double x = aSection.myCoords[ anId ];
422 double y = aSection.myCoords[ anId+1 ];
426 HYDROOperations_BSpline aBSpline( aPoints, anIsSectionClosed );
427 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSpline.Curve() ).Edge();
428 aMakeSectionWire.Add( anEdge );
430 TopoDS_Wire aSectionWire = aMakeSectionWire.Wire();
431 aMakeWire.Add( aSectionWire );
435 TopoDS_Wire aWire = aMakeWire.Wire();