#include <HYDROData_Polyline.h>
#include <HYDROData_Iterator.h>
+#include <HYDROData_BSplineOperation.h>
+
+#include <ImageComposer_MetaTypes.h>
+
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <gp_Pnt.hxx>
#include <TDataStd_Name.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_ByteArray.hxx>
#include <TDataStd_BooleanArray.hxx>
#include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_Real.hxx>
#include <TDataStd_RealArray.hxx>
#include <TDataStd_ExtStringArray.hxx>
#include <TDataStd_UAttribute.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+#include <BRep_Builder.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <QPainterPath>
+#include <QStringList>
-// 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
+#define PYTHON_POLYLINE_ID "KIND_POLYLINE"
IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
HYDROData_Polyline::HYDROData_Polyline()
+: HYDROData_Object()
{
}
{
}
-/**
- * Return polyline dimension
- * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
- */
-int HYDROData_Polyline::getDimension() const
+TopoDS_Shape HYDROData_Polyline::GetTopShape() const
{
- Handle(TDataStd_Integer) aDim;
- if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
- return 0;
- return aDim->Get();
+ // TODO
+ return getTopShape();
+}
+
+TopoDS_Shape HYDROData_Polyline::GetShape3D() const
+{
+ // TODO
+ return getTopShape();
}
/**
- * Set polyline dimension. Should be 2 or 3.
- * \param theDimension the polyline dimension
+ * Dump object to Python script representation.
*/
-void HYDROData_Polyline::setDimension( int theDimension )
+QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
{
- removeAll();
- int aDim=0;
- if( theDimension == 2 || theDimension == 3){
- aDim = theDimension;
+ QStringList aResList;
+
+ Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+ if ( aDocument.IsNull() )
+ return aResList;
+
+ QString aDocName = aDocument->GetDocPyName();
+ QString aPolylineName = GetName();
+
+ aResList << QString( "%1 = %2.CreateObject( %3 );" )
+ .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
+ aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
+
+ // Set polilyne dimension
+
+ aResList << QString( "" );
+
+ int aDim = GetDimension();
+ aResList << QString( "%1.SetDimension( %2 );" )
+ .arg( aPolylineName ).arg( aDim );
+
+ // Set polilyne data
+
+ PolylineData aPolylineData = GetPolylineData();
+ if ( !aPolylineData.isEmpty() )
+ {
+ QString aPolylineDataName = "polyline_data";
+
+ aResList << QString( "" );
+ aResList << QString( "%1 = [];" ).arg( aPolylineDataName );
+
+ PolylineData::const_iterator aDataIt = aPolylineData.constBegin();
+ for ( ; aDataIt != aPolylineData.constEnd(); ++aDataIt )
+ {
+ const PolylineSection& aSection = *aDataIt;
+
+ QString aPolylineSectName = "polyline_section";
+
+ aResList << QString( "" );
+ aResList << QString( "%1 = PolylineSection();" ).arg( aPolylineSectName );
+
+ QString aCoordsStr;
+ foreach( const double& aCoordVal, aSection.myCoords )
+ aCoordsStr += QString::number( aCoordVal ) + ", ";
+ aCoordsStr.remove( aCoordsStr.length() - 2, 2 );
+
+ aResList << QString( "" );
+
+ aResList << QString( "%1.mySectionName = \"%2\";" )
+ .arg( aPolylineSectName )
+ .arg( TCollection_AsciiString( aSection.mySectionName ).ToCString() );
+ aResList << QString( "%1.myType = %2;" )
+ .arg( aPolylineSectName ).arg( aSection.myType );
+ aResList << QString( "%1.myIsClosed = %2;" )
+ .arg( aPolylineSectName ).arg( aSection.myIsClosed );
+ aResList << QString( "%1.myCoords = [ %2 ];" )
+ .arg( aPolylineSectName ).arg( aCoordsStr );
+
+ aResList << QString( "%1.append( %2 );" )
+ .arg( aPolylineDataName ).arg( aPolylineSectName );
}
- TDataStd_Integer::Set(myLab, aDim);
+ aResList << QString( "" );
+
+ aResList << QString( "%1.SetPolylineData( %2 );" )
+ .arg( aPolylineName ).arg( aPolylineDataName );
+ }
+
+ return aResList;
+}
+
+QVariant HYDROData_Polyline::GetDataVariant()
+{
+ QPainterPath aPath = GetPainterPath();
+
+ QVariant aVarData;
+ aVarData.setValue<QPainterPath>( aPath );
+
+ return aVarData;
}
/**
* Replace current polyline data by new sections list
* \param theSections the sections list
*/
-void HYDROData_Polyline::setPolylineData( const QList<PolylineSection>& theSections )
+void HYDROData_Polyline::SetPolylineData( const PolylineData& theSections )
{
//Keep dimension
- int aDim = getDimension();
+ int aDim = GetDimension();
if( aDim == 0 )
return;
- removeAll();
- setDimension(aDim);
+ RemoveAll();
+ SetDimension(aDim);
if( theSections.size() == 0 )
return;
int aPointsCnt = 0;
- TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
+ TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
Handle(TDataStd_ExtStringArray) aSectsNameArray;
aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
- TDF_Label aSizeLab = myLab.FindChild(TAG_SECTIONS_SIZE);
+ TDF_Label aSizeLab = myLab.FindChild(DataTag_SectionsSize);
Handle(TDataStd_IntegerArray) aSizeArray;
aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
- TDF_Label aClosedLab = myLab.FindChild(TAG_SECTIONS_CLOSED);
+ TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed);
Handle(TDataStd_BooleanArray) aClosedArray;
aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
- TDF_Label aTypeLab = myLab.FindChild(TAG_SECTIONS_TYPE);
+ TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType);
Handle(TDataStd_ByteArray) aTypeArray;
aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
aPtr++;
}
}
+
+ UpdateWire( theSections );
}
/**
* Return polyline data
* \return polyline section list
*/
-QList<PolylineSection> HYDROData_Polyline::getPolylineData()
+HYDROData_Polyline::PolylineData HYDROData_Polyline::GetPolylineData() const
{
int aSectCnt;
- QList<PolylineSection> aRes;
+ PolylineData aRes;
//Get sections size array handle
- TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
+ TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
Handle(TDataStd_IntegerArray) aSizeArray;
if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
return aRes; // return empty if no array
if( aSectCnt == 0 )
return aRes;
//Get section type array handle
- aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
+ aLab = myLab.FindChild( DataTag_SectionsType );
Handle(TDataStd_ByteArray) aTypeArray;
if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
return aRes;
if( aLen != aSectCnt )
return aRes;
//Get section closed array handle
- aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
+ aLab = myLab.FindChild( DataTag_SectionsClosed );
Handle(TDataStd_BooleanArray) aClosedArray;
if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
return aRes;
if( aLen != aSectCnt )
return aRes;
//Get sections names
- TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
+ TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
Handle(TDataStd_ExtStringArray) aSectNamesArray;
if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
return aRes;
return aRes;
}
+/**
+ * Returns true if polyline is closed
+ */
+bool HYDROData_Polyline::IsClosed() const
+{
+ int aDim = GetDimension();
+ PolylineData aPolylineData = GetPolylineData();
+
+ if ( aDim == 0 || aPolylineData.isEmpty() )
+ return false;
+
+ PolylineData::const_iterator anIt = aPolylineData.constBegin();
+ for ( ; anIt != aPolylineData.constEnd(); ++anIt )
+ {
+ const PolylineSection& aSection = *anIt;
+ if ( !aSection.myIsClosed )
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Return polyline dimension
+ * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
+ */
+int HYDROData_Polyline::GetDimension() const
+{
+ Handle(TDataStd_Integer) aDim;
+ if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
+ return 0;
+ return aDim->Get();
+}
+
+/**
+ * Set polyline dimension. Should be 2 or 3.
+ * \param theDimension the polyline dimension
+ */
+void HYDROData_Polyline::SetDimension( int theDimension )
+{
+ RemoveAll();
+ int aDim=0;
+ if( theDimension == 2 || theDimension == 3){
+ aDim = theDimension;
+ }
+ TDataStd_Integer::Set(myLab, aDim);
+}
+
/**
* Remove all polyline attributes except dimension.
*/
-void HYDROData_Polyline::removeAll()
+void HYDROData_Polyline::RemoveAll()
{
//Remove only section data
- TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
+ TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
aLab.ForgetAllAttributes();
- aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
+ aLab = myLab.FindChild( DataTag_SectionsType );
aLab.ForgetAllAttributes();
- aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
+ aLab = myLab.FindChild( DataTag_SectionsClosed );
aLab.ForgetAllAttributes();
myLab.ForgetAttribute(TDataStd_RealArray::GetID());
}
/**
- * Return polyline painter path. Current implementation
- * is ignored section type.
+ * Returns the painter path.
+ * Note: currently only the first section of the polyline data is taken into account.
* \return polyline painter path.
*/
-QPainterPath HYDROData_Polyline::painterPath()
+QPainterPath HYDROData_Polyline::GetPainterPath() const
{
QPainterPath aPath;
- 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]);
+ int aDim = GetDimension();
+ if( aDim != 2 && aDim != 3 )
+ return aPath;
+
+ PolylineData aSects = GetPolylineData();
+ if( aSects.isEmpty() )
+ return aPath;
+
+ PolylineSection aSection = aSects.first();
+ int aPntCount = aSection.myCoords.size() / aDim;
+ PolylineSection::SectionType aSectionType = aSection.myType;
+ bool anIsSectionClosed = aSection.myIsClosed;
+ if( aSectionType == PolylineSection::SECTION_POLYLINE )
+ {
+ if( aPntCount )
+ aPath.moveTo( aSection.myCoords[0], aSection.myCoords[1] );
+ for( int i = 1; i < aPntCount; i++ )
+ {
+ int anIndex = i * aDim;
+ aPath.lineTo( aSection.myCoords[ anIndex ], aSection.myCoords[ anIndex + 1 ] );
}
- if( aSects[i].myIsClosed ){
+ if( anIsSectionClosed )
aPath.closeSubpath();
+ }
+ else //if( aSectionType == PolylineSection::SECTION_SPLINE )
+ {
+ QList<double> aPoints;
+ for( int i = 0; i < aPntCount; i++ )
+ {
+ int anIndex = i * aDim;
+ aPoints << aSection.myCoords[ anIndex ] << aSection.myCoords[ anIndex + 1 ];
}
+ HYDROData_BSplineOperation aBSpline( aPoints, 0, anIsSectionClosed );
+ aPath = aBSpline.ComputePath();
}
return aPath;
}
+
+void HYDROData_Polyline::SetZValue( const double theZValue )
+{
+ TDataStd_Real::Set(myLab.FindChild(DataTag_ZValue), theZValue);
+}
+
+double HYDROData_Polyline::ZValue() const
+{
+ Handle(TDataStd_Real) aZValue;
+ if(myLab.FindChild(DataTag_ZValue).FindAttribute(TDataStd_Real::GetID(), aZValue))
+ return aZValue->Get();
+ return 0;
+}
+
+void HYDROData_Polyline::UpdateWire( const PolylineData& theSections )
+{
+ BRepBuilderAPI_MakeWire aMakeWire;
+
+ int aDim = GetDimension();
+
+ double aZValue = ZValue();
+
+ TopTools_ListOfShape aSectionWiresList;
+
+ int aSectionCount = theSections.size();
+ for( int aSectionId = 0; aSectionId < aSectionCount; aSectionId++ )
+ {
+ const PolylineSection& aSection = theSections[ aSectionId ];
+ PolylineSection::SectionType aSectionType = aSection.myType;
+ bool anIsSectionClosed = aSection.myIsClosed;
+ int aPointCount = aSection.myCoords.size() / aDim;
+ if( aPointCount > 1 )
+ {
+ BRepBuilderAPI_MakeWire aMakeSectionWire;
+ if( aSectionType == PolylineSection::SECTION_POLYLINE )
+ {
+ for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
+ {
+ int anId1 = aDim * aPointId;
+ int anId2 = aDim * ( aPointId + 1 );
+ if( aPointId == aPointCount - 1 )
+ {
+ if( anIsSectionClosed )
+ anId2 = 0;
+ else
+ break;
+ }
+
+ gp_Pnt aPnt1( aSection.myCoords[ anId1 ], aSection.myCoords[ anId1 + 1 ], aZValue );
+ gp_Pnt aPnt2( aSection.myCoords[ anId2 ], aSection.myCoords[ anId2 + 1 ], aZValue );
+
+ TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
+ aMakeSectionWire.Add( anEdge );
+ }
+ }
+ else //if( aSectionType == PolylineSection::SECTION_SPLINE )
+ {
+ QList<double> aPoints;
+ for( int aPointId = 0; aPointId < aPointCount; aPointId++ )
+ {
+ int anId = aPointId * aDim;
+ double x = aSection.myCoords[ anId ];
+ double y = aSection.myCoords[ anId+1 ];
+ aPoints << x << y;
+ }
+
+ HYDROData_BSplineOperation aBSpline( aPoints, aZValue, anIsSectionClosed );
+ TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSpline.Curve() ).Edge();
+ aMakeSectionWire.Add( anEdge );
+ }
+ TopoDS_Wire aSectionWire = aMakeSectionWire.Wire();
+ aSectionWiresList.Append( aSectionWire );
+ aMakeWire.Add( aSectionWire );
+ }
+ }
+
+ TopoDS_Shape aShape;
+ if ( aMakeWire.IsDone() ) {
+ aShape = aMakeWire.Shape();
+ } else {
+ // build compound
+ TopoDS_Compound aCompound;
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound( aCompound );
+ TopTools_ListIteratorOfListOfShape anIter( aSectionWiresList );
+ for ( ; anIter.More(); anIter.Next() ) {
+ aBuilder.Add( aCompound, anIter.Value() );
+ }
+ aShape = aCompound;
+ }
+
+ SetTopShape( aShape );
+}