Salome HOME
updated copyright message
[modules/geom.git] / src / GEOMGUI / GEOMGUI_AnnotationAttrs.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : GEOMGUI_AnnotationAttr.cxx
24 // Author : Anton POLETAEV, Open CASCADE S.A.S.
25 //
26
27 // SALOME includes
28 #include <GEOMGUI_AnnotationAttrs.h>
29 #include <GEOM_Annotation.hxx>
30 #include <SALOMEDSImpl_AttributeParameter.hxx>
31
32 // STL includes
33 #include <string>
34 #include <vector>
35 #include <sstream>
36
37 IMPLEMENT_STANDARD_RTTIEXT( GEOMGUI_AnnotationAttrs, Standard_Transient )
38
39 namespace
40 {
41   static const std::string PARAMETER_COUNT = "GEOMGUI_AnnotationAttrs_Count";
42
43   std::string PARAMETER_I( const std::string& s, const int i ) {
44     std::stringstream ss;
45     ss << i;
46     return std::string( s ) + ss.str();
47   }
48   std::string PARAMETER_IS_VISIBLE( const int i ) {
49     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_IsVisible", i );
50   }
51   std::string PARAMETER_IS_2D( const int i ) {
52     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_Is2D", i );
53   }
54   std::string PARAMETER_TEXT( const int i ) {
55     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_Text", i );
56   }
57   std::string PARAMETER_POSITION( const int i ) {
58     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_Position", i );
59   }
60   std::string PARAMETER_ATTACH( const int i ) {
61     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_Attach", i );
62   }
63   std::string PARAMETER_SHAPE(  const int i ) {
64     return PARAMETER_I( "GEOMGUI_AnnotationAttrs_Shape", i );
65   }
66
67   // REGEXP pattern for converting array of entries into plain text string.
68   // The pattern has the following structure:
69   // ENTRY: { text[string] : visibility[bool] : screen fixed[bool] : position[xyz] : attach[xyz] }
70   static const QString PATTERN_ITEM_GROUP = "\\{ (Text=(?::{2,}|.)*:(?!:)Screen=.*:Position=\\{(.*):(.*):(.*)\\}:Attach=\\{(.*):(.*):(.*)\\}:ShapeIdx=.*:ShapeType=.*) \\}";
71   static const QString PATTERN_ITEM = "Text=((?::{2,}|.)*):(?!:)Screen=(\\d{1}):Position=\\{(.*):(.*):(.*)\\}:Attach=\\{(.*):(.*):(.*)\\}:ShapeIdx=(\\-?\\d{1,}):ShapeType=(\\d{1})";
72   static QString toPattern (const QString& theText,
73                             const bool theIsFixed,
74                             const gp_Pnt& thePosition,
75                             const gp_Pnt& theAttach,
76                             const int theShapeIndex,
77                             const int theShapeType)
78   {
79     return QString( "{ Text=" ) + theText +
80            QString( ":" ) + QString( "Screen=" ) + QString::number( theIsFixed ? 1 : 0 ) +
81            QString( ":" ) + QString( "Position={" ) +
82              QString::number( thePosition.X() ) + QString( ":" ) + 
83              QString::number( thePosition.Y() ) + QString( ":" ) + 
84              QString::number( thePosition.Z() ) + QString( "}" ) + 
85            QString( ":" ) + QString( "Attach={" ) +
86              QString::number( theAttach.X() ) + QString( ":" ) + 
87              QString::number( theAttach.Y() ) + QString( ":" ) + 
88              QString::number( theAttach.Z() ) + QString( "}" ) +
89            QString( ":" ) + QString( "ShapeIdx=" ) + QString::number( theShapeIndex ) +
90            QString( ":" ) + QString( "ShapeType=" ) + QString::number( theShapeType ) +
91            QString( " }" );
92   }
93 }
94
95 //=================================================================================
96 // function : FindAttributes
97 // purpose  : 
98 //=================================================================================
99 Handle(GEOMGUI_AnnotationAttrs) GEOMGUI_AnnotationAttrs::FindAttributes( const _PTR(SObject)& theObject )
100 {
101   _PTR(GenericAttribute) aGenericAttr;
102   _PTR(AttributeParameter) aParameterMap;
103
104   if ( !theObject || !theObject->FindAttribute( aGenericAttr, "AttributeParameter" ) )
105   {
106     return Handle(GEOMGUI_AnnotationAttrs)();
107   }
108
109   aParameterMap = aGenericAttr;
110
111   if ( !aParameterMap->IsSet( PARAMETER_COUNT, PT_INTEGER ) )
112   {
113     return Handle(GEOMGUI_AnnotationAttrs)();
114   }
115
116   return new GEOMGUI_AnnotationAttrs( theObject, aParameterMap );
117 }
118
119 //=================================================================================
120 // function : FindOrCreateAttributes
121 // purpose  : 
122 //=================================================================================
123 Handle(GEOMGUI_AnnotationAttrs) GEOMGUI_AnnotationAttrs::FindOrCreateAttributes(
124   const _PTR(SObject)& theObject, SalomeApp_Study* theStudy )
125 {
126   _PTR(StudyBuilder) aBuilder = theStudy->studyDS()->NewBuilder();
127   _PTR(AttributeParameter) aParameterMap = aBuilder->FindOrCreateAttribute( theObject, "AttributeParameter" );
128   if ( !aParameterMap->IsSet( PARAMETER_COUNT, PT_INTEGER ) )
129   {
130     aParameterMap->SetInt( PARAMETER_COUNT, 0 );
131   }
132
133   return new GEOMGUI_AnnotationAttrs( theObject, aParameterMap );
134 }
135
136 //=================================================================================
137 // function : Remove
138 // purpose  : 
139 //=================================================================================
140 void GEOMGUI_AnnotationAttrs::Remove( const _PTR(SObject)& theObject )
141 {
142   _PTR(GenericAttribute) aGenericAttr;
143   _PTR(AttributeParameter) aParameterMap;
144
145   if ( !theObject->FindAttribute( aGenericAttr, "AttributeParameter" ) )
146   {
147     return;
148   }
149
150   aParameterMap = aGenericAttr;
151
152   if ( !aParameterMap->IsSet( PARAMETER_COUNT, PT_INTEGER ) )
153   {
154     return;
155   }
156
157   const int aParamCount = aParameterMap->GetInt( PARAMETER_COUNT );
158
159   for ( int anI = 0; anI < aParamCount; ++anI )
160   {
161     aParameterMap->RemoveID( PARAMETER_IS_VISIBLE( anI ), PT_BOOLEAN );
162     aParameterMap->RemoveID( PARAMETER_IS_2D( anI ), PT_BOOLEAN );
163     aParameterMap->RemoveID( PARAMETER_TEXT( anI ), PT_STRING );
164     aParameterMap->RemoveID( PARAMETER_POSITION( anI ), PT_REALARRAY );
165     aParameterMap->RemoveID( PARAMETER_ATTACH( anI ), PT_REALARRAY );
166     aParameterMap->RemoveID( PARAMETER_SHAPE( anI ), PT_INTARRAY );
167   }
168
169   aParameterMap->RemoveID( PARAMETER_COUNT, PT_INTEGER );
170 }
171
172 //=================================================================================
173 // function : ExportAsPropertyString
174 // purpose  : 
175 //=================================================================================
176 QString GEOMGUI_AnnotationAttrs::ExportAsPropertyString() const
177 {
178   QStringList anItems;
179
180   for ( int anI = 0; anI < GetNbAnnotation(); ++anI )
181   {
182     Properties aEntry;
183
184     GetProperties( anI, aEntry );
185
186     anItems.append( toPattern( aEntry.Text,
187                                aEntry.IsScreenFixed,
188                                aEntry.Position,
189                                aEntry.Attach,
190                                aEntry.ShapeIndex,
191                                aEntry.ShapeType ) );
192   }
193
194   return anItems.join( ":" );
195 }
196
197 //=================================================================================
198 // function : ImportFromPropertyString
199 // purpose  : 
200 //=================================================================================
201 void GEOMGUI_AnnotationAttrs::ImportFromPropertyString( const QString& theString )
202 {
203   SetNbAnnotation( 0 );
204
205   QRegExp aRegExpItemGroups( PATTERN_ITEM_GROUP );
206   QRegExp aRegExpItem( "^" + PATTERN_ITEM + "$" );
207   aRegExpItemGroups.setMinimal( true );
208   aRegExpItem.setMinimal( true );
209
210   int aPos = 0;
211   while ( ( aPos = aRegExpItemGroups.indexIn( theString, aPos ) ) != -1 )
212   {
213     aPos += aRegExpItemGroups.matchedLength();
214
215     QString aStrItem = aRegExpItemGroups.cap(1);
216
217     if ( aRegExpItem.indexIn( aStrItem ) < 0 )
218     {
219       continue;
220     }
221
222     QString aStrText       = aRegExpItem.cap( 1 );
223     QString aStrFixed      = aRegExpItem.cap( 2 );
224     QString aStrPosX       = aRegExpItem.cap( 3 );
225     QString aStrPosY       = aRegExpItem.cap( 4 );
226     QString aStrPosZ       = aRegExpItem.cap( 5 );
227     QString aStrAttX       = aRegExpItem.cap( 6 );
228     QString aStrAttY       = aRegExpItem.cap( 7 );
229     QString aStrAttZ       = aRegExpItem.cap( 8 );
230     QString aStrShapeIdx   = aRegExpItem.cap( 9 );
231     QString aStrShapeType  = aRegExpItem.cap( 10 );
232     aStrText.replace( "::", ":" );
233
234     Properties aEntry;
235     aEntry.Text = aStrText;
236     aEntry.IsVisible = false;
237     aEntry.IsScreenFixed = aStrFixed.toInt() != 0;
238     aEntry.Position.SetX( aStrPosX.toDouble() );
239     aEntry.Position.SetY( aStrPosY.toDouble() );
240     aEntry.Position.SetZ( aStrPosZ.toDouble() );
241     aEntry.Attach.SetX( aStrAttX.toDouble() );
242     aEntry.Attach.SetY( aStrAttY.toDouble() );
243     aEntry.Attach.SetZ( aStrAttZ.toDouble() );
244     aEntry.ShapeIndex = aStrShapeIdx.toInt();
245     aEntry.ShapeType = aStrShapeType.toInt();
246
247     Append( aEntry );
248   }
249 }
250
251 //=================================================================================
252 // function : SetNbAnnotation
253 // purpose  : 
254 //=================================================================================
255 void GEOMGUI_AnnotationAttrs::SetNbAnnotation( const int theCount ) const
256 {
257   const int aCount = this->GetNbAnnotation();
258
259   if ( aCount < theCount )
260   {
261     // set default values
262     for ( int anI = aCount; anI < theCount; ++anI )
263     {
264       myParameterMap->SetBool( PARAMETER_IS_VISIBLE( anI ), true );
265       myParameterMap->SetBool( PARAMETER_IS_2D( anI ), false );
266       myParameterMap->SetString( PARAMETER_TEXT( anI ), std::string() );
267       myParameterMap->SetRealArray( PARAMETER_POSITION( anI ), std::vector<double>(3, 0.0) );
268       myParameterMap->SetRealArray( PARAMETER_ATTACH( anI ), std::vector<double>(3, 0.0) );
269       myParameterMap->SetIntArray( PARAMETER_SHAPE( anI ), std::vector<int>(2, 0) );
270     }
271   }
272   else
273   {
274     // remove exceeding values
275     for ( int anI = theCount; anI < aCount; ++anI )
276     {
277       myParameterMap->RemoveID( PARAMETER_IS_VISIBLE( anI ), PT_BOOLEAN );
278       myParameterMap->RemoveID( PARAMETER_IS_2D( anI ), PT_BOOLEAN );
279       myParameterMap->RemoveID( PARAMETER_TEXT( anI ), PT_STRING );
280       myParameterMap->RemoveID( PARAMETER_POSITION( anI ), PT_REALARRAY );
281       myParameterMap->RemoveID( PARAMETER_ATTACH( anI ), PT_REALARRAY );
282       myParameterMap->RemoveID( PARAMETER_SHAPE( anI ), PT_INTARRAY );
283     }
284   }
285
286   myParameterMap->SetInt( PARAMETER_COUNT, theCount );
287 }
288
289 //=================================================================================
290 // function : GetNbAnnotation
291 // purpose  : 
292 //=================================================================================
293 int GEOMGUI_AnnotationAttrs::GetNbAnnotation() const
294 {
295   return myParameterMap->GetInt( PARAMETER_COUNT );
296 }
297
298 //=================================================================================
299 // function : SetVisible
300 // purpose  : 
301 //=================================================================================
302 void GEOMGUI_AnnotationAttrs::SetIsVisible( const int theIndex, const bool theIsVisible )
303 {
304   myParameterMap->SetBool( PARAMETER_IS_VISIBLE( theIndex ), theIsVisible );
305 }
306
307 //=================================================================================
308 // function : GetIsVisible
309 // purpose  : 
310 //=================================================================================
311 bool GEOMGUI_AnnotationAttrs::GetIsVisible( const int theIndex ) const
312 {
313   return myParameterMap->GetBool( PARAMETER_IS_VISIBLE( theIndex ) );
314 }
315
316 //=================================================================================
317 // function : SetText
318 // purpose  : 
319 //=================================================================================
320 void GEOMGUI_AnnotationAttrs::SetText( const int theIndex, const QString& theText )
321 {
322   myParameterMap->SetString( PARAMETER_TEXT( theIndex ), theText.toStdString() );
323 }
324
325 //=================================================================================
326 // function : GetText
327 // purpose  : 
328 //=================================================================================
329 QString GEOMGUI_AnnotationAttrs::GetText( const int theIndex ) const
330 {
331   return QString::fromStdString( myParameterMap->GetString( PARAMETER_TEXT( theIndex ) ) );
332 }
333
334 //=================================================================================
335 // function : SetIsScreenFixed
336 // purpose  : 
337 //=================================================================================
338 void GEOMGUI_AnnotationAttrs::SetIsScreenFixed( const int theIndex, const bool theIsScreenFixed )
339 {
340   myParameterMap->SetBool( PARAMETER_IS_2D( theIndex ), theIsScreenFixed );
341 }
342
343 //=================================================================================
344 // function : GetIsScreenFixed
345 // purpose  : 
346 //=================================================================================
347 bool GEOMGUI_AnnotationAttrs::GetIsScreenFixed( const int theIndex ) const
348 {
349   return myParameterMap->GetBool( PARAMETER_IS_2D( theIndex ) );
350 }
351
352 //=================================================================================
353 // function : SetPosition
354 // purpose  : 
355 //=================================================================================
356 void GEOMGUI_AnnotationAttrs::SetPosition( const int theIndex, const gp_Pnt& thePosition )
357 {
358   std::vector<double> aCoords( 3 );
359
360   aCoords[0] = thePosition.X();
361   aCoords[1] = thePosition.Y();
362   aCoords[2] = thePosition.Z();
363
364   myParameterMap->SetRealArray( PARAMETER_POSITION( theIndex ), aCoords );
365 }
366
367 //=================================================================================
368 // function : GetPosition
369 // purpose  : 
370 //=================================================================================
371 gp_Pnt GEOMGUI_AnnotationAttrs::GetPosition( const int theIndex ) const
372 {
373   std::vector<double> aCoords =
374     myParameterMap->GetRealArray( PARAMETER_POSITION( theIndex ) );
375
376   return gp_Pnt( aCoords[0], aCoords[1], aCoords[2] );
377 }
378
379 //=================================================================================
380 // function : SetAttach
381 // purpose  : 
382 //=================================================================================
383 void GEOMGUI_AnnotationAttrs::SetAttach( const int theIndex, const gp_Pnt& theAttach )
384 {
385   std::vector<double> aCoords( 3 );
386
387   aCoords[0] = theAttach.X();
388   aCoords[1] = theAttach.Y();
389   aCoords[2] = theAttach.Z();
390
391   myParameterMap->SetRealArray( PARAMETER_ATTACH( theIndex ), aCoords );
392 }
393
394 //=================================================================================
395 // function : GetAttach
396 // purpose  : 
397 //=================================================================================
398 gp_Pnt GEOMGUI_AnnotationAttrs::GetAttach( const int theIndex ) const
399 {
400   std::vector<double> aCoords =
401     myParameterMap->GetRealArray( PARAMETER_ATTACH( theIndex ) );
402
403   return gp_Pnt( aCoords[0], aCoords[1], aCoords[2] );
404 }
405
406 //=================================================================================
407 // function : SetShapeSel
408 // purpose  : 
409 //=================================================================================
410 void GEOMGUI_AnnotationAttrs::SetShapeSel( const int theIndex, const int theShapeType, const int theSubIdx )
411 {
412   std::vector<int> aSelection( 2 );
413
414   aSelection[0] = theShapeType;
415   aSelection[1] = theSubIdx;
416
417   myParameterMap->SetIntArray( PARAMETER_SHAPE( theIndex ), aSelection );
418 }
419
420 //=================================================================================
421 // function : GetShapeSel
422 // purpose  : 
423 //=================================================================================
424 void GEOMGUI_AnnotationAttrs::GetShapeSel( const int theIndex, int& theShapeType, int& theSubIdx ) const
425 {
426   std::vector<int> aSelection =
427     myParameterMap->GetIntArray( PARAMETER_SHAPE( theIndex ) );
428
429   theShapeType = aSelection[0];
430   theSubIdx    = aSelection[1];
431 }
432
433 //=================================================================================
434 // function : Append
435 // purpose  : 
436 //=================================================================================
437 void GEOMGUI_AnnotationAttrs::Append( const Properties& theProps )
438 {
439   this->Append( theProps, gp_Ax3() );
440 }
441
442 //=================================================================================
443 // function : Append
444 // purpose  : 
445 //=================================================================================
446 void GEOMGUI_AnnotationAttrs::Append( const Properties& theProps, const gp_Ax3& theShapeLCS )
447 {
448   const int aCount = this->GetNbAnnotation();
449   this->SetNbAnnotation( aCount + 1 );
450   this->SetProperties( aCount, theProps, theShapeLCS );
451 }
452
453 //=================================================================================
454 // function : Remove
455 // purpose  : 
456 //=================================================================================
457 void GEOMGUI_AnnotationAttrs::Remove( const Standard_Integer theIndex )
458 {
459   const int aCount = this->GetNbAnnotation();
460   if ( theIndex < 0 || theIndex >= aCount ) {
461     return;
462   }
463
464   std::vector<Properties> aEntries( (aCount - 1) - theIndex );
465   for ( int anI = theIndex + 1; anI < aCount; ++anI ) {
466     GetProperties( anI, aEntries[ anI - (theIndex + 1) ] );
467   }
468
469   SetNbAnnotation( theIndex );
470
471   for ( int anI = 0; anI < static_cast<int>( aEntries.size() ); ++anI ) {
472     Append( aEntries[anI] );
473   }
474 }
475
476 //=================================================================================
477 // function : SetProperties
478 // purpose  : 
479 //=================================================================================
480 void GEOMGUI_AnnotationAttrs::SetProperties( const int theIndex, const Properties& theProps )
481 {
482   this->SetProperties( theIndex, theProps, gp_Ax3() );
483 }
484
485 //=================================================================================
486 // function : SetProperties
487 // purpose  : 
488 //=================================================================================
489 void GEOMGUI_AnnotationAttrs::SetProperties( const int theIndex, const Properties& theProps,
490                                              const gp_Ax3& theShapeLCS )
491 {
492   gp_Trsf aToShapeLCS;
493   aToShapeLCS.SetTransformation( gp_Ax3(), theShapeLCS );
494
495   this->SetText( theIndex, theProps.Text );
496   this->SetIsVisible( theIndex, theProps.IsVisible );
497   this->SetIsScreenFixed( theIndex, theProps.IsScreenFixed );
498   this->SetShapeSel( theIndex, theProps.ShapeType, theProps.ShapeIndex );
499   this->SetAttach( theIndex, theProps.Attach.Transformed( aToShapeLCS ) );
500   this->SetPosition( theIndex, (theProps.IsScreenFixed) ? 
501     theProps.Position : theProps.Position.Transformed( aToShapeLCS ) );
502 }
503
504 //=================================================================================
505 // function : GetProperties
506 // purpose  : 
507 //=================================================================================
508 void GEOMGUI_AnnotationAttrs::GetProperties( const int theIndex, Properties& theProps ) const
509 {
510   theProps.Text = this->GetText( theIndex );
511   theProps.IsVisible = this->GetIsVisible( theIndex );
512   theProps.IsScreenFixed = this->GetIsScreenFixed( theIndex );
513   theProps.Position = this->GetPosition( theIndex );
514   theProps.Attach = this->GetAttach( theIndex );
515
516   this->GetShapeSel( theIndex, theProps.ShapeType, theProps.ShapeIndex );
517 }
518
519 //=================================================================================
520 // function : SetupPresentation
521 // purpose  : 
522 //=================================================================================
523 void GEOMGUI_AnnotationAttrs::SetupPresentation( const Handle(GEOM_Annotation)& thePresentation,
524                                                  const Properties& theProps,
525                                                  const gp_Ax3& theShapeLCS )
526 {
527   gp_Trsf aFromShapeLCS;
528   aFromShapeLCS.SetTransformation( theShapeLCS, gp_Ax3() );
529
530   TCollection_ExtendedString aText;
531   for (int i = 0; i < (int)theProps.Text.length(); i++ )
532     aText.Insert( i + 1, theProps.Text[ i ].unicode() );
533
534   thePresentation->SetText( aText );
535   thePresentation->SetIsScreenFixed( theProps.IsScreenFixed );
536   thePresentation->SetAttachPoint( theProps.Attach.Transformed( aFromShapeLCS ) );
537   thePresentation->SetPosition( (theProps.IsScreenFixed) ? 
538     theProps.Position : theProps.Position.Transformed( aFromShapeLCS ) );
539 }
540
541 //=================================================================================
542 // function : SetupPresentation
543 // purpose  : 
544 //=================================================================================
545 void GEOMGUI_AnnotationAttrs::SetupPresentation( const Handle(GEOM_Annotation)& thePresentation,
546                                                  const int theIndex,
547                                                  const gp_Ax3& theShapeLCS )
548 {
549   Properties aProps;
550   this->GetProperties( theIndex, aProps );
551   this->SetupPresentation( thePresentation, aProps, theShapeLCS );
552 }