#include <HYDROData_Polyline.h>
#include <HYDROData_Iterator.h>
-#include <TDataStd_RealArray.hxx>
#include <TDataStd_Name.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TDataStd_ByteArray.hxx>
+#include <TDataStd_BooleanArray.hxx>
+#include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_RealArray.hxx>
+#include <TDataStd_ExtStringArray.hxx>
#include <TDataStd_UAttribute.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
+#include <QPainterPath>
+
// tage of the child of my label that contains information about the operator
static const Standard_GUID GUID_MUST_BE_UPDATED("6647e1f7-1971-4c5a-86c7-11ff0291452d");
+#define TAG_POINTS 1
+#define TAG_SECTIONS_NAME 2
+#define TAG_SECTIONS_CLOSED 3
+#define TAG_SECTIONS_SIZE 4
+#define TAG_SECTIONS_TYPE 5
+
IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
{
}
-void HYDROData_Polyline::setPoints( QList<QPointF> thePointsList )
+/**
+ * Return polyline dimension
+ * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
+ */
+int HYDROData_Polyline::getDimension() const
{
- removeAllPoints();
- if( thePointsList.isEmpty() )
- return;
- Handle(TDataStd_RealArray) anArray;
- anArray = TDataStd_RealArray::Set( myLab, 0, thePointsList.size()*2-1 );
- for( int i = 0 ; i < thePointsList.size() ; i++ ){
- anArray->SetValue(i*2, thePointsList[i].x() );
- anArray->SetValue(i*2+1, thePointsList[i].y() );
- }
+ Handle(TDataStd_Integer) aDim;
+ if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
+ return 0;
+ return aDim->Get();
}
-void HYDROData_Polyline::addPoint( const QPointF& thePoint )
+/**
+ * Set polyline dimension. Should be 2 or 3.
+ * \param theDimension the polyline dimension
+ */
+void HYDROData_Polyline::setDimension( int theDimension )
{
- QList<QPointF> aPointsArray = points();
- aPointsArray.append( thePoint );
- setPoints( aPointsArray );
-}
-
-void HYDROData_Polyline::insertPoint( int theIndex, const QPointF& thePoint)
-{
- QList<QPointF> aPointsArray = points();
- aPointsArray.insert( theIndex, thePoint );
- setPoints( aPointsArray );
+ removeAll();
+ int aDim=0;
+ if( theDimension == 2 || theDimension == 3){
+ aDim = theDimension;
+ }
+ TDataStd_Integer::Set(myLab, aDim);
}
-void HYDROData_Polyline::removePoint( int theIndex )
+/**
+ * Replace current polyline data by new sections list
+ * \param theSections the sections list
+ */
+void HYDROData_Polyline::setPolylineData( const QList<PolylineSection>& theSections )
{
- QList<QPointF> aPointsArray = points();
- aPointsArray.removeAt( theIndex );
- setPoints( aPointsArray );
-}
+//Keep dimension
+ int aDim = getDimension();
+ if( aDim == 0 )
+ return;
+ removeAll();
+ setDimension(aDim);
-void HYDROData_Polyline::removeAllPoints()
-{
- myLab.ForgetAttribute(TDataStd_RealArray::GetID());
- return;
-}
+ if( theSections.size() == 0 )
+ return;
+ int aSectionsSize = theSections.size();
-int HYDROData_Polyline::pointsCount()
-{
+ int aPointsCnt = 0;
+
+ TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
+ Handle(TDataStd_ExtStringArray) aSectsNameArray;
+ aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
+
+ TDF_Label aSizeLab = myLab.FindChild(TAG_SECTIONS_SIZE);
+ Handle(TDataStd_IntegerArray) aSizeArray;
+ aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
+
+ TDF_Label aClosedLab = myLab.FindChild(TAG_SECTIONS_CLOSED);
+ Handle(TDataStd_BooleanArray) aClosedArray;
+ aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
+
+ TDF_Label aTypeLab = myLab.FindChild(TAG_SECTIONS_TYPE);
+ Handle(TDataStd_ByteArray) aTypeArray;
+ aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
+
+//Extract sections parameters and count points
+ for( int i = 0 ; i < theSections.size() ; i++ ){
+ int aSectSize = theSections[i].myCoords.size();
+ aSectsNameArray->SetValue( i, theSections[i].mySectionName );
+ aSizeArray->SetValue( i, aSectSize );
+ aClosedArray->SetValue( i, theSections[i].myIsClosed );
+ char aType = (char)theSections[i].myType;
+ aTypeArray->SetValue( i, aType );
+ aPointsCnt += aSectSize;
+ }
+//Don't create a points array
+ if( aPointsCnt == 0 )
+ return;
+//Save coordinates
Handle(TDataStd_RealArray) anArray;
- if(!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray))
- return 0;
- return anArray->Length()/2;
+ anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
+ int aPtr = 0;
+ for( int i = 0 ; i < theSections.size() ; i++ ){
+ for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
+ anArray->SetValue(aPtr, theSections[i].myCoords[j]);
+ aPtr++;
+ }
+ }
}
-QList<QPointF> HYDROData_Polyline::points()
+/**
+ * Return polyline data
+ * \return polyline section list
+ */
+QList<PolylineSection> HYDROData_Polyline::getPolylineData()
{
- QList<QPointF> aRes;
- Handle(TDataStd_RealArray) anArray;
- if(!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray))
+ int aSectCnt;
+ QList<PolylineSection> aRes;
+//Get sections size array handle
+ TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
+ Handle(TDataStd_IntegerArray) aSizeArray;
+ if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
+ return aRes; // return empty if no array
+ aSectCnt = aSizeArray->Length();
+ if( aSectCnt == 0 )
+ return aRes;
+//Get section type array handle
+ aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
+ Handle(TDataStd_ByteArray) aTypeArray;
+ if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
+ return aRes;
+ int aLen = aTypeArray->Length();
+ if( aLen != aSectCnt )
+ return aRes;
+//Get section closed array handle
+ aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
+ Handle(TDataStd_BooleanArray) aClosedArray;
+ if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
+ return aRes;
+ aLen = aClosedArray->Length();
+ if( aLen != aSectCnt )
+ return aRes;
+//Get sections names
+ TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
+ Handle(TDataStd_ExtStringArray) aSectNamesArray;
+ if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
return aRes;
- int anArraySize = anArray->Length();
- for( int i = 0 ; i < anArraySize/2 ; i++ ){
- qreal anX = anArray->Value( i*2 );
- qreal anY = anArray->Value( i*2 + 1 );
- QPointF aPoint( anX, anY );
- aRes.append( aPoint );
+ aLen = aSectNamesArray->Length();
+ if( aLen != aSectCnt )
+ return aRes;
+//Get coordinates array
+ Handle(TDataStd_RealArray) aCoordsArray;
+ myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
+
+ int aCoordPtr = 0;
+ for( int i = 0 ; i < aSectCnt ; i++ ){
+ PolylineSection aSect;
+ aSect.myIsClosed = aClosedArray->Value(i);
+ aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
+ aSect.mySectionName = aSectNamesArray->Value(i);
+ int aSectSize = aSizeArray->Value(i);
+ for( int j = 0 ; j < aSectSize ; j++ ){
+ double aCoord = aCoordsArray->Value(aCoordPtr);
+ aSect.myCoords << aCoord;
+ aCoordPtr++;
+ }
+ aRes << aSect;
}
return aRes;
}
-QPainterPath HYDROData_Polyline::painterPathLinear()
+/**
+ * Remove all polyline attributes except dimension.
+ */
+void HYDROData_Polyline::removeAll()
+{
+//Remove only section data
+ TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
+ aLab.ForgetAllAttributes();
+
+ aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
+ aLab.ForgetAllAttributes();
+
+ aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
+ aLab.ForgetAllAttributes();
+
+ myLab.ForgetAttribute(TDataStd_RealArray::GetID());
+ return;
+}
+
+/**
+ * Return polyline painter path. Current implementation
+ * is ignored section type.
+ * \return polyline painter path.
+ */
+QPainterPath HYDROData_Polyline::painterPath()
{
QPainterPath aPath;
- QList<QPointF> aPointsArray = points();
- if( aPointsArray.size() == 0 )
- return aPath;
- aPath.moveTo( aPointsArray[0] );
- for( int i = 0 ; i < aPointsArray.size() ; i++ ){
- aPath.lineTo( aPointsArray[i] );
+ int aDim = getDimension();
+ if( ( aDim != 2 ) || ( aDim != 3) )
+ return aPath;
+ QList<PolylineSection> aSects = getPolylineData();
+ for( int i = 0 ; aSects.size() ; i++ ){
+ int aPntCnt = aSects[i].myCoords.size()/aDim;
+ if( aPntCnt ){
+ aPath.moveTo(aSects[i].myCoords[0], aSects[i].myCoords[1] );
+ }
+ for( int j = 1 ; j < aPntCnt ; j++ ){
+ int anIndx = j*aDim;
+ aPath.lineTo(aSects[i].myCoords[anIndx], aSects[i].myCoords[anIndx+1]);
+ }
+ if( aSects[i].myIsClosed ){
+ aPath.closeSubpath();
+ }
}
- aPath.lineTo( aPointsArray[0] );
-//I dont know is it need or not ???
- aPath.closeSubpath();
return aPath;
}
#include <HYDROData_Object.h>
+#include <TCollection_ExtendedString.hxx>
+
#include <QPointF>
#include <QPainterPath>
#include <QList>
DEFINE_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
+struct PolylineSection{
+public:
+ enum SectionType{ SECTION_POLYLINE=0, SECTION_SPLINE=1 };
+
+ PolylineSection(){ myIsClosed=true; myType=SECTION_POLYLINE; mySectionName="Section";}
+ TCollection_ExtendedString mySectionName;
+ SectionType myType;
+ bool myIsClosed;
+ QList<double> myCoords;
+};
+
/**\class HYDROData_Polyline
* \brief Class that stores/retreives information about the painter path.
*
HYDRODATA_EXPORT virtual const ObjectKind GetKind() const {return KIND_POLYLINE;}
/**
- * Replace current array by points list
- * \param thePoint the point to add
+ * Replace current polyline data by new sections list
+ * \param theSections the sections list
*/
- HYDRODATA_EXPORT void setPoints( QList<QPointF> thePointsList );
+ HYDRODATA_EXPORT void setPolylineData( const QList<PolylineSection>& theSections );
/**
- * Add point to the end of point list
- * \param thePoint the point to add
+ * Return polyline data
+ * \return polyline section list
*/
- HYDRODATA_EXPORT void addPoint( const QPointF& thePoint );
+ HYDRODATA_EXPORT QList<PolylineSection> getPolylineData();
/**
- * Add point to the point list at the specified position
- * \param theIndex the index of the list the point will insert after
- */
- HYDRODATA_EXPORT void insertPoint( int theIndex, const QPointF& thePoint);
-
- /**
- * Remove point from polyline
- * \param theIndex the point index
- */
- HYDRODATA_EXPORT void removePoint( int theIndex );
-
- /**
- * Remove all points from polyline
- * \param theIndex the point index
+ * Return polyline dimension
+ * \return polyline dimension (2 or 3)
*/
- HYDRODATA_EXPORT void removeAllPoints();
+ HYDRODATA_EXPORT int getDimension() const;
/**
- * Return list point count
- * \return list point count
+ * Set polyline dimension (2 or 3)
+ * \param theDimension the polyline dimension
*/
- HYDRODATA_EXPORT int pointsCount();
+ HYDRODATA_EXPORT void setDimension( int theDimension );
/**
- * Returns list of points
- * \return list of points
+ * Remove all sections from polyline
*/
- HYDRODATA_EXPORT QList<QPointF> points();
+ HYDRODATA_EXPORT void removeAll();
/**
* Returns the painter path. The painter path is construct by lines
*/
- HYDRODATA_EXPORT QPainterPath painterPathLinear();
+ HYDRODATA_EXPORT QPainterPath painterPath();
protected:
* Destructs properties of the object and object itself, removes it from the document.
*/
~HYDROData_Polyline();
-
};
#endif
Handle(HYDROData_Polyline) aPolyline =
Handle(HYDROData_Polyline)::DownCast(aDoc->CreateObject(KIND_POLYLINE));
// empty image
- QList<QPointF> aPoints = aPolyline->points();
- CPPUNIT_ASSERT(aPoints.size() == 0 );
- for( int i = 0 ; i < 10 ; i++ ){
- double anX = ((double)i)*0.1;
- double anY = ((double)(i-5))*10.;
- QPointF aPoint(anX,anY);
- aPoints.append(aPoint);
- }
+ int aDim = aPolyline->getDimension();
+ CPPUNIT_ASSERT(aDim == 0 );
- aPolyline->setPoints( aPoints );
-
- QList<QPointF> aRes = aPolyline->points();
+ aPolyline->setDimension(2);
+ aDim = aPolyline->getDimension();
+ CPPUNIT_ASSERT( aDim == 2 );
+
+ aPolyline->setDimension(3);
+ aDim = aPolyline->getDimension();
+ CPPUNIT_ASSERT( aDim == 3 );
+
+ PolylineSection aSect1;
+ aSect1.mySectionName = "Section_1";
+ aSect1.myType = PolylineSection::SECTION_POLYLINE;
+ aSect1.myIsClosed = false;
+
+ QList<PolylineSection> aSections;
+ aSections << aSect1;
- CPPUNIT_ASSERT( aRes.size() == 10 );
+ PolylineSection aSect2;
+ aSect1.mySectionName = "Section_2";
+ aSect1.myType = PolylineSection::SECTION_SPLINE;
+ aSect1.myIsClosed = true;
+ aSections << aSect2;
+
+ aPolyline->setPolylineData( aSections );
+ QList<PolylineSection> aRestoredSect = aPolyline->getPolylineData();
+ int aRestSize = aRestoredSect.size();
+ CPPUNIT_ASSERT( aRestSize == 2 );
- for( int i = 0 ; i < 10 ; i++ ){
- double anX = aRes[i].x();
- double anY = aRes[i].y();
- double aRefX = ((double)i)*0.1;
- double aRefY = ((double)(i-5))*10.;
- CPPUNIT_ASSERT( anX == aRefX );
- CPPUNIT_ASSERT( anY == aRefY );
-
- }
+// printf("Sect1.Name=%s RestName=%s\n", aSect1.mySectionName, aRestoredSect[0].mySectionName );
+ CPPUNIT_ASSERT( aRestoredSect[0].myType == PolylineSection::SECTION_POLYLINE );
+ CPPUNIT_ASSERT( aRestoredSect[0].myIsClosed == false );
+ CPPUNIT_ASSERT( aRestoredSect[0].mySectionName.IsLess( aSect1.mySectionName ) == false );
+ CPPUNIT_ASSERT( aRestoredSect[0].mySectionName.IsGreater( aSect1.mySectionName ) == false );
+ CPPUNIT_ASSERT( aRestoredSect[0].myCoords.size() == 0 );
+
+ CPPUNIT_ASSERT( aRestoredSect[1].myType == PolylineSection::SECTION_SPLINE );
+ CPPUNIT_ASSERT( aRestoredSect[1].myIsClosed == true );
+ CPPUNIT_ASSERT( aRestoredSect[1].mySectionName.IsLess( aSect2.mySectionName ) == false );
+ CPPUNIT_ASSERT( aRestoredSect[1].mySectionName.IsGreater( aSect2.mySectionName ) == false );
+ CPPUNIT_ASSERT( aRestoredSect[1].myCoords.size() == 0 );
+
aDoc->Close();
}
Handle(HYDROData_Polyline) aPolyline1 =
Handle(HYDROData_Polyline)::DownCast(aDoc->CreateObject(KIND_POLYLINE));
- QList<QPointF> aPoints;
- for( int i = 0 ; i < 10 ; i++ ){
- double anX = ((double)i)*0.1;
- double anY = ((double)(i-5))*10.;
- QPointF aPoint(anX,anY);
- aPoints.append(aPoint);
- }
- aPolyline1->setPoints(aPoints);
+// aPolyline1->setPoints(aPoints);
Handle(HYDROData_Polyline) aPolyline2 =
Handle(HYDROData_Polyline)::DownCast(aDoc->CreateObject(KIND_POLYLINE));
aPolyline1->CopyTo(aPolyline2);
- QList<QPointF> aRes = aPolyline2->points();
-
- CPPUNIT_ASSERT( aRes.size() == 10 );
-
- for( int i = 0 ; i < 10 ; i++ ){
- double anX = aRes[i].x();
- double anY = aRes[i].y();
- double aRefX = ((double)i)*0.1;
- double aRefY = ((double)(i-5))*10.;
- CPPUNIT_ASSERT( anX == aRefX );
- CPPUNIT_ASSERT( anY == aRefY );
-
- }
aDoc->Close();
}