Salome HOME
Merge branch 'master' of newgeom:newgeom.git
[modules/shaper.git] / src / GeomAPI / GeomAPI_AISObject.cpp
1 // File:        GeomAPI_AISObject.cpp
2 // Created:     25 Jun 2014
3 // Author:      Artem ZHIDKOV
4
5 #include <GeomAPI_AISObject.h>
6
7 #include <GeomAPI_Circ.h>
8 #include <GeomAPI_Dir.h>
9 #include <GeomAPI_Lin.h>
10 #include <GeomAPI_Pln.h>
11 #include <GeomAPI_Pnt.h>
12 #include <GeomAPI_Shape.h>
13 #include <GeomAPI_XYZ.h>
14
15 #include <Geom_Plane.hxx>
16 #include <TopoDS_Shape.hxx>
17 #include <Quantity_NameOfColor.hxx>
18
19 #include <AIS_InteractiveObject.hxx>
20 #include <AIS_LengthDimension.hxx>
21 #include <AIS_ParallelRelation.hxx>
22 #include <AIS_PerpendicularRelation.hxx>
23 #include <AIS_RadiusDimension.hxx>
24 #include <AIS_Shape.hxx>
25
26
27 const int CONSTRAINT_TEXT_HEIGHT = 28; /// the text height of the constraint
28 const int CONSTRAINT_TEXT_SELECTION_TOLERANCE = 20; /// the text selection tolerance
29
30 // Initialization of color constants
31 int Colors::COLOR_BROWN = Quantity_NOC_BROWN;
32 int Colors::COLOR_RED = Quantity_NOC_RED;
33 int Colors::COLOR_GREEN = Quantity_NOC_GREEN;
34 int Colors::COLOR_BLUE = Quantity_NOC_BLUE1;
35
36
37 GeomAPI_AISObject::GeomAPI_AISObject()
38   : GeomAPI_Interface(new Handle(AIS_InteractiveObject)())
39 {
40 }
41
42 void GeomAPI_AISObject::createShape(boost::shared_ptr<GeomAPI_Shape> theShape)
43 {
44   const TopoDS_Shape& aTDS = (theShape && theShape->implPtr<TopoDS_Shape>()) ?
45                              theShape->impl<TopoDS_Shape>() : TopoDS_Shape();
46
47   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
48   if (!anAIS.IsNull())
49   {
50     Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
51     if (aShapeAIS)
52     {
53       // if the AIS object is displayed in the opened local context in some mode, additional
54       // AIS sub objects are created there. They should be rebuild for correct selecting.
55       // It is possible to correct it by closing local context before the shape set and opening
56       // after. Another workaround to thrown down the selection and reselecting the AIS.
57       // If there was a problem here, try the first solution with close/open local context.
58
59       aShapeAIS->Set(aTDS);
60       aShapeAIS->Redisplay(Standard_True);
61     }
62   }
63   else
64     setImpl(new Handle(AIS_InteractiveObject)(new AIS_Shape(aTDS)));
65 }
66
67
68 void GeomAPI_AISObject::createDistance(boost::shared_ptr<GeomAPI_Pnt> theStartPoint,
69                                        boost::shared_ptr<GeomAPI_Pnt> theEndPoint,
70                                        boost::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
71                                        boost::shared_ptr<GeomAPI_Pln> thePlane,
72                                        double                         theDistance)
73 {
74   double aFlyout = 0;
75   if (theFlyoutPoint)
76   {
77     boost::shared_ptr<GeomAPI_Lin> aLine = 
78       boost::shared_ptr<GeomAPI_Lin>(new GeomAPI_Lin(theStartPoint, theEndPoint));
79     double aDist = aLine->distance(theFlyoutPoint);
80
81     boost::shared_ptr<GeomAPI_XYZ> aLineDir = theEndPoint->xyz()->decreased(theStartPoint->xyz());
82     boost::shared_ptr<GeomAPI_XYZ> aFOutDir = theFlyoutPoint->xyz()->decreased(theStartPoint->xyz());
83     boost::shared_ptr<GeomAPI_XYZ> aNorm = thePlane->direction()->xyz();
84     if (aLineDir->cross(aFOutDir)->dot(aNorm) < 0)
85       aDist = -aDist;
86     aFlyout = aDist;
87   }
88
89   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
90   if (anAIS.IsNull())
91   {
92     Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(
93       theStartPoint->impl<gp_Pnt>(), theEndPoint->impl<gp_Pnt>(), thePlane->impl<gp_Pln>());
94     aDimAIS->SetCustomValue(theDistance);
95
96     Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
97     anAspect->MakeArrows3d (Standard_False);
98     anAspect->MakeText3d(false);
99     anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
100     anAspect->MakeTextShaded(false);
101     aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
102     aDimAIS->SetDimensionAspect(anAspect);
103     aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
104     aDimAIS->SetFlyout(aFlyout);
105
106     setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
107   }
108   else {
109     // update presentation
110     Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
111     if (!aDimAIS.IsNull()) {
112       aDimAIS->SetMeasuredGeometry(theStartPoint->impl<gp_Pnt>(), theEndPoint->impl<gp_Pnt>(), 
113                                    thePlane->impl<gp_Pln>());
114       aDimAIS->SetCustomValue(theDistance);
115       aDimAIS->SetFlyout(aFlyout);
116
117       aDimAIS->Redisplay(Standard_True);
118     }
119   }
120 }
121
122 void GeomAPI_AISObject::createRadius(boost::shared_ptr<GeomAPI_Circ> theCircle,
123                                      boost::shared_ptr<GeomAPI_Pnt>  theFlyoutPoint,
124                                      double                          theRadius)
125 {
126   boost::shared_ptr<GeomAPI_Pnt> aCenter = theCircle->center();
127
128   // TODO: a bug in AIS_RadiusDimension:
129   // The anchor point can't be myCirc.Location() - an exception is raised.
130   // But we need exactly this case...
131   // We want to show a radius dimension starting from the circle centre and 
132   // ending at the user-defined point.
133   // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
134   boost::shared_ptr<GeomAPI_Pnt> anAnchor = theCircle->project(theFlyoutPoint);
135   boost::shared_ptr<GeomAPI_XYZ> anAnchorXYZ = anAnchor->xyz();
136   anAnchorXYZ = anAnchorXYZ->decreased(aCenter->xyz());
137   boost::shared_ptr<GeomAPI_Dir> aDeltaDir(new GeomAPI_Dir(anAnchorXYZ));
138   const double aDelta = 1e-3;
139   anAnchor->setX(anAnchor->x() + aDelta * aDeltaDir->x());
140   anAnchor->setY(anAnchor->y() + aDelta * aDeltaDir->y());
141   anAnchor->setZ(anAnchor->z() + aDelta * aDeltaDir->z());
142
143   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
144   if (anAIS.IsNull())
145   {
146     Handle(AIS_RadiusDimension) aDimAIS = 
147       new AIS_RadiusDimension(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
148     aDimAIS->SetCustomValue(theRadius);
149
150     Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
151     anAspect->MakeArrows3d (Standard_False);
152     anAspect->MakeText3d(false);
153     anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
154     anAspect->MakeTextShaded(false);
155     aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
156     aDimAIS->SetDimensionAspect (anAspect);
157     aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
158
159     setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
160   }
161   else
162   {
163     // update presentation
164     Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
165     if (!aDimAIS.IsNull())
166     {
167       aDimAIS->SetMeasuredGeometry(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
168       aDimAIS->SetCustomValue(theRadius);
169       aDimAIS->Redisplay(Standard_True);
170     }
171   }
172 }
173
174 void GeomAPI_AISObject::createParallel(boost::shared_ptr<GeomAPI_Shape> theLine1,
175                                        boost::shared_ptr<GeomAPI_Shape> theLine2,
176                                        boost::shared_ptr<GeomAPI_Pnt>   theFlyoutPoint,
177                                        boost::shared_ptr<GeomAPI_Pln>   thePlane)
178 {
179   Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
180   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
181   if (anAIS.IsNull())
182   {
183     Handle(AIS_ParallelRelation) aParallel = 
184       new AIS_ParallelRelation(theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
185     if (theFlyoutPoint)
186       aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
187
188     setImpl(new Handle(AIS_InteractiveObject)(aParallel));
189   }
190   else
191   {
192     Handle(AIS_ParallelRelation) aParallel = Handle(AIS_ParallelRelation)::DownCast(anAIS);
193     if (!aParallel.IsNull())
194     {
195       aParallel->SetFirstShape(theLine1->impl<TopoDS_Shape>());
196       aParallel->SetSecondShape(theLine2->impl<TopoDS_Shape>());
197       aParallel->SetPlane(aPlane);
198       if (theFlyoutPoint)
199         aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
200       aParallel->Redisplay(Standard_True);
201     }
202   }
203 }
204
205 void GeomAPI_AISObject::createPerpendicular(boost::shared_ptr<GeomAPI_Shape> theLine1,
206                                             boost::shared_ptr<GeomAPI_Shape> theLine2,
207                                             boost::shared_ptr<GeomAPI_Pln>   thePlane)
208 {
209   Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
210   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
211   if (anAIS.IsNull())
212   {
213     Handle(AIS_PerpendicularRelation) aPerpendicular = 
214       new AIS_PerpendicularRelation(theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
215
216     setImpl(new Handle(AIS_InteractiveObject)(aPerpendicular));
217   }
218   else
219   {
220     Handle(AIS_PerpendicularRelation) aPerpendicular = Handle(AIS_PerpendicularRelation)::DownCast(anAIS);
221     if (!aPerpendicular.IsNull())
222     {
223       aPerpendicular->SetFirstShape(theLine1->impl<TopoDS_Shape>());
224       aPerpendicular->SetSecondShape(theLine2->impl<TopoDS_Shape>());
225       aPerpendicular->SetPlane(aPlane);
226       aPerpendicular->Redisplay(Standard_True);
227     }
228   }
229 }
230
231
232 void GeomAPI_AISObject::setColor(const int& theColor)
233 {
234   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
235   if (anAIS.IsNull())
236     return ;
237   anAIS->SetColor(Quantity_Color((Quantity_NameOfColor)theColor));
238 }
239
240 void GeomAPI_AISObject::setWidth(const double& theWidth)
241 {
242   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
243   if (anAIS.IsNull())
244     return ;
245   anAIS->SetWidth(theWidth);
246 }
247
248 bool GeomAPI_AISObject::empty() const
249 {
250   Handle(AIS_InteractiveObject) anAIS = 
251     const_cast<GeomAPI_AISObject*>(this)->impl<Handle(AIS_InteractiveObject)>();
252   if (anAIS.IsNull())
253     return true;
254   return false;
255 }
256