Salome HOME
5ce7871ac86c91c80b362c32d20f4787ce9b9f4b
[modules/geom.git] / src / GEOMGUI / GEOMGUI_DimensionProperty.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, 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.
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_DimensionProperty.cxx
24 // Author : Anton POLETAEV, Open CASCADE S.A.S.
25 //
26
27 #include "GEOMGUI_DimensionProperty.h"
28
29 // OCCT includes
30 #include <Standard_ProgramError.hxx>
31 #include <gp_Trsf.hxx>
32
33 #include <SalomeApp_Study.h>
34
35 //=================================================================================
36 // function : Length::Init
37 // purpose  : 
38 //=================================================================================
39 void GEOMGUI_DimensionProperty::Length::Init( const Handle(AIS_LengthDimension)& theIO, const gp_Ax3& theLCS )
40 {
41   gp_Trsf aFromLCS;
42   aFromLCS.SetTransformation( gp_Ax3(), theLCS );
43
44   FirstPoint  = theIO->FirstPoint().Transformed( aFromLCS );
45   SecondPoint = theIO->SecondPoint().Transformed( aFromLCS );
46   Plane       = theIO->GetPlane().Transformed( aFromLCS );
47   Flyout      = theIO->GetFlyout();
48   TextHPos    = theIO->DimensionAspect()->TextHorizontalPosition();
49   TextVPos    = theIO->DimensionAspect()->TextVerticalPosition();
50   ArrowPos    = theIO->DimensionAspect()->ArrowOrientation();
51 }
52
53 //=================================================================================
54 // function : Length::Update
55 // purpose  : 
56 //=================================================================================
57 void GEOMGUI_DimensionProperty::Length::Update( Handle(AIS_LengthDimension)& theIO, const gp_Ax3& theLCS )
58 {
59   gp_Trsf aToLCS;
60   aToLCS.SetTransformation( theLCS, gp_Ax3() );
61
62   gp_Pnt aPoint1 = FirstPoint.Transformed( aToLCS );
63   gp_Pnt aPoint2 = SecondPoint.Transformed( aToLCS );
64   gp_Pln aPlane  = Plane.Transformed( aToLCS );
65
66   theIO->SetMeasuredGeometry( aPoint1, aPoint2, aPlane );
67   theIO->SetFlyout( Flyout );
68
69   Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
70   aStyle->SetTextHorizontalPosition( TextHPos );
71   aStyle->SetTextVerticalPosition( TextVPos );
72   aStyle->SetArrowOrientation( ArrowPos );
73   theIO->SetDimensionAspect( aStyle );
74 }
75
76 //=================================================================================
77 // function : Length::operator == 
78 // purpose  : 
79 //=================================================================================
80 bool GEOMGUI_DimensionProperty::Length::operator == (const Length& theOther) const
81 {
82   if ( FirstPoint.X()  != theOther.FirstPoint.X()
83     || FirstPoint.Y()  != theOther.FirstPoint.Y()
84     || FirstPoint.Z()  != theOther.FirstPoint.Z()
85     || SecondPoint.X() != theOther.SecondPoint.X()
86     || SecondPoint.Y() != theOther.SecondPoint.Y()
87     || SecondPoint.Z() != theOther.SecondPoint.Z() )
88   {
89     return false;
90   }
91
92   if ( Plane.Location().X() != theOther.Plane.Location().X()
93     || Plane.Location().Y() != theOther.Plane.Location().Y()
94     || Plane.Location().Z() != theOther.Plane.Location().Z()
95     || Plane.Axis().Direction().X() != theOther.Plane.Axis().Direction().X()
96     || Plane.Axis().Direction().Y() != theOther.Plane.Axis().Direction().Y()
97     || Plane.Axis().Direction().Z() != theOther.Plane.Axis().Direction().Z() )
98   {
99     return false;
100   }
101
102   if ( Flyout   != theOther.Flyout 
103     || TextHPos != theOther.TextHPos 
104     || TextVPos != theOther.TextVPos
105     || ArrowPos != theOther.ArrowPos )
106   {
107     return false;
108   }
109
110   return true;
111 }
112
113 //=================================================================================
114 // function : Diameter::Init
115 // purpose  : 
116 //=================================================================================
117 void GEOMGUI_DimensionProperty::Diameter::Init( const Handle(AIS_DiameterDimension)& theIO, const gp_Ax3& theLCS )
118 {
119   gp_Trsf aFromLCS;
120   aFromLCS.SetTransformation( gp_Ax3(), theLCS );
121
122   Circle   = theIO->Circle().Transformed( aFromLCS );
123   Plane    = theIO->GetPlane().Transformed( aFromLCS );
124   Flyout   = theIO->GetFlyout();
125   TextHPos = theIO->DimensionAspect()->TextHorizontalPosition();
126   TextVPos = theIO->DimensionAspect()->TextVerticalPosition();
127   ArrowPos = theIO->DimensionAspect()->ArrowOrientation();
128 }
129
130 //=================================================================================
131 // function : Diameter::Update
132 // purpose  : 
133 //=================================================================================
134 void GEOMGUI_DimensionProperty::Diameter::Update( Handle(AIS_DiameterDimension)& theIO, const gp_Ax3& theLCS )
135 {
136   gp_Trsf aToLCS;
137   aToLCS.SetTransformation( theLCS, gp_Ax3() );
138
139   gp_Circ aCircle = Circle.Transformed( aToLCS );
140   gp_Pln  aPlane  = Plane.Transformed( aToLCS );
141
142   Standard_Boolean isParallel = 
143     aCircle.Axis().Direction().IsParallel( aPlane.Axis().Direction(), Precision::Angular() );
144
145   if ( isParallel )
146   {
147     theIO->UnsetCustomPlane();
148     theIO->SetMeasuredGeometry( aCircle );
149   }
150   else
151   {
152     theIO->SetCustomPlane( aPlane );
153     theIO->SetMeasuredGeometry( aCircle );
154   }
155
156   theIO->SetFlyout( Flyout );
157
158   Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
159   aStyle->SetTextHorizontalPosition( TextHPos );
160   aStyle->SetTextVerticalPosition( TextVPos );
161   aStyle->SetArrowOrientation( ArrowPos );
162   theIO->SetDimensionAspect( aStyle );
163 }
164
165 //=================================================================================
166 // function : Diameter::operator == 
167 // purpose  : 
168 //=================================================================================
169 bool GEOMGUI_DimensionProperty::Diameter::operator == (const Diameter& theOther) const
170 {
171   if ( Circle.Location().X()  != theOther.Circle.Location().X()
172     || Circle.Location().Y()  != theOther.Circle.Location().Y()
173     || Circle.Location().Z()  != theOther.Circle.Location().Z()
174     || Circle.Axis().Direction().X() != theOther.Circle.Axis().Direction().X()
175     || Circle.Axis().Direction().Y() != theOther.Circle.Axis().Direction().Y()
176     || Circle.Axis().Direction().Z() != theOther.Circle.Axis().Direction().Z()
177     || Circle.XAxis().Direction().X() != theOther.Circle.XAxis().Direction().X()
178     || Circle.XAxis().Direction().Y() != theOther.Circle.XAxis().Direction().Y()
179     || Circle.XAxis().Direction().Z() != theOther.Circle.XAxis().Direction().Z() 
180     || Circle.Radius() != theOther.Circle.Radius() )
181   {
182     return false;
183   }
184
185   if ( Plane.Location().X() != theOther.Plane.Location().X()
186     || Plane.Location().Y() != theOther.Plane.Location().Y()
187     || Plane.Location().Z() != theOther.Plane.Location().Z()
188     || Plane.Axis().Direction().X() != theOther.Plane.Axis().Direction().X()
189     || Plane.Axis().Direction().Y() != theOther.Plane.Axis().Direction().Y()
190     || Plane.Axis().Direction().Z() != theOther.Plane.Axis().Direction().Z() )
191   {
192     return false;
193   }
194
195   if ( Flyout   != theOther.Flyout 
196     || TextHPos != theOther.TextHPos 
197     || TextVPos != theOther.TextVPos 
198     || ArrowPos != theOther.ArrowPos )
199   {
200     return false;
201   }
202
203   return true;
204 }
205
206 //=================================================================================
207 // function : Angle::Init
208 // purpose  : 
209 //=================================================================================
210 void GEOMGUI_DimensionProperty::Angle::Init( const Handle(AIS_AngleDimension)& theIO, const gp_Ax3& theLCS )
211 {
212   gp_Trsf aFromLCS;
213   aFromLCS.SetTransformation( gp_Ax3(), theLCS );
214
215   FirstPoint  = theIO->FirstPoint().Transformed( aFromLCS );
216   SecondPoint = theIO->SecondPoint().Transformed( aFromLCS );
217   CenterPoint = theIO->CenterPoint().Transformed( aFromLCS );
218   Flyout      = theIO->GetFlyout();
219   TextHPos    = theIO->DimensionAspect()->TextHorizontalPosition();
220   TextVPos    = theIO->DimensionAspect()->TextVerticalPosition();
221   ArrowPos    = theIO->DimensionAspect()->ArrowOrientation();
222 }
223
224 //=================================================================================
225 // function : Angle::Update
226 // purpose  : 
227 //=================================================================================
228 void GEOMGUI_DimensionProperty::Angle::Update( Handle(AIS_AngleDimension)& theIO, const gp_Ax3& theLCS )
229 {
230   gp_Trsf aToLCS;
231   aToLCS.SetTransformation( theLCS, gp_Ax3() );
232
233   gp_Pnt aPoint1 = FirstPoint.Transformed( aToLCS );
234   gp_Pnt aPoint2 = CenterPoint.Transformed( aToLCS );
235   gp_Pnt aPoint3 = SecondPoint.Transformed( aToLCS );
236
237   theIO->SetMeasuredGeometry( aPoint1, aPoint2, aPoint3 );
238   theIO->SetFlyout( Flyout );
239
240   Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
241   aStyle->SetTextHorizontalPosition( TextHPos );
242   aStyle->SetTextVerticalPosition( TextVPos );
243   aStyle->SetArrowOrientation( ArrowPos );
244   theIO->SetDimensionAspect( aStyle );
245 }
246
247 //=================================================================================
248 // function : Angle::operator == 
249 // purpose  : 
250 //=================================================================================
251 bool GEOMGUI_DimensionProperty::Angle::operator == (const Angle& theOther) const
252 {
253   if ( FirstPoint.X()  != theOther.FirstPoint.X()
254     || FirstPoint.Y()  != theOther.FirstPoint.Y()
255     || FirstPoint.Z()  != theOther.FirstPoint.Z()
256     || SecondPoint.X() != theOther.SecondPoint.X()
257     || SecondPoint.Y() != theOther.SecondPoint.Y()
258     || SecondPoint.Z() != theOther.SecondPoint.Z()
259     || CenterPoint.X() != theOther.CenterPoint.X()
260     || CenterPoint.Y() != theOther.CenterPoint.Y()
261     || CenterPoint.Z() != theOther.CenterPoint.Z() )
262   {
263     return false;
264   }
265
266   if ( Flyout   != theOther.Flyout 
267     || TextHPos != theOther.TextHPos 
268     || TextVPos != theOther.TextVPos 
269     || ArrowPos != theOther.ArrowPos )
270   {
271     return false;
272   }
273
274   return true;
275 }
276
277 //=================================================================================
278 // function : Constructor
279 // purpose  : 
280 //=================================================================================
281 GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty()
282 {
283 }
284
285 //=================================================================================
286 // function : Copy constructor
287 // purpose  : 
288 //=================================================================================
289 GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( const GEOMGUI_DimensionProperty& theOther )
290 {
291   const VectorOfVisibility& aOtherVis   = theOther.myVisibility;
292   const VectorOfNames& aOtherNames      = theOther.myNames;
293   const VectorOfRecords& aOtherRecords  = theOther.myRecords;
294
295   VectorOfVisibility::const_iterator aVisIt = aOtherVis.constBegin();
296   VectorOfNames::const_iterator   aNamesIt  = aOtherNames.constBegin();
297   VectorOfRecords::const_iterator aRecordIt = aOtherRecords.constBegin();
298   for ( ; aRecordIt != aOtherRecords.constEnd(); ++aVisIt, ++aNamesIt, ++aRecordIt )
299   {
300     RecordPtr aNewRecord;
301     const RecordPtr& aRecord = *aRecordIt;
302     switch( aRecord->Type() )
303     {
304       case DimensionType_Length :
305         aNewRecord = RecordPtr( new Length( *aRecord->AsLength() ) );
306         break;
307
308       case DimensionType_Diameter :
309         aNewRecord = RecordPtr( new Diameter( *aRecord->AsDiameter() ) );
310         break;
311
312       case DimensionType_Angle :
313         aNewRecord = RecordPtr( new Angle( *aRecord->AsAngle() ) );
314         break;
315     }
316
317     myVisibility.append( *aVisIt );
318     myNames.append( *aNamesIt );
319     myRecords.append( aNewRecord );
320   }
321 }
322
323 //=================================================================================
324 // function : Init constructor
325 // purpose  : 
326 //=================================================================================
327 GEOMGUI_DimensionProperty::GEOMGUI_DimensionProperty( SalomeApp_Study* theStudy, const std::string& theEntry )
328 {
329   LoadFromAttribute( theStudy, theEntry );
330 }
331
332 //=================================================================================
333 // function : Destructor
334 // purpose  : 
335 //=================================================================================
336 GEOMGUI_DimensionProperty::~GEOMGUI_DimensionProperty()
337 {
338 }
339
340 //=================================================================================
341 // function : operator QVariant()
342 // purpose  : 
343 //=================================================================================
344 GEOMGUI_DimensionProperty::operator QVariant()
345 {
346   QVariant aQVariant;
347   aQVariant.setValue( *this );
348   return aQVariant;
349 }
350
351 //=================================================================================
352 // function : operator ==
353 // purpose  : 
354 //=================================================================================
355 bool GEOMGUI_DimensionProperty::operator == (const GEOMGUI_DimensionProperty& theOther) const
356 {
357   if ( myVisibility.size() != theOther.myVisibility.size()
358     || myNames.size() != theOther.myNames.size()
359     || myRecords.size() != theOther.myRecords.size() )
360   {
361     return false;
362   }
363
364   for ( int it = 0; it < myRecords.size(); ++it )
365   {
366     if ( myVisibility[it] != theOther.myVisibility[it] )
367     {
368       return false;
369     }
370
371     if ( myNames[it] != theOther.myNames[it] )
372     {
373       return false;
374     }
375
376     const RecordPtr& aRecord = myRecords[it];
377     const RecordPtr& aOtherRecord = theOther.myRecords[it];
378     if ( aRecord->Type() != aOtherRecord->Type() )
379     {
380       return false;
381     }
382
383     switch ( aRecord->Type() )
384     {
385       case DimensionType_Length:
386         if ( (*aRecord->AsLength()) != (*aOtherRecord->AsLength()) )
387         {
388           return false;
389         }
390         break;
391
392       case DimensionType_Diameter:
393         if ( (*aRecord->AsDiameter()) != (*aOtherRecord->AsDiameter()) )
394         {
395           return false;
396         }
397         break;
398
399       case DimensionType_Angle:
400         if ( (*aRecord->AsAngle()) != (*aOtherRecord->AsAngle()) )
401         {
402           return false;
403         }
404         break;
405     }
406   }
407
408   return true;
409 }
410
411 //=================================================================================
412 // function : GetNumber
413 // purpose  : 
414 //=================================================================================
415 int GEOMGUI_DimensionProperty::GetNumber() const
416 {
417   return myRecords.size();
418 }
419
420 //=================================================================================
421 // function : AddRecord
422 // purpose  : 
423 //=================================================================================
424 void GEOMGUI_DimensionProperty::AddRecord( const Handle(AIS_Dimension)& theIO, const gp_Ax3& theLCS )
425 {
426   RecordPtr aNewRecord;
427
428   int aType = TypeFromIO( theIO );
429
430   switch ( aType )
431   {
432     case DimensionType_Length :
433     {
434       Handle(AIS_LengthDimension) aLength = 
435         Handle(AIS_LengthDimension)::DownCast( theIO );
436
437       aNewRecord = RecordPtr( new Length() );
438       aNewRecord->AsLength()->Init( aLength, theLCS );
439       break;
440     }
441
442     case DimensionType_Diameter :
443     {
444       Handle(AIS_DiameterDimension) aDiam =
445         Handle(AIS_DiameterDimension)::DownCast( theIO );
446
447       aNewRecord = RecordPtr( new Diameter() );
448       aNewRecord->AsDiameter()->Init( aDiam, theLCS );
449       break;
450     }
451
452     case DimensionType_Angle :
453     {
454       Handle(AIS_AngleDimension) anAngle =
455         Handle(AIS_AngleDimension)::DownCast( theIO );
456
457       aNewRecord = RecordPtr( new Angle() );
458       aNewRecord->AsAngle()->Init( anAngle, theLCS );
459     }
460   }
461
462   myVisibility.append( true );
463   myNames.append( QString() );
464   myRecords.append( aNewRecord );
465 }
466
467 //=================================================================================
468 // function : AddRecord
469 // purpose  : 
470 //=================================================================================
471 void GEOMGUI_DimensionProperty::AddRecord( const RecordPtr& theRecord )
472 {
473   myVisibility.append( true );
474   myNames.append( QString() );
475   myRecords.append( theRecord );
476 }
477
478 //=================================================================================
479 // function : RemoveRecord
480 // purpose  : 
481 //=================================================================================
482 void GEOMGUI_DimensionProperty::RemoveRecord( const int theIndex )
483 {
484   myNames.remove( theIndex );
485   myVisibility.remove( theIndex );
486   myRecords.remove( theIndex );
487 }
488
489 //=================================================================================
490 // function : Clear
491 // purpose  : 
492 //=================================================================================
493 void GEOMGUI_DimensionProperty::Clear()
494 {
495   myNames.clear();
496   myVisibility.clear();
497   myRecords.clear();
498 }
499
500 //=================================================================================
501 // function : SetRecord
502 // purpose  : 
503 //=================================================================================
504 void GEOMGUI_DimensionProperty::SetRecord( const int theIndex,
505                                            const Handle(AIS_Dimension)& theIO,
506                                            const gp_Ax3& theLCS )
507 {
508   int aType = TypeFromIO( theIO );
509
510   RecordPtr& aChangeRecord = myRecords[theIndex];
511
512   switch ( aType )
513   {
514     case DimensionType_Length :
515     {
516       Handle(AIS_LengthDimension) aLength = 
517         Handle(AIS_LengthDimension)::DownCast( theIO );
518
519       aChangeRecord = RecordPtr( new Length() );
520       aChangeRecord->AsLength()->Init( aLength, theLCS );
521       break;
522     }
523
524     case DimensionType_Diameter :
525     {
526       Handle(AIS_DiameterDimension) aDiam =
527         Handle(AIS_DiameterDimension)::DownCast( theIO );
528
529       aChangeRecord = RecordPtr( new Diameter() );
530       aChangeRecord->AsDiameter()->Init( aDiam, theLCS );
531       break;
532     }
533
534     case DimensionType_Angle :
535     {
536       Handle(AIS_AngleDimension) anAngle =
537         Handle(AIS_AngleDimension)::DownCast( theIO );
538
539       aChangeRecord = RecordPtr( new Angle() );
540       aChangeRecord->AsAngle()->Init( anAngle, theLCS );
541     }
542   }
543 }
544
545 //=================================================================================
546 // function : SetRecord
547 // purpose  : 
548 //=================================================================================
549 void GEOMGUI_DimensionProperty::SetRecord( const int theIndex, const RecordPtr& theRecord )
550 {
551   myRecords[theIndex] = theRecord;
552 }
553
554 //=================================================================================
555 // function : GetRecord
556 // purpose  : 
557 //=================================================================================
558 const GEOMGUI_DimensionProperty::RecordPtr& GEOMGUI_DimensionProperty::GetRecord( const int theIndex ) const
559 {
560   return myRecords[theIndex];
561 }
562
563 //=================================================================================
564 // function : IsVisible
565 // purpose  : 
566 //=================================================================================
567 bool GEOMGUI_DimensionProperty::IsVisible( const int theIndex ) const
568 {
569   return myVisibility[theIndex];
570 }
571
572 //=================================================================================
573 // function : SetVisible
574 // purpose  : 
575 //=================================================================================
576 void GEOMGUI_DimensionProperty::SetVisible( const int theIndex, const bool theIsVisible )
577 {
578   myVisibility[theIndex] = theIsVisible;
579 }
580
581 //=================================================================================
582 // function : GetName
583 // purpose  : 
584 //=================================================================================
585 QString GEOMGUI_DimensionProperty::GetName( const int theIndex ) const
586 {
587   return myNames[theIndex];
588 }
589
590 //=================================================================================
591 // function : SetName
592 // purpose  : 
593 //=================================================================================
594 void GEOMGUI_DimensionProperty::SetName( const int theIndex, const QString &theName )
595 {
596   myNames[theIndex] = theName;
597 }
598
599 //=================================================================================
600 // function : GetType
601 // purpose  : 
602 //=================================================================================
603 int GEOMGUI_DimensionProperty::GetType( const int theIndex ) const
604 {
605   return myRecords[theIndex]->Type();
606 }
607
608 //=================================================================================
609 // function : LoadFromAttribute
610 // purpose  : 
611 //=================================================================================
612 void GEOMGUI_DimensionProperty::LoadFromAttribute( SalomeApp_Study* theStudy,
613                                                    const std::string& theEntry )
614 {
615   Clear();
616
617   _PTR(SObject) aSObj = theStudy->studyDS()->FindObjectID( theEntry );
618   if ( !aSObj )
619   {
620     return;
621   }
622
623   _PTR(StudyBuilder) aBuilder = theStudy->studyDS()->NewBuilder();
624
625   _PTR(GenericAttribute) aSeekAtt;
626   _PTR(AttributeTableOfReal) aRecordsAtt;
627
628   if ( !aSObj->FindAttribute( aSeekAtt, "AttributeTableOfReal" ) )
629   {
630     return;
631   }
632
633   aRecordsAtt = aSeekAtt;
634
635   for ( int aRecordIt = 1; aRecordIt <= aRecordsAtt->GetNbColumns(); ++aRecordIt )
636   {
637     std::vector<double> aPacked = aRecordsAtt->GetColumn( aRecordIt );
638
639     RecordPtr aRecord;
640
641     QString aName( aRecordsAtt->GetColumnTitle( aRecordIt ).c_str() );
642
643     // unpack records
644     int it = 0;
645
646     // visibility [0]
647     bool isVisible = (bool) aPacked[it++];
648
649     // type [1]
650     int aType = (int) aPacked[it++];
651
652     switch (aType)
653     {
654       case DimensionType_Length :
655       {
656         Length* aLength = new Length;
657
658         // custom plane [2,3,4,5]
659         Standard_Real A = (Standard_Real) aPacked[it++];
660         Standard_Real B = (Standard_Real) aPacked[it++];
661         Standard_Real C = (Standard_Real) aPacked[it++];
662         Standard_Real D = (Standard_Real) aPacked[it++];
663         aLength->Plane = gp_Pln( A, B, C, D );
664
665         // flyout size [6]
666         aLength->Flyout = (Standard_Real) aPacked[it++];
667
668         // text flags [7,8]
669         aLength->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
670         aLength->TextVPos = (Prs3d_DimensionTextVerticalPosition)  (int)aPacked[it++];
671
672         // arrow flags [9]
673         aLength->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
674
675         // point 1 [10,11,12]
676         Standard_Real aFirstX = aPacked[it++];
677         Standard_Real aFirstY = aPacked[it++];
678         Standard_Real aFirstZ = aPacked[it++];
679         aLength->FirstPoint = gp_Pnt( aFirstX, aFirstY, aFirstZ );
680
681         // point 2 [13,14,15]
682         Standard_Real aSecondX = aPacked[it++];
683         Standard_Real aSecondY = aPacked[it++];
684         Standard_Real aSecondZ = aPacked[it++];
685         aLength->SecondPoint = gp_Pnt( aSecondX, aSecondY, aSecondZ );
686
687         aRecord = RecordPtr( aLength );
688         break;
689       }
690
691       case DimensionType_Diameter :
692       {
693         Diameter* aDiam = new Diameter;
694
695         // custom plane [2,3,4,5]
696         Standard_Real A = (Standard_Real) aPacked[it++];
697         Standard_Real B = (Standard_Real) aPacked[it++];
698         Standard_Real C = (Standard_Real) aPacked[it++];
699         Standard_Real D = (Standard_Real) aPacked[it++];
700         aDiam->Plane = gp_Pln( A, B, C, D );
701
702         // flyout size [6]
703         aDiam->Flyout = (Standard_Real) aPacked[it++];
704
705         // text flags [7,8]
706         aDiam->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
707         aDiam->TextVPos = (Prs3d_DimensionTextVerticalPosition)  (int)aPacked[it++];
708
709         // arrow flags [9]
710         aDiam->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
711
712         // circle location [10,11,12]
713         Standard_Real aLocX = (Standard_Real) aPacked[it++];
714         Standard_Real aLocY = (Standard_Real) aPacked[it++];
715         Standard_Real aLocZ = (Standard_Real) aPacked[it++];
716
717         // circle normal [13,14,15]
718         Standard_Real aNormX = (Standard_Real) aPacked[it++];
719         Standard_Real aNormY = (Standard_Real) aPacked[it++];
720         Standard_Real aNormZ = (Standard_Real) aPacked[it++];
721
722         // x-direction [16,17,18]
723         Standard_Real aXDirX = (Standard_Real) aPacked[it++];
724         Standard_Real aXDirY = (Standard_Real) aPacked[it++];
725         Standard_Real aXDirZ = (Standard_Real) aPacked[it++];
726
727         // radius [19]
728         Standard_Real aRadius = (Standard_Real) aPacked[it++];
729
730         gp_Ax2 anAx( gp_Pnt( aLocX, aLocY, aLocZ ),
731                      gp_Dir( aNormX, aNormY, aNormZ ),
732                      gp_Dir( aXDirX, aXDirY, aXDirZ ) );
733
734         aDiam->Circle = gp_Circ( anAx, aRadius );
735
736         aRecord = RecordPtr( aDiam );
737         break;
738       }
739
740       case DimensionType_Angle :
741       {
742         Angle* anAngle = new Angle;
743
744         // flyout [2]
745         anAngle->Flyout = (Standard_Real) aPacked[it++];
746
747         // text flags [3,4]
748         anAngle->TextHPos = (Prs3d_DimensionTextHorizontalPosition)(int)aPacked[it++];
749         anAngle->TextVPos = (Prs3d_DimensionTextVerticalPosition)  (int)aPacked[it++];
750
751         // arrow flags [5]
752         anAngle->ArrowPos = (Prs3d_DimensionArrowOrientation) (int)aPacked[it++];
753
754         // point 1 [6,7,8]
755         Standard_Real aFirstX = (Standard_Real) aPacked[it++];
756         Standard_Real aFirstY = (Standard_Real) aPacked[it++];
757         Standard_Real aFirstZ = (Standard_Real) aPacked[it++];
758
759         // point 2 [9,10,11]
760         Standard_Real aSecondX = (Standard_Real) aPacked[it++];
761         Standard_Real aSecondY = (Standard_Real) aPacked[it++];
762         Standard_Real aSecondZ = (Standard_Real) aPacked[it++];
763
764         // center [12,13,14]
765         Standard_Real aCenterX = (Standard_Real) aPacked[it++];
766         Standard_Real aCenterY = (Standard_Real) aPacked[it++];
767         Standard_Real aCenterZ = (Standard_Real) aPacked[it++];
768
769         anAngle->FirstPoint  = gp_Pnt( aFirstX, aFirstY, aFirstZ );
770         anAngle->SecondPoint = gp_Pnt( aSecondX, aSecondY, aSecondZ );
771         anAngle->CenterPoint = gp_Pnt( aCenterX, aCenterY, aCenterZ );
772
773         aRecord = RecordPtr( anAngle );
774         break;
775       }
776     }
777
778     myVisibility.append( isVisible );
779     myNames.append( aName );
780     myRecords.append( aRecord );
781   }
782 }
783
784 //=================================================================================
785 // function : SaveToAttribute
786 // purpose  : 
787 //=================================================================================
788 void GEOMGUI_DimensionProperty::SaveToAttribute( SalomeApp_Study *theStudy,
789                                                  const std::string &theEntry )
790 {
791   _PTR(SObject) aSObj = theStudy->studyDS()->FindObjectID( theEntry );
792   if ( !aSObj )
793   {
794     return;
795   }
796
797   _PTR(StudyBuilder) aBuilder = theStudy->studyDS()->NewBuilder();
798
799   _PTR(AttributeTableOfReal) aRecordsAtt;
800
801   aRecordsAtt = aBuilder->FindOrCreateAttribute( aSObj, "AttributeTableOfReal" );
802   aRecordsAtt->SetNbColumns( 0 );
803
804   for ( int it = 0; it < myRecords.size(); ++it )
805   {
806     bool aVisibility   = myVisibility[it];
807     QString& aName     = myNames[it];
808     RecordPtr& aRecord = myRecords[it];
809
810     std::vector<double> aPacked;
811
812     // visibility [0]
813     aPacked.push_back( (double) aVisibility );
814
815     // type [1]
816     aPacked.push_back( (double) aRecord->Type() );
817
818     switch ( aRecord->Type() )
819     {
820       case DimensionType_Length:
821       {
822         Length* aProps = aRecord->AsLength();
823
824         // custom plane [2,3,4,5]
825         Standard_Real A, B, C, D;
826         aProps->Plane.Coefficients( A, B, C, D );
827         aPacked.push_back( (double) A );
828         aPacked.push_back( (double) B );
829         aPacked.push_back( (double) C );
830         aPacked.push_back( (double) D );
831
832         // flyout size [6]
833         aPacked.push_back( (double) aProps->Flyout );
834
835         // text flags [7,8]
836         aPacked.push_back( (double) aProps->TextHPos );
837         aPacked.push_back( (double) aProps->TextVPos );
838
839         // arrow flags [9]
840         aPacked.push_back( (double) aProps->ArrowPos );
841
842         // point 1 [10,11,12]
843         aPacked.push_back( (double) aProps->FirstPoint.X() );
844         aPacked.push_back( (double) aProps->FirstPoint.Y() );
845         aPacked.push_back( (double) aProps->FirstPoint.Z() );
846
847         // point 2 [13,14,15]
848         aPacked.push_back( (double) aProps->SecondPoint.X() );
849         aPacked.push_back( (double) aProps->SecondPoint.Y() );
850         aPacked.push_back( (double) aProps->SecondPoint.Z() );
851         break;
852       }
853
854       case DimensionType_Diameter:
855       {
856         Diameter* aProps = aRecord->AsDiameter();
857
858         // custom plane [2,3,4,5]
859         Standard_Real A, B, C, D;
860         aProps->Plane.Coefficients( A, B, C, D );
861         aPacked.push_back( (double) A );
862         aPacked.push_back( (double) B );
863         aPacked.push_back( (double) C );
864         aPacked.push_back( (double) D );
865
866         // flyout size [6]
867         aPacked.push_back( (double) aProps->Flyout );
868
869         // text flags [7,8]
870         aPacked.push_back( (double) aProps->TextHPos );
871         aPacked.push_back( (double) aProps->TextVPos );
872
873         // arrow flags [9]
874         aPacked.push_back( (double) aProps->ArrowPos );
875
876         // circle location [10,11,12]
877         aPacked.push_back( (double) aProps->Circle.Location().X() );
878         aPacked.push_back( (double) aProps->Circle.Location().Y() );
879         aPacked.push_back( (double) aProps->Circle.Location().Z() );
880
881         // circle normal [13,14,15]
882         aPacked.push_back( (double) aProps->Circle.Axis().Direction().X() );
883         aPacked.push_back( (double) aProps->Circle.Axis().Direction().Y() );
884         aPacked.push_back( (double) aProps->Circle.Axis().Direction().Z() );
885
886         // x-direction [16,17,18]
887         aPacked.push_back( (double) aProps->Circle.XAxis().Direction().X() );
888         aPacked.push_back( (double) aProps->Circle.XAxis().Direction().Y() );
889         aPacked.push_back( (double) aProps->Circle.XAxis().Direction().Z() );
890
891         // radius [19]
892         aPacked.push_back( (double) aProps->Circle.Radius() );
893         break;
894       }
895
896       case DimensionType_Angle:
897       {
898         Angle* aProps = aRecord->AsAngle();
899
900         // flyout [2]
901         aPacked.push_back( (double) aProps->Flyout );
902
903         // text flags [3,4]
904         aPacked.push_back( (double) aProps->TextHPos );
905         aPacked.push_back( (double) aProps->TextVPos );
906
907         // arrow flags [5]
908         aPacked.push_back( (double) aProps->ArrowPos );
909
910         // point 1 [6,7,8]
911         aPacked.push_back( (double) aProps->FirstPoint.X() );
912         aPacked.push_back( (double) aProps->FirstPoint.Y() );
913         aPacked.push_back( (double) aProps->FirstPoint.Z() );
914
915         // point 2 [9,10,11]
916         aPacked.push_back( (double) aProps->SecondPoint.X() );
917         aPacked.push_back( (double) aProps->SecondPoint.Y() );
918         aPacked.push_back( (double) aProps->SecondPoint.Z() );
919
920         // center [12,13,14]
921         aPacked.push_back( (double) aProps->CenterPoint.X() );
922         aPacked.push_back( (double) aProps->CenterPoint.Y() );
923         aPacked.push_back( (double) aProps->CenterPoint.Z() );
924         break;
925       }
926     }
927
928     aRecordsAtt->AddColumn( aPacked );
929     aRecordsAtt->SetColumnTitle( it + 1, aName.toStdString() );
930   }
931 }
932
933 //=================================================================================
934 // function : TypeFromIO
935 // purpose  : 
936 //=================================================================================
937 int GEOMGUI_DimensionProperty::TypeFromIO( const Handle(AIS_Dimension)& theIO ) const
938 {
939   if ( theIO->IsKind( STANDARD_TYPE( AIS_LengthDimension ) ) )
940   {
941     return DimensionType_Length;
942   }
943
944   if ( theIO->IsKind( STANDARD_TYPE( AIS_DiameterDimension ) ) )
945   {
946     return DimensionType_Diameter;
947   }
948
949   if ( theIO->IsKind( STANDARD_TYPE( AIS_AngleDimension ) ) )
950   {
951     return DimensionType_Angle;
952   }
953
954   Standard_ProgramError::Raise( "unsupported dimension type" );
955
956   return 0;
957 }