// Copyright (C) 2007-2014 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 // // File : GEOMGUI_DimensionProperty.cxx // Author : Anton POLETAEV, Open CASCADE S.A.S. // #include "GEOMGUI_DimensionProperty.h" // OCCT includes #include #include #include // Static patterns for casting value-to-string & value-from-string. The patterns are: // ITEM: { name[string] : visibility : type : values[composite] }; // PLANE: a[float] : b[float] : c[float] : d[float] // PROPS: flyout[float] : text h pos[int] : text v pos[int] : arrow pos[int] // XYZ: x [float] : y[float] : z[float] // FLOAT: value [float] namespace { static const QString PATTERN_ITEM_GROUP = "\\{ (Name=(?::{2,}|.)*:(?!:)Visible=.*:Type=.*:.*) \\}"; static const QString PATTERN_ITEM = "Name=((?::{2,}|.)*):(?!:)Visible=(\\d{1}):Type=(\\d{1}):(.*)"; static const QString PATTERN_PLANE = "Plane=\\{(.*):(.*):(.*):(.*)\\}"; static const QString PATTERN_PROPS = "Flyout=(.*):TextH=(.*):TextV=(.*):Arrow=(.*)"; static const QString PATTERN_XYZ = "%1=\\{(.*):(.*):(.*)\\}"; static const QString PATTERN_FLOAT = "%1=(.*)"; static const QString PATTERN_LENGTH = PATTERN_PLANE + ":" + PATTERN_PROPS + ":" + PATTERN_XYZ.arg( "Point1" ) + ":" + PATTERN_XYZ.arg( "Point2" ); static const QString PATTERN_DIAMETER = PATTERN_PLANE + ":" + PATTERN_PROPS + ":" + PATTERN_XYZ.arg( "Position" ) + ":" + PATTERN_XYZ.arg( "NDir" ) + ":" + PATTERN_XYZ.arg( "XDir" ) + ":" + PATTERN_FLOAT.arg( "Radius" ); static const QString PATTERN_ANGLE = PATTERN_PROPS + ":" + PATTERN_XYZ.arg( "Point1" ) + ":" + PATTERN_XYZ.arg( "Point2" ) + ":" + PATTERN_XYZ.arg( "Point3" ); }; //================================================================================= // function : Length::Init // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Length::Init( const Handle(AIS_LengthDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aFromLCS; aFromLCS.SetTransformation( gp_Ax3(), theLCS ); FirstPoint = theIO->FirstPoint().Transformed( aFromLCS ); SecondPoint = theIO->SecondPoint().Transformed( aFromLCS ); Plane = theIO->GetPlane().Transformed( aFromLCS ); Flyout = theIO->GetFlyout(); TextHPos = theIO->DimensionAspect()->TextHorizontalPosition(); TextVPos = theIO->DimensionAspect()->TextVerticalPosition(); ArrowPos = theIO->DimensionAspect()->ArrowOrientation(); } //================================================================================= // function : Length::Update // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Length::Update( Handle(AIS_LengthDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aToLCS; aToLCS.SetTransformation( theLCS, gp_Ax3() ); gp_Pnt aPoint1 = FirstPoint.Transformed( aToLCS ); gp_Pnt aPoint2 = SecondPoint.Transformed( aToLCS ); gp_Pln aPlane = Plane.Transformed( aToLCS ); theIO->SetMeasuredGeometry( aPoint1, aPoint2, aPlane ); theIO->SetFlyout( Flyout ); Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect(); aStyle->SetTextHorizontalPosition( TextHPos ); aStyle->SetTextVerticalPosition( TextVPos ); aStyle->SetArrowOrientation( ArrowPos ); theIO->SetDimensionAspect( aStyle ); } //================================================================================= // function : Length::ToValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Length::ToValues(std::vector& theValues) const { // custom plane [2,3,4,5] Standard_Real A, B, C, D; Plane.Coefficients( A, B, C, D ); theValues.push_back( (double) A ); theValues.push_back( (double) B ); theValues.push_back( (double) C ); theValues.push_back( (double) D ); // flyout size [6] theValues.push_back( (double) Flyout ); // text flags [7,8] theValues.push_back( (double) TextHPos ); theValues.push_back( (double) TextVPos ); // arrow flags [9] theValues.push_back( (double) ArrowPos ); // point 1 [10,11,12] theValues.push_back( (double) FirstPoint.X() ); theValues.push_back( (double) FirstPoint.Y() ); theValues.push_back( (double) FirstPoint.Z() ); // point 2 [13,14,15] theValues.push_back( (double) SecondPoint.X() ); theValues.push_back( (double) SecondPoint.Y() ); theValues.push_back( (double) SecondPoint.Z() ); } //================================================================================= // function : Length::FromValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Length::FromValues(int& theIt, const std::vector& theValues) { // custom plane [2,3,4,5] Standard_Real A = (Standard_Real) theValues[theIt++]; Standard_Real B = (Standard_Real) theValues[theIt++]; Standard_Real C = (Standard_Real) theValues[theIt++]; Standard_Real D = (Standard_Real) theValues[theIt++]; Plane = gp_Pln( A, B, C, D ); // flyout size [6] Flyout = (Standard_Real) theValues[theIt++]; // text flags [7,8] TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)theValues[theIt++]; TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)theValues[theIt++]; // arrow flags [9] ArrowPos = (Prs3d_DimensionArrowOrientation) (int)theValues[theIt++]; // point 1 [10,11,12] Standard_Real aFirstX = theValues[theIt++]; Standard_Real aFirstY = theValues[theIt++]; Standard_Real aFirstZ = theValues[theIt++]; FirstPoint = gp_Pnt( aFirstX, aFirstY, aFirstZ ); // point 2 [13,14,15] Standard_Real aSecondX = theValues[theIt++]; Standard_Real aSecondY = theValues[theIt++]; Standard_Real aSecondZ = theValues[theIt++]; SecondPoint = gp_Pnt( aSecondX, aSecondY, aSecondZ ); } //================================================================================= // function : Length::operator == // purpose : //================================================================================= bool GEOMGUI_DimensionProperty::Length::operator == (const Length& theOther) const { if ( FirstPoint.X() != theOther.FirstPoint.X() || FirstPoint.Y() != theOther.FirstPoint.Y() || FirstPoint.Z() != theOther.FirstPoint.Z() || SecondPoint.X() != theOther.SecondPoint.X() || SecondPoint.Y() != theOther.SecondPoint.Y() || SecondPoint.Z() != theOther.SecondPoint.Z() ) { return false; } if ( Plane.Location().X() != theOther.Plane.Location().X() || Plane.Location().Y() != theOther.Plane.Location().Y() || Plane.Location().Z() != theOther.Plane.Location().Z() || Plane.Axis().Direction().X() != theOther.Plane.Axis().Direction().X() || Plane.Axis().Direction().Y() != theOther.Plane.Axis().Direction().Y() || Plane.Axis().Direction().Z() != theOther.Plane.Axis().Direction().Z() ) { return false; } if ( Flyout != theOther.Flyout || TextHPos != theOther.TextHPos || TextVPos != theOther.TextVPos || ArrowPos != theOther.ArrowPos ) { return false; } return true; } //================================================================================= // function : Diameter::Init // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Diameter::Init( const Handle(AIS_DiameterDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aFromLCS; aFromLCS.SetTransformation( gp_Ax3(), theLCS ); Circle = theIO->Circle().Transformed( aFromLCS ); Plane = theIO->GetPlane().Transformed( aFromLCS ); Flyout = theIO->GetFlyout(); TextHPos = theIO->DimensionAspect()->TextHorizontalPosition(); TextVPos = theIO->DimensionAspect()->TextVerticalPosition(); ArrowPos = theIO->DimensionAspect()->ArrowOrientation(); } //================================================================================= // function : Diameter::Update // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Diameter::Update( Handle(AIS_DiameterDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aToLCS; aToLCS.SetTransformation( theLCS, gp_Ax3() ); gp_Circ aCircle = Circle.Transformed( aToLCS ); gp_Pln aPlane = Plane.Transformed( aToLCS ); Standard_Boolean isParallel = aCircle.Axis().Direction().IsParallel( aPlane.Axis().Direction(), Precision::Angular() ); if ( isParallel ) { theIO->UnsetCustomPlane(); theIO->SetMeasuredGeometry( aCircle ); } else { theIO->SetCustomPlane( aPlane ); theIO->SetMeasuredGeometry( aCircle ); } theIO->SetFlyout( Flyout ); Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect(); aStyle->SetTextHorizontalPosition( TextHPos ); aStyle->SetTextVerticalPosition( TextVPos ); aStyle->SetArrowOrientation( ArrowPos ); theIO->SetDimensionAspect( aStyle ); } //================================================================================= // function : Diameter::ToValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Diameter::ToValues(std::vector& theValues) const { // custom plane [2,3,4,5] Standard_Real A, B, C, D; Plane.Coefficients( A, B, C, D ); theValues.push_back( (double) A ); theValues.push_back( (double) B ); theValues.push_back( (double) C ); theValues.push_back( (double) D ); // flyout size [6] theValues.push_back( (double) Flyout ); // text flags [7,8] theValues.push_back( (double) TextHPos ); theValues.push_back( (double) TextVPos ); // arrow flags [9] theValues.push_back( (double) ArrowPos ); // circle location [10,11,12] theValues.push_back( (double) Circle.Location().X() ); theValues.push_back( (double) Circle.Location().Y() ); theValues.push_back( (double) Circle.Location().Z() ); // circle normal [13,14,15] theValues.push_back( (double) Circle.Axis().Direction().X() ); theValues.push_back( (double) Circle.Axis().Direction().Y() ); theValues.push_back( (double) Circle.Axis().Direction().Z() ); // x-direction [16,17,18] theValues.push_back( (double) Circle.XAxis().Direction().X() ); theValues.push_back( (double) Circle.XAxis().Direction().Y() ); theValues.push_back( (double) Circle.XAxis().Direction().Z() ); // radius [19] theValues.push_back( (double) Circle.Radius() ); } //================================================================================= // function : Diameter::FromValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Diameter::FromValues(int& theIt, const std::vector& theValues) { // custom plane [2,3,4,5] Standard_Real A = (Standard_Real) theValues[theIt++]; Standard_Real B = (Standard_Real) theValues[theIt++]; Standard_Real C = (Standard_Real) theValues[theIt++]; Standard_Real D = (Standard_Real) theValues[theIt++]; Plane = gp_Pln( A, B, C, D ); // flyout size [6] Flyout = (Standard_Real) theValues[theIt++]; // text flags [7,8] TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)theValues[theIt++]; TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)theValues[theIt++]; // arrow flags [9] ArrowPos = (Prs3d_DimensionArrowOrientation) (int)theValues[theIt++]; // circle location [10,11,12] Standard_Real aLocX = (Standard_Real) theValues[theIt++]; Standard_Real aLocY = (Standard_Real) theValues[theIt++]; Standard_Real aLocZ = (Standard_Real) theValues[theIt++]; // circle normal [13,14,15] Standard_Real aNormX = (Standard_Real) theValues[theIt++]; Standard_Real aNormY = (Standard_Real) theValues[theIt++]; Standard_Real aNormZ = (Standard_Real) theValues[theIt++]; // x-direction [16,17,18] Standard_Real aXDirX = (Standard_Real) theValues[theIt++]; Standard_Real aXDirY = (Standard_Real) theValues[theIt++]; Standard_Real aXDirZ = (Standard_Real) theValues[theIt++]; // radius [19] Standard_Real aRadius = (Standard_Real) theValues[theIt++]; gp_Ax2 anAx( gp_Pnt( aLocX, aLocY, aLocZ ), gp_Dir( aNormX, aNormY, aNormZ ), gp_Dir( aXDirX, aXDirY, aXDirZ ) ); Circle = gp_Circ( anAx, aRadius ); } //================================================================================= // function : Diameter::operator == // purpose : //================================================================================= bool GEOMGUI_DimensionProperty::Diameter::operator == (const Diameter& theOther) const { if ( Circle.Location().X() != theOther.Circle.Location().X() || Circle.Location().Y() != theOther.Circle.Location().Y() || Circle.Location().Z() != theOther.Circle.Location().Z() || Circle.Axis().Direction().X() != theOther.Circle.Axis().Direction().X() || Circle.Axis().Direction().Y() != theOther.Circle.Axis().Direction().Y() || Circle.Axis().Direction().Z() != theOther.Circle.Axis().Direction().Z() || Circle.XAxis().Direction().X() != theOther.Circle.XAxis().Direction().X() || Circle.XAxis().Direction().Y() != theOther.Circle.XAxis().Direction().Y() || Circle.XAxis().Direction().Z() != theOther.Circle.XAxis().Direction().Z() || Circle.Radius() != theOther.Circle.Radius() ) { return false; } if ( Plane.Location().X() != theOther.Plane.Location().X() || Plane.Location().Y() != theOther.Plane.Location().Y() || Plane.Location().Z() != theOther.Plane.Location().Z() || Plane.Axis().Direction().X() != theOther.Plane.Axis().Direction().X() || Plane.Axis().Direction().Y() != theOther.Plane.Axis().Direction().Y() || Plane.Axis().Direction().Z() != theOther.Plane.Axis().Direction().Z() ) { return false; } if ( Flyout != theOther.Flyout || TextHPos != theOther.TextHPos || TextVPos != theOther.TextVPos || ArrowPos != theOther.ArrowPos ) { return false; } return true; } //================================================================================= // function : Angle::Init // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Angle::Init( const Handle(AIS_AngleDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aFromLCS; aFromLCS.SetTransformation( gp_Ax3(), theLCS ); FirstPoint = theIO->FirstPoint().Transformed( aFromLCS ); SecondPoint = theIO->SecondPoint().Transformed( aFromLCS ); CenterPoint = theIO->CenterPoint().Transformed( aFromLCS ); Flyout = theIO->GetFlyout(); TextHPos = theIO->DimensionAspect()->TextHorizontalPosition(); TextVPos = theIO->DimensionAspect()->TextVerticalPosition(); ArrowPos = theIO->DimensionAspect()->ArrowOrientation(); } //================================================================================= // function : Angle::Update // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Angle::Update( Handle(AIS_AngleDimension)& theIO, const gp_Ax3& theLCS ) { gp_Trsf aToLCS; aToLCS.SetTransformation( theLCS, gp_Ax3() ); gp_Pnt aPoint1 = FirstPoint.Transformed( aToLCS ); gp_Pnt aPoint2 = CenterPoint.Transformed( aToLCS ); gp_Pnt aPoint3 = SecondPoint.Transformed( aToLCS ); theIO->SetMeasuredGeometry( aPoint1, aPoint2, aPoint3 ); theIO->SetFlyout( Flyout ); Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect(); aStyle->SetTextHorizontalPosition( TextHPos ); aStyle->SetTextVerticalPosition( TextVPos ); aStyle->SetArrowOrientation( ArrowPos ); theIO->SetDimensionAspect( aStyle ); } //================================================================================= // function : Angle::ToValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Angle::ToValues(std::vector& theValues) const { // flyout [2] theValues.push_back( (double) Flyout ); // text flags [3,4] theValues.push_back( (double) TextHPos ); theValues.push_back( (double) TextVPos ); // arrow flags [5] theValues.push_back( (double) ArrowPos ); // point 1 [6,7,8] theValues.push_back( (double) FirstPoint.X() ); theValues.push_back( (double) FirstPoint.Y() ); theValues.push_back( (double) FirstPoint.Z() ); // point 2 [9,10,11] theValues.push_back( (double) SecondPoint.X() ); theValues.push_back( (double) SecondPoint.Y() ); theValues.push_back( (double) SecondPoint.Z() ); // center [12,13,14] theValues.push_back( (double) CenterPoint.X() ); theValues.push_back( (double) CenterPoint.Y() ); theValues.push_back( (double) CenterPoint.Z() ); } //================================================================================= // function : Angle::FromValues // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Angle::FromValues(int& theIt, const std::vector& theValues) { // flyout [2] Flyout = (Standard_Real) theValues[theIt++]; // text flags [3,4] TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)theValues[theIt++]; TextVPos = (Prs3d_DimensionTextVerticalPosition) (int)theValues[theIt++]; // arrow flags [5] ArrowPos = (Prs3d_DimensionArrowOrientation) (int)theValues[theIt++]; // point 1 [6,7,8] Standard_Real aFirstX = (Standard_Real) theValues[theIt++]; Standard_Real aFirstY = (Standard_Real) theValues[theIt++]; Standard_Real aFirstZ = (Standard_Real) theValues[theIt++]; // point 2 [9,10,11] Standard_Real aSecondX = (Standard_Real) theValues[theIt++]; Standard_Real aSecondY = (Standard_Real) theValues[theIt++]; Standard_Real aSecondZ = (Standard_Real) theValues[theIt++]; // center [12,13,14] Standard_Real aCenterX = (Standard_Real) theValues[theIt++]; Standard_Real aCenterY = (Standard_Real) theValues[theIt++]; Standard_Real aCenterZ = (Standard_Real) theValues[theIt++]; FirstPoint = gp_Pnt( aFirstX, aFirstY, aFirstZ ); SecondPoint = gp_Pnt( aSecondX, aSecondY, aSecondZ ); CenterPoint = gp_Pnt( aCenterX, aCenterY, aCenterZ ); } //================================================================================= // function : Angle::operator == // purpose : //================================================================================= bool GEOMGUI_DimensionProperty::Angle::operator == (const Angle& theOther) const { if ( FirstPoint.X() != theOther.FirstPoint.X() || FirstPoint.Y() != theOther.FirstPoint.Y() || FirstPoint.Z() != theOther.FirstPoint.Z() || SecondPoint.X() != theOther.SecondPoint.X() || SecondPoint.Y() != theOther.SecondPoint.Y() || SecondPoint.Z() != theOther.SecondPoint.Z() || CenterPoint.X() != theOther.CenterPoint.X() || CenterPoint.Y() != theOther.CenterPoint.Y() || CenterPoint.Z() != theOther.CenterPoint.Z() ) { return false; } if ( Flyout != theOther.Flyout || TextHPos != theOther.TextHPos || TextVPos != theOther.TextVPos || ArrowPos != theOther.ArrowPos ) { return false; } return true; } //================================================================================= // function : Constructor // purpose : //================================================================================= GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty() { } //================================================================================= // function : Copy constructor // purpose : //================================================================================= GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( const GEOMGUI_DimensionProperty& theOther ) { const VectorOfVisibility& aOtherVis = theOther.myVisibility; const VectorOfNames& aOtherNames = theOther.myNames; const VectorOfRecords& aOtherRecords = theOther.myRecords; VectorOfVisibility::const_iterator aVisIt = aOtherVis.constBegin(); VectorOfNames::const_iterator aNamesIt = aOtherNames.constBegin(); VectorOfRecords::const_iterator aRecordIt = aOtherRecords.constBegin(); for ( ; aRecordIt != aOtherRecords.constEnd(); ++aVisIt, ++aNamesIt, ++aRecordIt ) { RecordPtr aNewRecord; const RecordPtr& aRecord = *aRecordIt; switch( aRecord->Type() ) { case DimensionType_Length : aNewRecord = RecordPtr( new Length( *aRecord->AsLength() ) ); break; case DimensionType_Diameter : aNewRecord = RecordPtr( new Diameter( *aRecord->AsDiameter() ) ); break; case DimensionType_Angle : aNewRecord = RecordPtr( new Angle( *aRecord->AsAngle() ) ); break; } myVisibility.append( *aVisIt ); myNames.append( *aNamesIt ); myRecords.append( aNewRecord ); } } //================================================================================= // function : Init constructor // purpose : //================================================================================= GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( SalomeApp_Study* theStudy, const std::string& theEntry ) { LoadFromAttribute( theStudy, theEntry ); } //================================================================================= // function : Init constructor // purpose : //================================================================================= GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( const QString& theProperty ) { QRegExp aRegExpItemGroups( PATTERN_ITEM_GROUP ); QRegExp aRegExpItem( "^" + PATTERN_ITEM + "$" ); aRegExpItemGroups.setMinimal( true ); aRegExpItem.setMinimal( true ); int aPos = 0; while ( ( aPos = aRegExpItemGroups.indexIn( theProperty, aPos ) ) != -1 ) { aPos += aRegExpItemGroups.matchedLength(); QString aStrItem = aRegExpItemGroups.cap(1); if ( aRegExpItem.indexIn( aStrItem ) < 0 ) { continue; } // extract name QString aStrName = aRegExpItem.cap( 1 ); QString aStrVisible = aRegExpItem.cap( 2 ); QString aStrType = aRegExpItem.cap( 3 ); QString aStrValues = aRegExpItem.cap( 4 ); // extract values aStrName.replace( "::", ":" ); bool isVisible = aStrVisible.toInt() != 0; int aType = aStrType.toInt(); RecordPtr aRecord; switch ( aType ) { case DimensionType_Length : aRecord = RecordPtr( new Length ); break; case DimensionType_Diameter : aRecord = RecordPtr( new Diameter ); break; case DimensionType_Angle : aRecord = RecordPtr( new Angle ); break; default: continue; } QRegExp aRegExpValues; switch ( aType ) { case DimensionType_Length : aRegExpValues = QRegExp( "^" + PATTERN_LENGTH + "$" ); break; case DimensionType_Diameter : aRegExpValues = QRegExp( "^" + PATTERN_DIAMETER + "$" ); break; case DimensionType_Angle : aRegExpValues = QRegExp( "^" + PATTERN_ANGLE + "$" ); break; } aRegExpValues.setMinimal(true); if ( aRegExpValues.indexIn( aStrValues ) < 0 ) { continue; } std::vector aValues; QStringList aStrListOfValues = aRegExpValues.capturedTexts(); QStringList::Iterator aStrListOfValuesIt = aStrListOfValues.begin(); ++aStrListOfValuesIt; // skip first capture for ( ; aStrListOfValuesIt != aStrListOfValues.end(); ++aStrListOfValuesIt ) { aValues.push_back( (*aStrListOfValuesIt).toDouble() ); } int aValueIt = 0; aRecord->FromValues( aValueIt, aValues ); myVisibility.append( isVisible ); myNames.append( aStrName ); myRecords.append( aRecord ); } } //================================================================================= // function : Destructor // purpose : //================================================================================= GEOMGUI_DimensionProperty::~GEOMGUI_DimensionProperty() { } //================================================================================= // function : operator QVariant() // purpose : //================================================================================= GEOMGUI_DimensionProperty::operator QVariant() const { QVariant aQVariant; aQVariant.setValue( *this ); return aQVariant; } //================================================================================= // function : operator QString() // purpose : //================================================================================= GEOMGUI_DimensionProperty::operator QString() const { QStringList anItems; VectorOfVisibility::ConstIterator aVisibilityIt = myVisibility.constBegin(); VectorOfRecords::ConstIterator aRecordIt = myRecords.constBegin(); VectorOfNames::ConstIterator aNameIt = myNames.constBegin(); for ( ; aRecordIt != myRecords.constEnd(); ++aRecordIt, ++aNameIt, ++aVisibilityIt ) { QString aName = *aNameIt; const bool& isVisible = *aVisibilityIt; const RecordPtr& aRecord = *aRecordIt; // pack values std::vector aPacked; aRecord->ToValues( aPacked ); // put values into pattern QString aStringValues; switch ( aRecord->Type() ) { case DimensionType_Length : aStringValues = PATTERN_LENGTH; break; case DimensionType_Diameter : aStringValues = PATTERN_DIAMETER; break; case DimensionType_Angle : aStringValues = PATTERN_ANGLE; break; default: continue; } aStringValues.remove("\\"); int it = 0; for ( ; it < aPacked.size(); ++it ) { int aNextPos = aStringValues.indexOf("(.*)"); if ( aNextPos < 0 ) { break; // invalid pattern } aStringValues.replace( aNextPos, 4, QString::number( aPacked.at(it) ) ); } if ( it < aPacked.size() ) { continue; // invalid pattern } // replace all ':' to '::' for pattern matching aName.replace(":", "::"); anItems.append( QString("{ Name=") + aName + QString(":") + QString("Visible=") + QString::number( isVisible ? 1 : 0 ) + QString(":") + QString("Type=") + QString::number( (int) aRecord->Type() ) + QString(":") + aStringValues + QString(" }") ); } return anItems.join( ":" ); } //================================================================================= // function : operator == // purpose : //================================================================================= bool GEOMGUI_DimensionProperty::operator == (const GEOMGUI_DimensionProperty& theOther) const { if ( myVisibility.size() != theOther.myVisibility.size() || myNames.size() != theOther.myNames.size() || myRecords.size() != theOther.myRecords.size() ) { return false; } for ( int it = 0; it < myRecords.size(); ++it ) { if ( myVisibility[it] != theOther.myVisibility[it] ) { return false; } if ( myNames[it] != theOther.myNames[it] ) { return false; } const RecordPtr& aRecord = myRecords[it]; const RecordPtr& aOtherRecord = theOther.myRecords[it]; if ( aRecord->Type() != aOtherRecord->Type() ) { return false; } switch ( aRecord->Type() ) { case DimensionType_Length: if ( (*aRecord->AsLength()) != (*aOtherRecord->AsLength()) ) { return false; } break; case DimensionType_Diameter: if ( (*aRecord->AsDiameter()) != (*aOtherRecord->AsDiameter()) ) { return false; } break; case DimensionType_Angle: if ( (*aRecord->AsAngle()) != (*aOtherRecord->AsAngle()) ) { return false; } break; } } return true; } //================================================================================= // function : GetNumber // purpose : //================================================================================= int GEOMGUI_DimensionProperty::GetNumber() const { return myRecords.size(); } //================================================================================= // function : AddRecord // purpose : //================================================================================= void GEOMGUI_DimensionProperty::AddRecord( const Handle(AIS_Dimension)& theIO, const gp_Ax3& theLCS ) { RecordPtr aNewRecord; int aType = TypeFromIO( theIO ); switch ( aType ) { case DimensionType_Length : { Handle(AIS_LengthDimension) aLength = Handle(AIS_LengthDimension)::DownCast( theIO ); aNewRecord = RecordPtr( new Length() ); aNewRecord->AsLength()->Init( aLength, theLCS ); break; } case DimensionType_Diameter : { Handle(AIS_DiameterDimension) aDiam = Handle(AIS_DiameterDimension)::DownCast( theIO ); aNewRecord = RecordPtr( new Diameter() ); aNewRecord->AsDiameter()->Init( aDiam, theLCS ); break; } case DimensionType_Angle : { Handle(AIS_AngleDimension) anAngle = Handle(AIS_AngleDimension)::DownCast( theIO ); aNewRecord = RecordPtr( new Angle() ); aNewRecord->AsAngle()->Init( anAngle, theLCS ); } } myVisibility.append( true ); myNames.append( QString() ); myRecords.append( aNewRecord ); } //================================================================================= // function : AddRecord // purpose : //================================================================================= void GEOMGUI_DimensionProperty::AddRecord( const RecordPtr& theRecord ) { myVisibility.append( true ); myNames.append( QString() ); myRecords.append( theRecord ); } //================================================================================= // function : RemoveRecord // purpose : //================================================================================= void GEOMGUI_DimensionProperty::RemoveRecord( const int theIndex ) { myNames.remove( theIndex ); myVisibility.remove( theIndex ); myRecords.remove( theIndex ); } //================================================================================= // function : Clear // purpose : //================================================================================= void GEOMGUI_DimensionProperty::Clear() { myNames.clear(); myVisibility.clear(); myRecords.clear(); } //================================================================================= // function : SetRecord // purpose : //================================================================================= void GEOMGUI_DimensionProperty::SetRecord( const int theIndex, const Handle(AIS_Dimension)& theIO, const gp_Ax3& theLCS ) { int aType = TypeFromIO( theIO ); RecordPtr& aChangeRecord = myRecords[theIndex]; switch ( aType ) { case DimensionType_Length : { Handle(AIS_LengthDimension) aLength = Handle(AIS_LengthDimension)::DownCast( theIO ); aChangeRecord = RecordPtr( new Length() ); aChangeRecord->AsLength()->Init( aLength, theLCS ); break; } case DimensionType_Diameter : { Handle(AIS_DiameterDimension) aDiam = Handle(AIS_DiameterDimension)::DownCast( theIO ); aChangeRecord = RecordPtr( new Diameter() ); aChangeRecord->AsDiameter()->Init( aDiam, theLCS ); break; } case DimensionType_Angle : { Handle(AIS_AngleDimension) anAngle = Handle(AIS_AngleDimension)::DownCast( theIO ); aChangeRecord = RecordPtr( new Angle() ); aChangeRecord->AsAngle()->Init( anAngle, theLCS ); } } } //================================================================================= // function : SetRecord // purpose : //================================================================================= void GEOMGUI_DimensionProperty::SetRecord( const int theIndex, const RecordPtr& theRecord ) { myRecords[theIndex] = theRecord; } //================================================================================= // function : GetRecord // purpose : //================================================================================= const GEOMGUI_DimensionProperty::RecordPtr& GEOMGUI_DimensionProperty::GetRecord( const int theIndex ) const { return myRecords[theIndex]; } //================================================================================= // function : IsVisible // purpose : //================================================================================= bool GEOMGUI_DimensionProperty::IsVisible( const int theIndex ) const { return myVisibility[theIndex]; } //================================================================================= // function : SetVisible // purpose : //================================================================================= void GEOMGUI_DimensionProperty::SetVisible( const int theIndex, const bool theIsVisible ) { myVisibility[theIndex] = theIsVisible; } //================================================================================= // function : GetName // purpose : //================================================================================= QString GEOMGUI_DimensionProperty::GetName( const int theIndex ) const { return myNames[theIndex]; } //================================================================================= // function : SetName // purpose : //================================================================================= void GEOMGUI_DimensionProperty::SetName( const int theIndex, const QString &theName ) { myNames[theIndex] = theName; } //================================================================================= // function : GetType // purpose : //================================================================================= int GEOMGUI_DimensionProperty::GetType( const int theIndex ) const { return myRecords[theIndex]->Type(); } //================================================================================= // function : LoadFromAttribute // purpose : //================================================================================= void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy, const std::string& theEntry ) { Clear(); _PTR(SObject) aSObj = theStudy->studyDS()->FindObjectID( theEntry ); if ( !aSObj ) { return; } _PTR(StudyBuilder) aBuilder = theStudy->studyDS()->NewBuilder(); _PTR(GenericAttribute) aSeekAtt; _PTR(AttributeTableOfReal) aRecordsAtt; if ( !aSObj->FindAttribute( aSeekAtt, "AttributeTableOfReal" ) ) { return; } aRecordsAtt = aSeekAtt; for ( int aRecordIt = 1; aRecordIt <= aRecordsAtt->GetNbColumns(); ++aRecordIt ) { std::vector aPacked = aRecordsAtt->GetColumn( aRecordIt ); RecordPtr aRecord; QString aName( aRecordsAtt->GetColumnTitle( aRecordIt ).c_str() ); // unpack records int it = 0; // visibility [0] bool isVisible = (bool) aPacked[it++]; // type [1] int aType = (int) aPacked[it++]; switch (aType) { case DimensionType_Length : aRecord = RecordPtr( new Length ); break; case DimensionType_Diameter : aRecord = RecordPtr( new Diameter ); break; case DimensionType_Angle : aRecord = RecordPtr( new Angle ); break; } aRecord->FromValues(it, aPacked); myVisibility.append( isVisible ); myNames.append( aName ); myRecords.append( aRecord ); } } //================================================================================= // function : SaveToAttribute // purpose : //================================================================================= void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy, const std::string &theEntry ) { _PTR(SObject) aSObj = theStudy->studyDS()->FindObjectID( theEntry ); if ( !aSObj ) { return; } _PTR(StudyBuilder) aBuilder = theStudy->studyDS()->NewBuilder(); _PTR(AttributeTableOfReal) aRecordsAtt; aRecordsAtt = aBuilder->FindOrCreateAttribute( aSObj, "AttributeTableOfReal" ); aRecordsAtt->SetNbColumns( 0 ); for ( int it = 0; it < myRecords.size(); ++it ) { bool aVisibility = myVisibility[it]; QString& aName = myNames[it]; RecordPtr& aRecord = myRecords[it]; std::vector aPacked; // visibility [0] aPacked.push_back( (double) aVisibility ); // type [1] aPacked.push_back( (double) aRecord->Type() ); // values aRecord->ToValues( aPacked ); aRecordsAtt->AddColumn( aPacked ); aRecordsAtt->SetColumnTitle( it + 1, aName.toStdString() ); } } //================================================================================= // function : TypeFromIO // purpose : //================================================================================= int GEOMGUI_DimensionProperty::TypeFromIO( const Handle(AIS_Dimension)& theIO ) const { if ( theIO->IsKind( STANDARD_TYPE( AIS_LengthDimension ) ) ) { return DimensionType_Length; } if ( theIO->IsKind( STANDARD_TYPE( AIS_DiameterDimension ) ) ) { return DimensionType_Diameter; } if ( theIO->IsKind( STANDARD_TYPE( AIS_AngleDimension ) ) ) { return DimensionType_Angle; } Standard_ProgramError::Raise( "unsupported dimension type" ); return 0; }