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