--- /dev/null
+// 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 <GEOMGUI_ShapeAnnotations.h>
+#include <GEOM_Annotation.hxx>
+
+// OCCT includes
+#include <Standard_ProgramError.hxx>
+#include <gp_Trsf.hxx>
+
+#include <SalomeApp_Study.h>
+
+// 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<double> aPropertyArray = aDataAtt->GetColumn( i );
+
+ ShapeAnnotation aEntry;
+ aEntry.Text = QString( aDataAtt->GetColumnTitle( i ).c_str() );
+ aEntry.IsVisible = static_cast<bool>( aPropertyArray[i++] );
+ aEntry.IsScreenFixed = static_cast<bool>( aPropertyArray[i++] );
+ aEntry.Position.SetX( static_cast<double>( aPropertyArray[i++] ) );
+ aEntry.Position.SetY( static_cast<double>( aPropertyArray[i++] ) );
+ aEntry.Position.SetZ( static_cast<double>( aPropertyArray[i++] ) );
+ aEntry.Attach.SetX( static_cast<double>( aPropertyArray[i++] ) );
+ aEntry.Attach.SetY( static_cast<double>( aPropertyArray[i++] ) );
+ aEntry.Attach.SetZ( static_cast<double>( 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<double> aPropertyArray;
+ aPropertyArray.push_back( static_cast<double>(aEntry.IsVisible) );
+ aPropertyArray.push_back( static_cast<double>(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() );
+ }
+}
--- /dev/null
+// 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 <gp_Ax3.hxx>
+#include <QVariant>
+#include <QVector>
+#include <QSharedPointer>
+
+#include <string>
+#include <vector>
+#include <list>
+
+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<ShapeAnnotation> myAnnotations;
+};
+
+Q_DECLARE_METATYPE(GEOMGUI_ShapeAnnotations);
+
+#endif