X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Polyline.cxx;h=80bd0f4b2a7e1ad27850d141f0b3c50b78adb513;hb=f7c005b67e48ec7bac99c566fb4f34215ec1a4b1;hp=a0ec4f2dabe4d613352fa4eeaa60a4626b3c7437;hpb=b58558f56e97ff01757710155cd9a8429b34ae46;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Polyline.cxx b/src/HYDROData/HYDROData_Polyline.cxx index a0ec4f2d..80bd0f4b 100755 --- a/src/HYDROData/HYDROData_Polyline.cxx +++ b/src/HYDROData/HYDROData_Polyline.cxx @@ -1,18 +1,62 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + #include #include -#include +#include + +#include + +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include + +#include -// tage of the child of my label that contains information about the operator -static const Standard_GUID GUID_MUST_BE_UPDATED("80f2bb81-3873-4631-8ddd-940d2119f000"); +#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() { } @@ -20,82 +64,428 @@ HYDROData_Polyline::~HYDROData_Polyline() { } -void HYDROData_Polyline::setPoints( QList thePointsList ) +TopoDS_Shape HYDROData_Polyline::GetTopShape() 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() ); - } + // TODO + return getTopShape(); } -void HYDROData_Polyline::addPoint( const QPointF& thePoint ) -{ - QList aPointsArray = points(); - aPointsArray.append( thePoint ); - setPoints( aPointsArray ); -} - -bool HYDROData_Polyline::insertPoint( int theIndex, const QPointF& thePoint) +TopoDS_Shape HYDROData_Polyline::GetShape3D() const { - QList aPointsArray = points(); - aPointsArray.insert( theIndex, thePoint ); - setPoints( aPointsArray ); + // TODO + return getTopShape(); } -bool HYDROData_Polyline::removePoint( int theIndex ) +/** + * Dump object to Python script representation. + */ +QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const { - QList aPointsArray = points(); - aPointsArray.removeAt( theIndex ); - setPoints( aPointsArray ); + 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 ); + } + aResList << QString( "" ); + + aResList << QString( "%1.SetPolylineData( %2 );" ) + .arg( aPolylineName ).arg( aPolylineDataName ); + } + + return aResList; } -void HYDROData_Polyline::removeAllPoints() +QVariant HYDROData_Polyline::GetDataVariant() { - myLab.ForgetAttribute(TDataStd_RealArray::GetID()); - return; + QPainterPath aPath = GetPainterPath(); + + QVariant aVarData; + aVarData.setValue( aPath ); + + return aVarData; } -int HYDROData_Polyline::pointsCount() +/** + * Replace current polyline data by new sections list + * \param theSections the sections list + */ +void HYDROData_Polyline::SetPolylineData( const PolylineData& theSections ) { +//Keep dimension + int aDim = GetDimension(); + if( aDim == 0 ) + return; + RemoveAll(); + SetDimension(aDim); + + if( theSections.size() == 0 ) + return; + int aSectionsSize = theSections.size(); + + int aPointsCnt = 0; + + 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(DataTag_SectionsSize); + Handle(TDataStd_IntegerArray) aSizeArray; + aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false ); + + TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed); + Handle(TDataStd_BooleanArray) aClosedArray; + aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 ); + + TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType); + 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++; + } + } + + UpdateWire( theSections ); } -QList HYDROData_Polyline::points() +/** + * Return polyline data + * \return polyline section list + */ +HYDROData_Polyline::PolylineData HYDROData_Polyline::GetPolylineData() const { - QList aRes; - Handle(TDataStd_RealArray) anArray; - if(!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray)) + int aSectCnt; + PolylineData aRes; +//Get sections size array handle + 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 + aSectCnt = aSizeArray->Length(); + if( aSectCnt == 0 ) + return aRes; +//Get section type array handle + aLab = myLab.FindChild( DataTag_SectionsType ); + 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( DataTag_SectionsClosed ); + Handle(TDataStd_BooleanArray) aClosedArray; + if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray)) + return aRes; + aLen = aClosedArray->Length(); + if( aLen != aSectCnt ) 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 ); +//Get sections names + TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName); + Handle(TDataStd_ExtStringArray) aSectNamesArray; + if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray)) + return aRes; + 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() +/** + * 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() +{ +//Remove only section data + TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize ); + aLab.ForgetAllAttributes(); + + aLab = myLab.FindChild( DataTag_SectionsType ); + aLab.ForgetAllAttributes(); + + aLab = myLab.FindChild( DataTag_SectionsClosed ); + aLab.ForgetAllAttributes(); + + myLab.ForgetAttribute(TDataStd_RealArray::GetID()); + return; +} + +/** + * 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::GetPainterPath() const { QPainterPath aPath; - QList aPointsArray = points(); - if( aPointsArray.size() == 0 ) + int aDim = GetDimension(); + if( aDim != 2 && aDim != 3 ) return aPath; - aPath.moveTo( aPointsArray[0] ); - for( int i = 0 ; i < aPointsArray.size() ; i++ ){ - aPath.lineTo( aPointsArray[i] ); + + 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( anIsSectionClosed ) + aPath.closeSubpath(); + } + else //if( aSectionType == PolylineSection::SECTION_SPLINE ) + { + QList 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(); } - aPath.lineTo( aPointsArray[0] ); -//I dont know is it need or not ??? - aPath.closeSubpath(); 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 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 ); +}