0024133: Development of improvement of dimensions implementation; new length, radius...
[occt.git] / src / AIS / AIS_DiameterDimension.cxx
1 // Created on: 1996-12-05
2 // Created by: Jacques MINOT/Odile Olivier/Sergey ZARITCHNY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // Modified     Mon 12-january-98
22 //              <ODL>, <SZY>
23
24
25 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
26 //                      if any in all dimensions.
27 #include <AIS_DiameterDimension.hxx>
28
29 #include <Adaptor3d_HCurve.hxx>
30 #include <AIS.hxx>
31 #include <AIS_Drawer.hxx>
32 #include <AIS_DimensionOwner.hxx>
33 #include <DsgPrs_DiameterPresentation.hxx>
34 #include <DsgPrs_RadiusPresentation.hxx>
35 #include <ElCLib.hxx>
36 #include <ElSLib.hxx>
37 #include <GC_MakeCircle.hxx>
38 #include <gce_MakeDir.hxx>
39 #include <Geom_Plane.hxx>
40 #include <gp_Pln.hxx>
41 #include <gp_Pnt.hxx>
42 #include <gp_Lin.hxx>
43 #include <gp_Ax1.hxx>
44 #include <gp_Dir.hxx>
45 #include <gp_Vec.hxx>
46 #include <Graphic3d_ArrayOfSegments.hxx>
47 #include <Graphic3d_Group.hxx>
48 #include <PrsMgr_PresentationManager3d.hxx>
49 #include <Prs3d_DimensionAspect.hxx>
50 #include <Prs3d_ArrowAspect.hxx>
51 #include <Prs3d_Drawer.hxx>
52 #include <Prs3d_TextAspect.hxx>
53 #include <Prs3d_Text.hxx>
54 #include <Prs3d_Root.hxx>
55 #include <Precision.hxx>
56 #include <Select3D_SensitiveSegment.hxx>
57 #include <Select3D_SensitiveBox.hxx>
58 #include <SelectMgr_EntityOwner.hxx>
59 #include <Standard_Macro.hxx>
60 #include <TopoDS.hxx>
61 #include <TopoDS_Shape.hxx>
62 #include <TCollection_ExtendedString.hxx>
63
64 IMPLEMENT_STANDARD_HANDLE(AIS_DiameterDimension, AIS_Dimension)
65 IMPLEMENT_STANDARD_RTTIEXT(AIS_DiameterDimension, AIS_Dimension)
66
67 //=======================================================================
68 //function : Constructor
69 //purpose  : 
70 //=======================================================================
71
72 AIS_DiameterDimension::AIS_DiameterDimension(const gp_Circ& theCircle)
73 : AIS_Dimension(),
74   myFlyout (0.0),
75   myCircle (theCircle)
76 {
77   SetKindOfDimension(AIS_KOD_DIAMETER);
78   myIsInitialized = Standard_True;
79   SetSpecialSymbol (0x00D8);
80   SetDisplaySpecialSymbol (AIS_DSS_Before);
81   // Count attach points
82   myFirstPoint = ElCLib::Value (0, myCircle);
83   mySecondPoint = myFirstPoint.Translated (gp_Vec(myFirstPoint, theCircle.Location())*2);
84 }
85
86 //=======================================================================
87 //function : Constructor
88 //purpose  : 
89 //=======================================================================
90
91 AIS_DiameterDimension::AIS_DiameterDimension(const gp_Circ& theCircle, const gp_Pnt& theAttachPoint)
92 : AIS_Dimension(),
93   myFlyout (0.0),
94   myCircle (theCircle)
95 {
96   SetKindOfDimension(AIS_KOD_DIAMETER);
97   SetSpecialSymbol (0x00D8);
98   SetDisplaySpecialSymbol (AIS_DSS_Before);
99   myFirstPoint = theAttachPoint;
100   // Count the second point
101   if (Abs(myFirstPoint.Distance (theCircle.Location()) - theCircle.Radius()) < Precision::Confusion())
102   {
103     mySecondPoint = myFirstPoint.Translated(gp_Vec(myFirstPoint, theCircle.Location())*2);
104   }
105   else
106   {
107     myFirstPoint = ElCLib::Value(0, myCircle);
108     mySecondPoint = myFirstPoint.Translated(gp_Vec(myFirstPoint, theCircle.Location())*2);
109   }
110   myIsInitialized = Standard_True;
111 }
112
113 //=======================================================================
114 //function : Constructor
115 //purpose  : 
116 //=======================================================================
117
118 AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
119                                               const Handle(Prs3d_DimensionAspect)& theDimensionStyle,
120                                               const Standard_Real theExtensionSize /*= 1.0*/)
121 : AIS_Dimension (theExtensionSize),
122   myFlyout (0.0),
123   myCircle (theCircle)
124 {
125   SetKindOfDimension(AIS_KOD_DIAMETER);
126   SetSpecialSymbol (0x00D8);
127   SetDisplaySpecialSymbol(AIS_DSS_Before);
128   myDrawer->SetDimensionAspect(theDimensionStyle);
129   myIsInitialized = Standard_True;
130 }
131
132 //=======================================================================
133 //function : Constructor
134 //purpose  : Universal constructor for diameter dimension of shape
135 //=======================================================================
136
137 AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape)
138 : AIS_Dimension (),
139   myFlyout (0.)
140 {
141   SetKindOfDimension(AIS_KOD_DIAMETER);
142   SetSpecialSymbol (0x00D8);
143   SetDisplaySpecialSymbol(AIS_DSS_Before);
144   myFirstShape = theShape;
145   myIsInitialized = Standard_False;
146 }
147
148 //=======================================================================
149 //function : Compute
150 //purpose  : 
151 //=======================================================================
152
153 void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
154                                      const Handle(Prs3d_Presentation)& thePresentation, 
155                                      const Standard_Integer theMode)
156 {
157   thePresentation->Clear();
158
159   Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
160   Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
161
162   if (!myIsInitialized)
163   {
164     if (!initCircularDimension (myFirstShape, myCircle,
165                                myFirstPoint, mySecondPoint))
166       return;
167     else
168       myIsInitialized = Standard_True;
169   }
170   if (!myIsWorkingPlaneCustom)
171    countDefaultPlane();
172
173   //Count flyout direction
174   gp_Ax1 aWorkingPlaneNormal = GetWorkingPlane().Axis();
175   gp_Dir aTargetPointsVector = gce_MakeDir (myFirstPoint, mySecondPoint);
176   // Count a flyout direction vector.
177   gp_Dir aFlyoutVector = aWorkingPlaneNormal.Direction()^aTargetPointsVector;
178   gp_Ax3 aLocalSystem (myFirstPoint, aTargetPointsVector, aFlyoutVector);
179
180   // Create lines for layouts
181   gp_Lin aLine1 (myFirstPoint, aFlyoutVector);
182   gp_Lin aLine2 (mySecondPoint, aFlyoutVector);
183
184   // Get flyout end points
185   gp_Pnt aFlyoutEnd1 = ElCLib::Value (ElCLib::Parameter (aLine1, myFirstPoint) + GetFlyout(), aLine1);
186   gp_Pnt aFlyoutEnd2 = ElCLib::Value (ElCLib::Parameter (aLine2, mySecondPoint) + GetFlyout(), aLine2);
187
188     // Add layout lines to graphic group
189   // Common to all type of dimension placement.
190   if (theMode == 0)
191   {
192     Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments(4);
193     aPrimSegments->AddVertex (myFirstPoint);
194     aPrimSegments->AddVertex (aFlyoutEnd1);
195
196     aPrimSegments->AddVertex (mySecondPoint);
197     aPrimSegments->AddVertex (aFlyoutEnd2);
198
199     Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
200   }
201
202   drawLinearDimension (thePresentation, aFlyoutEnd1, aFlyoutEnd2, (AIS_DimensionDisplayMode)theMode);
203 }
204
205 //=======================================================================
206 //function : computeValue
207 //purpose  : 
208 //=======================================================================
209
210 void AIS_DiameterDimension::computeValue ()
211 {
212   myValue = myFirstPoint.Distance (mySecondPoint);
213   AIS_Dimension::computeValue();
214 }
215
216 //=======================================================================
217 //function : countDefaultPlane
218 //purpose  : 
219 //=======================================================================
220
221 void AIS_DiameterDimension::countDefaultPlane ()
222 {
223   // Compute normal of the default plane.
224   //gp_Vec aVec1(mySecondPoint, myFirstPoint),
225   //       aVec2(mySecondPoint, ElCLib::Value(M_PI_2, myCircle));
226   myDefaultPlane = gp_Pln(gp_Ax3(myCircle.Position()));
227   // Set computed value to <myWorkingPlane>
228   ResetWorkingPlane ();
229 }
230
231 //=======================================================================
232 //function : SetFlyout
233 //purpose  : 
234 //=======================================================================
235
236 void AIS_DiameterDimension::SetFlyout (const Standard_Real theFlyout)
237 {
238   myFlyout = theFlyout;
239 }
240
241 //=======================================================================
242 //function : GetFlyout
243 //purpose  : 
244 //=======================================================================
245
246 Standard_Real AIS_DiameterDimension::GetFlyout () const
247 {
248   return myFlyout;
249 }