From: apl Date: Tue, 27 Sep 2016 10:54:16 +0000 (+0300) Subject: shape annotation container X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=804c280322a7672b4af9bb76db47f925c048af7b;p=modules%2Fgeom.git shape annotation container --- diff --git a/src/GEOMGUI/GEOMGUI_ShapeAnnotations.cxx b/src/GEOMGUI/GEOMGUI_ShapeAnnotations.cxx new file mode 100755 index 000000000..964453ce2 --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_ShapeAnnotations.cxx @@ -0,0 +1,326 @@ +// Copyright (C) 2007-2016 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_ShapeAnnotations.cxx +// Author : Anton POLETAEV, Open CASCADE S.A.S. +// + +#include +#include + +// OCCT includes +#include +#include + +#include + +// REGEXP pattern for converting array of entries into plain text string. +// The pattern has the following structure: +// ENTRY: { text[string] : visibility[bool] : screen fixed[bool] : position[xyz] : attach[xyz] } +namespace +{ + static const QString PATTERN_ITEM_GROUP = "\\{ (Text=(?::{2,}|.)*:(?!:)Visible=.*:Screen=.*:Position=\\{(.*):(.*):(.*)\\}:Attach=\\{(.*):(.*):(.*)\\}) \\}"; + static const QString PATTERN_ITEM = "Text=((?::{2,}|.)*):(?!:)Visible=(\\d{1}):Screen=(\\d{1}):Position=\\{(.*):(.*):(.*)\\}:Attach=\\{(.*):(.*):(.*)\\}"; + static QString toPattern (const QString& theText, + const bool theIsVisible, + const bool theIsFixed, + const gp_Pnt& thePosition, + const gp_Pnt& theAttach) + { + return QString("{ Text=") + theText + + QString(":") + QString("Visible=") + QString::number( theIsVisible ? 1 : 0 ) + + QString(":") + QString("Screen=") + QString::number( theIsFixed ? 1 : 0 ) + + QString(":") + QString("Position={") + + QString::number( thePosition.X() ) + QString(":") + + QString::number( thePosition.Y() ) + QString(":") + + QString::number( thePosition.Z() ) + QString("}") + + QString(":") + QString("Attach={") + + QString::number( theAttach.X() ) + QString(":") + + QString::number( theAttach.Y() ) + QString(":") + + QString::number( theAttach.Z() ) + QString("}") + + QString(" }"); + } +}; + +//================================================================================= +// function : Constructor +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::GEOMGUI_ShapeAnnotations() +{ +} + +//================================================================================= +// function : Copy constructor +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::GEOMGUI_ShapeAnnotations( const GEOMGUI_ShapeAnnotations& theOther ) +{ + myAnnotations = theOther.myAnnotations; +} + +//================================================================================= +// function : Init constructor +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::GEOMGUI_ShapeAnnotations( SalomeApp_Study* theStudy, const std::string& theEntry ) +{ + LoadFromAttribute( theStudy, theEntry ); +} + +//================================================================================= +// function : Init constructor +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::GEOMGUI_ShapeAnnotations( 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; + } + + QString aStrText = aRegExpItem.cap( 1 ); + QString aStrVisible = aRegExpItem.cap( 2 ); + QString aStrFixed = aRegExpItem.cap( 3 ); + QString aStrPosX = aRegExpItem.cap( 4 ); + QString aStrPosY = aRegExpItem.cap( 5 ); + QString aStrPosZ = aRegExpItem.cap( 6 ); + QString aStrAttX = aRegExpItem.cap( 7 ); + QString aStrAttY = aRegExpItem.cap( 8 ); + QString aStrAttZ = aRegExpItem.cap( 9 ); + aStrText.replace( "::", ":" ); + + ShapeAnnotation aEntry; + aEntry.Text = aStrText; + aEntry.IsVisible = aStrVisible.toInt() != 0; + aEntry.IsScreenFixed = aStrFixed.toInt() != 0; + aEntry.Position.SetX( aStrPosX.toDouble() ); + aEntry.Position.SetY( aStrPosY.toDouble() ); + aEntry.Position.SetZ( aStrPosZ.toDouble() ); + aEntry.Attach.SetX( aStrAttX.toDouble() ); + aEntry.Attach.SetY( aStrAttY.toDouble() ); + aEntry.Attach.SetZ( aStrAttZ.toDouble() ); + + myAnnotations.append( aEntry ); + } +} + +//================================================================================= +// function : Destructor +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::~GEOMGUI_ShapeAnnotations() +{ +} + +//================================================================================= +// function : operator QVariant() +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::operator QVariant() const +{ + QVariant aQVariant; + aQVariant.setValue( *this ); + return aQVariant; +} + +//================================================================================= +// function : operator QString() +// purpose : +//================================================================================= +GEOMGUI_ShapeAnnotations::operator QString() const +{ + QStringList anItems; + + for ( int i = 0; i < myAnnotations.size(); ++i ) + { + const ShapeAnnotation& aEntry = myAnnotations[i]; + // + anItems.append (toPattern (aEntry.Text, aEntry.IsVisible, aEntry.IsScreenFixed, aEntry.Position, aEntry.Attach)); + } + + return anItems.join( ":" ); +} + +//================================================================================= +// function : operator == +// purpose : +//================================================================================= +bool GEOMGUI_ShapeAnnotations::operator == (const GEOMGUI_ShapeAnnotations& theOther) const +{ + if ( myAnnotation.size() != theOther.myAnnotations.size() ) + { + return false; + } + + for ( int i = 0; i < myAnnotation.size(); ++i ) + { + if ( myAnnotations[i] != theOther.myAnnotations[i] ) + { + return false; + } + } + + return true; +} + +//================================================================================= +// function : Add +// purpose : +//================================================================================= +void GEOMGUI_ShapeAnnotations::Add( const Handle(GEOM_Annotation)& theShapeAnnotation, const gp_Ax3& theLCS ) +{ + Add( ShapeAnnotation() ); + // + FromPresentation( Count() - 1, theShapeAnnotation, theLCS ); +} + +//================================================================================= +// function : FromPresentation +// purpose : +//================================================================================= +void GEOMGUI_ShapeAnnotations::FromPresentation( const int theIndex, + const Handle(GEOM_Annotation)& theShapeAnnotation, + const gp_Ax3& theLCS ) +{ + gp_Trsf aFromLCS; + aFromLCS.SetTransformation( gp_Ax3(), theLCS ); + // + ShapeAnnotation& aChangeEntry = myAnnotations[theIndex]; + aChangeEntry.IsScreenFixed = theShapeAnnotation->GetIsScreenFixed(); + aChangeEntry.Text = QString( theShapeAnnotation->GetText().ToExtString() ); + aChangeEntry.Attach = theShapeAnnotation->GetAttachPoint().Transformed( aFromLCS ); + aChangeEntry.Position = theShapeAnnotation->GetPosition(); +} + +//================================================================================= +// function : ToPresentation +// purpose : +//================================================================================= +void GEOMGUI_ShapeAnnotations::ToPresentation( const int theIndex, + const Handle(GEOM_Annotation)& theShapeAnnotation, + const gp_Ax3& theLCS ) +{ + gp_Trsf aToLCS; + aToLCS.SetTransformation( theLCS, gp_Ax3() ); + // + const ShapeAnnotation& aEntry = myAnnotations[theIndex]; + theShapeAnnotation->SetScreenFixed( aEntry.IsScreenFixed ); + theShapeAnnotation->SetText( aEntry.Text ); + theShapeAnnotation->SetPosition( aEntry.Position ); + theShapeAnnotation->SetAttachPoint( aEntry.Attach.Transformed( aToLCS ) ); +} + +//================================================================================= +// function : LoadFromAttribute +// purpose : +//================================================================================= +void GEOMGUI_ShapeAnnotations::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) aDataAtt; + + if ( !aSObj->FindAttribute( aSeekAtt, "AttributeTableOfReal" ) ) + { + return; + } + + aDataAtt = aSeekAtt; + + for ( int i = 1; i <= aDataAtt->GetNbColumns(); ++i ) + { + std::vector aPropertyArray = aDataAtt->GetColumn( i ); + + ShapeAnnotation aEntry; + aEntry.Text = QString( aDataAtt->GetColumnTitle( i ).c_str() ); + aEntry.IsVisible = static_cast( aPropertyArray[i++] ); + aEntry.IsScreenFixed = static_cast( aPropertyArray[i++] ); + aEntry.Position.SetX( static_cast( aPropertyArray[i++] ) ); + aEntry.Position.SetY( static_cast( aPropertyArray[i++] ) ); + aEntry.Position.SetZ( static_cast( aPropertyArray[i++] ) ); + aEntry.Attach.SetX( static_cast( aPropertyArray[i++] ) ); + aEntry.Attach.SetY( static_cast( aPropertyArray[i++] ) ); + aEntry.Attach.SetZ( static_cast( aPropertyArray[i++] ) ); + + myAnnotations.append( aEntry ); + } +} + +//================================================================================= +// function : SaveToAttribute +// purpose : +//================================================================================= +void GEOMGUI_ShapeAnnotations::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) aDataAtt; + + aDataAtt = aBuilder->FindOrCreateAttribute( aSObj, "AttributeTableOfReal" ); + aDataAtt->SetNbColumns( 0 ); + + for ( int i = 0; i < myAnnotations.size(); ++i ) + { + const ShapeAnnotation& aEntry = myAnnotations[i]; + + std::vector aPropertyArray; + aPropertyArray.push_back( static_cast(aEntry.IsVisible) ); + aPropertyArray.push_back( static_cast(aEntry.IsScreenFixed) ); + aPropertyArray.push_back( aEntry.Position.X() ); + aPropertyArray.push_back( aEntry.Position.Y() ); + aPropertyArray.push_back( aEntry.Position.Z() ); + aPropertyArray.push_back( aEntry.Attach.X() ); + aPropertyArray.push_back( aEntry.Attach.Y() ); + aPropertyArray.push_back( aEntry.Attach.Z() ); + + aDataAtt->AddColumn( aPropertyArray ); + aDataAtt->SetColumnTitle( i + 1, aEntry.Text.toStdString() ); + } +} diff --git a/src/GEOMGUI/GEOMGUI_ShapeAnnotations.h b/src/GEOMGUI/GEOMGUI_ShapeAnnotations.h new file mode 100755 index 000000000..8b9e7410f --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_ShapeAnnotations.h @@ -0,0 +1,213 @@ +// Copyright (C) 2007-2016 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_ShapeAnnotations.h +// Author : Anton POLETAEV, Open CASCADE S.A.S. +// + +#ifndef GEOMGUI_SHAPEANNOTATIONS_H +#define GEOMGUI_SHAPEANNOTATIONS_H + +// OCCT includes +#include +#include +#include +#include + +#include +#include +#include + +class SalomeApp_Study; + +/*! + * \brief Algorithms to translate and manitain list of shape annotation properties. + * + * Shape annotation presentations are store in relative coordinate system (LCS). + * To ensure that dimension is bound to the equal shape irrespectively of its location + * transformation. + */ +class Standard_EXPORT GEOMGUI_ShapeAnnotations +{ +public: + + /*! + * \ brief Structure representing properties of the shape annotation entry. + */ + struct ShapeAnnotation + { + QString Text; + bool IsVisible; + bool IsScreenFixed; + gp_Pnt Position; + gp_Pnt Attach; + }; + +public: + + /*! + * \brief Constructor. Inits empty property. + */ + GEOMGUI_ShapeAnnotations(); + + /*! + * \brief Copy constructor. + */ + GEOMGUI_ShapeAnnotations( const GEOMGUI_ShapeAnnotations& theOther ); + + /*! + * \brief Constructor. Inits property from attribute. + */ + GEOMGUI_ShapeAnnotations( SalomeApp_Study* theStudy, const std::string& theEntry ); + + /*! + * \brief Constructor. Inits property from formatted QString. + */ + GEOMGUI_ShapeAnnotations( const QString& theProperty ); + + /*! + * \brief Destructor. + */ + ~GEOMGUI_ShapeAnnotations(); + + /*! + * \brief Overload QVariant cast operator. + */ + operator QVariant() const; + + /*! + * \brief Overload QString cast operator. + */ + operator QString() const; + + /*! + * \brief Overload comparsion. + */ + bool operator == (const GEOMGUI_ShapeAnnotations &theOther) const; + + /*! + * \brief Overload comparsion. + */ + bool operator != (const GEOMGUI_ShapeAnnotations &theOther) const + { + return !(operator == (theOther)); + } + +public: + + /*! + * \brief Adds new shape annotation entry using explicit definition. + * \param theShapeAnnotation [in] the explicit definition of the annotation. + */ + void Add( const ShapeAnnotation& theShapeAnnotation ) + { + myAnnotations.append( theShapeAnnotation ); + } + + /*! + * \brief Adds new entry using data of the interactive presentation given. + * \param theShapeAnnotation [in] the interactive shape annotation holding properties. + * \param theLCS [in] the local coordinate system of parent object. + */ + void Add( const Handle(GEOM_Annotation)& theShapeAnnotation, const gp_Ax3& theLCS ); + + /*! + * \brief Update entry data using the explicit definition. + * \param theIndex [in] the index of the dimension record. + * \param theShapeAnnotation [in] the explicit definition of the annotation. + */ + void SetValues( const int theIndex, const ShapeAnnotation& theShapeAnnotation ) + { + myAnnotations[theIndex] = theShapeAnnotation; + } + + /*! + * \brief Sets annotation's entry data using the properties of interactive presentation. + * \param theIndex [in] the index of the record. + * \param theShapeAnnotation [in] the interactive presnetation. + * \param theLCS [in] the local coordinate system of parent object. + */ + void FromPresentation( const int theIndex, + const Handle(GEOM_Annotation)& theShapeAnnotation, + const gp_Ax3& theLCS ); + + /*! + * \brief Update presentation properties using the annotation record definition. + * \param theIndex [in] the index of the dimension record. + * \param theShapeAnnotation [in] the explicit definition of the annotation. + */ + void ToPresentation( const int theIndex, + const Handle(GEOM_Annotation)& theShapeAnnotation, + const gp_Ax3& theLCS ); + + /*! + * \brief Get explicit definition of an annotation by index. + * \param theIndex [in] the index of the entry. + */ + const ShapeAnnotation& Get( const int theIndex ) const { return myAnnotations[theIndex]; } + + /*! + * \brief Returns mutable reference on the annotation entry. + * \param theIndex [in] the index of annotation entry. + */ + ShapeAnnotation& Change( const int theIndex ) { return myAnnotations[theIndex]; } + + /*! + * \brief Removes entry by its index. + * \param theIndex [in] the index of annotation entry. + */ + void Remove( const int theIndex ) { myAnnotations.remove( theIndex ); } + + /*! + * \brief Clears property data. + */ + void Clear() { myAnnotations.clear(); } + + /*! + * \brief Returns number of shape annotation records. + */ + int Count() const { return myAnnotations.size(); } + +public: + + /*! + * \brief Loads properties data from attribute. + * \param theStudy [in] the study. + * \param theEntry [in] the entry of GEOM object to operate with. + */ + void LoadFromAttribute( SalomeApp_Study* theStudy, const std::string& theEntry ); + + /*! + * \brief Saves properties data to attribute. + * \param theStudy [in] the study. + * \param theEntry [in] the entry of GEOM object to operate with. + */ + void SaveToAttribute( SalomeApp_Study* theStudy, const std::string& theEntry ); + +private: + + QVector myAnnotations; +}; + +Q_DECLARE_METATYPE(GEOMGUI_ShapeAnnotations); + +#endif