1 // File: GeomAPI_AISObject.cpp
2 // Created: 25 Jun 2014
3 // Author: Artem ZHIDKOV
5 #include <GeomAPI_AISObject.h>
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>
15 #include <Geom_Plane.hxx>
16 #include <TopoDS_Shape.hxx>
17 #include <Quantity_NameOfColor.hxx>
18 #include <BRepBndLib.hxx>
20 #include <AIS_InteractiveObject.hxx>
21 #include <AIS_LengthDimension.hxx>
22 #include <AIS_ParallelRelation.hxx>
23 #include <AIS_PerpendicularRelation.hxx>
24 #include <AIS_RadiusDimension.hxx>
25 #include <AIS_Shape.hxx>
26 #include <AIS_FixRelation.hxx>
28 const double tolerance = 1e-7;
30 const int CONSTRAINT_TEXT_HEIGHT = 28; /// the text height of the constraint
31 const int CONSTRAINT_TEXT_SELECTION_TOLERANCE = 20; /// the text selection tolerance
33 GeomAPI_AISObject::GeomAPI_AISObject()
34 : GeomAPI_Interface(new Handle(AIS_InteractiveObject)())
38 void GeomAPI_AISObject::createShape(std::shared_ptr<GeomAPI_Shape> theShape)
40 const TopoDS_Shape& aTDS =
41 (theShape && theShape->implPtr<TopoDS_Shape>()) ?
42 theShape->impl<TopoDS_Shape>() : TopoDS_Shape();
44 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
45 if (!anAIS.IsNull()) {
46 Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
48 // if the AIS object is displayed in the opened local context in some mode, additional
49 // AIS sub objects are created there. They should be rebuild for correct selecting.
50 // It is possible to correct it by closing local context before the shape set and opening
51 // after. Another workaround to thrown down the selection and reselecting the AIS.
52 // If there was a problem here, try the first solution with close/open local context.
55 aShapeAIS->Redisplay(Standard_True);
58 setImpl(new Handle(AIS_InteractiveObject)(new AIS_Shape(aTDS)));
61 void GeomAPI_AISObject::createDistance(std::shared_ptr<GeomAPI_Pnt> theStartPoint,
62 std::shared_ptr<GeomAPI_Pnt> theEndPoint,
63 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
64 std::shared_ptr<GeomAPI_Pln> thePlane, double theDistance)
69 if (theStartPoint->distance(theEndPoint) < tolerance)
70 aDist = theStartPoint->distance(theFlyoutPoint);
72 std::shared_ptr<GeomAPI_Lin> aLine = std::shared_ptr<GeomAPI_Lin>(
73 new GeomAPI_Lin(theStartPoint, theEndPoint));
74 aDist = aLine->distance(theFlyoutPoint);
77 std::shared_ptr<GeomAPI_XYZ> aLineDir = theEndPoint->xyz()->decreased(theStartPoint->xyz());
78 std::shared_ptr<GeomAPI_XYZ> aFOutDir = theFlyoutPoint->xyz()->decreased(
79 theStartPoint->xyz());
80 std::shared_ptr<GeomAPI_XYZ> aNorm = thePlane->direction()->xyz();
81 if (aLineDir->cross(aFOutDir)->dot(aNorm) < 0)
86 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
88 Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(theStartPoint->impl<gp_Pnt>(),
89 theEndPoint->impl<gp_Pnt>(),
90 thePlane->impl<gp_Pln>());
91 aDimAIS->SetCustomValue(theDistance);
93 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
94 anAspect->MakeArrows3d(Standard_False);
95 anAspect->MakeText3d(false);
96 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
97 anAspect->MakeTextShaded(false);
98 anAspect->ArrowAspect()->SetLength(theDistance / 10.);
99 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
100 aDimAIS->SetDimensionAspect(anAspect);
101 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
102 aDimAIS->SetFlyout(aFlyout);
104 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
106 // update presentation
107 Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
108 if (!aDimAIS.IsNull()) {
109 aDimAIS->SetMeasuredGeometry(theStartPoint->impl<gp_Pnt>(), theEndPoint->impl<gp_Pnt>(),
110 thePlane->impl<gp_Pln>());
111 aDimAIS->SetCustomValue(theDistance);
112 aDimAIS->SetFlyout(aFlyout);
114 aDimAIS->Redisplay(Standard_True);
119 void GeomAPI_AISObject::createRadius(std::shared_ptr<GeomAPI_Circ> theCircle,
120 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
123 std::shared_ptr<GeomAPI_Pnt> aCenter = theCircle->center();
125 // TODO: a bug in AIS_RadiusDimension:
126 // The anchor point can't be myCirc.Location() - an exception is raised.
127 // But we need exactly this case...
128 // We want to show a radius dimension starting from the circle centre and
129 // ending at the user-defined point.
130 // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
131 std::shared_ptr<GeomAPI_Pnt> anAnchor = theCircle->project(theFlyoutPoint);
132 std::shared_ptr<GeomAPI_XYZ> anAnchorXYZ = anAnchor->xyz();
133 anAnchorXYZ = anAnchorXYZ->decreased(aCenter->xyz());
134 std::shared_ptr<GeomAPI_Dir> aDeltaDir(new GeomAPI_Dir(anAnchorXYZ));
135 const double aDelta = 1e-3;
136 anAnchor->setX(anAnchor->x() + aDelta * aDeltaDir->x());
137 anAnchor->setY(anAnchor->y() + aDelta * aDeltaDir->y());
138 anAnchor->setZ(anAnchor->z() + aDelta * aDeltaDir->z());
140 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
141 if (anAIS.IsNull()) {
142 Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(theCircle->impl<gp_Circ>(),
143 anAnchor->impl<gp_Pnt>());
144 aDimAIS->SetCustomValue(theRadius);
146 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
147 anAspect->MakeArrows3d(Standard_False);
148 anAspect->MakeText3d(false);
149 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
150 anAspect->ArrowAspect()->SetLength(theRadius / 5.);
151 anAspect->MakeTextShaded(false);
152 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
153 aDimAIS->SetDimensionAspect(anAspect);
154 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
156 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
158 // update presentation
159 Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
160 if (!aDimAIS.IsNull()) {
161 aDimAIS->SetMeasuredGeometry(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
162 aDimAIS->SetCustomValue(theRadius);
163 aDimAIS->Redisplay(Standard_True);
168 void GeomAPI_AISObject::createParallel(std::shared_ptr<GeomAPI_Shape> theLine1,
169 std::shared_ptr<GeomAPI_Shape> theLine2,
170 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
171 std::shared_ptr<GeomAPI_Pln> thePlane)
173 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
174 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
175 if (anAIS.IsNull()) {
176 Handle(AIS_ParallelRelation) aParallel = new AIS_ParallelRelation(
177 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
179 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
181 setImpl(new Handle(AIS_InteractiveObject)(aParallel));
183 Handle(AIS_ParallelRelation) aParallel = Handle(AIS_ParallelRelation)::DownCast(anAIS);
184 if (!aParallel.IsNull()) {
185 aParallel->SetFirstShape(theLine1->impl<TopoDS_Shape>());
186 aParallel->SetSecondShape(theLine2->impl<TopoDS_Shape>());
187 aParallel->SetPlane(aPlane);
189 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
190 aParallel->Redisplay(Standard_True);
195 void GeomAPI_AISObject::createPerpendicular(std::shared_ptr<GeomAPI_Shape> theLine1,
196 std::shared_ptr<GeomAPI_Shape> theLine2,
197 std::shared_ptr<GeomAPI_Pln> thePlane)
199 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
200 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
201 if (anAIS.IsNull()) {
202 Handle(AIS_PerpendicularRelation) aPerpendicular = new AIS_PerpendicularRelation(
203 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
205 setImpl(new Handle(AIS_InteractiveObject)(aPerpendicular));
207 Handle(AIS_PerpendicularRelation) aPerpendicular = Handle(AIS_PerpendicularRelation)::DownCast(
209 if (!aPerpendicular.IsNull()) {
210 aPerpendicular->SetFirstShape(theLine1->impl<TopoDS_Shape>());
211 aPerpendicular->SetSecondShape(theLine2->impl<TopoDS_Shape>());
212 aPerpendicular->SetPlane(aPlane);
213 aPerpendicular->Redisplay(Standard_True);
219 void GeomAPI_AISObject::createFixed(std::shared_ptr<GeomAPI_Shape> theShape,
220 std::shared_ptr<GeomAPI_Pln> thePlane)
222 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
223 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
224 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
225 Handle(AIS_FixRelation) aFixPrs;
226 if (anAIS.IsNull()) {
227 aFixPrs = new AIS_FixRelation(aShape, aPlane);
229 setImpl(new Handle(AIS_InteractiveObject)(aFixPrs));
231 aFixPrs = Handle(AIS_FixRelation)::DownCast(anAIS);
232 if (!aFixPrs.IsNull()) {
233 aFixPrs->SetFirstShape(aShape);
234 aFixPrs->SetPlane(aPlane);
235 aFixPrs->Redisplay(Standard_True);
238 if (!aFixPrs.IsNull()) {
240 BRepBndLib::Add(aShape, aBox);
241 double aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
242 aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
243 gp_Pnt aXYZ1(aXmin, aXmax, aYmin);
244 gp_Pnt aXYZ2(aXmax, aYmax, aZmax);
245 double aDist = aXYZ1.Distance(aXYZ2);
246 if (aDist > Precision::Confusion()) {
247 aFixPrs->SetArrowSize(aDist/8.);
254 void GeomAPI_AISObject::setColor(const int& theColor)
256 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
259 Quantity_Color aColor((Quantity_NameOfColor) theColor);
260 anAIS->SetColor(aColor);
261 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
262 if (!aDimAIS.IsNull()) {
263 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
267 void GeomAPI_AISObject::setWidth(const double& theWidth)
269 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
272 anAIS->SetWidth(theWidth);
275 void GeomAPI_AISObject::setColor(int theR, int theG, int theB)
277 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
280 Quantity_Color aColor(theR / 255., theG / 255., theB / 255., Quantity_TOC_RGB);
281 anAIS->SetColor(aColor);
282 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
283 if (!aDimAIS.IsNull()) {
284 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
288 bool GeomAPI_AISObject::empty() const
290 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
291 ->impl<Handle(AIS_InteractiveObject)>();