1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAPI_AISObject.cpp
4 // Created: 25 Jun 2014
5 // Author: Artem ZHIDKOV
7 #include <GeomAPI_AISObject.h>
9 #include <GeomAPI_Circ.h>
10 #include <GeomAPI_Dir.h>
11 #include <GeomAPI_Lin.h>
12 #include <GeomAPI_Pln.h>
13 #include <GeomAPI_Pnt.h>
14 #include <GeomAPI_Shape.h>
15 #include <GeomAPI_XYZ.h>
17 #include <Geom_Plane.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <Quantity_NameOfColor.hxx>
20 #include <BRepBndLib.hxx>
22 #include <AIS_InteractiveObject.hxx>
23 #include <AIS_LengthDimension.hxx>
24 #include <AIS_ParallelRelation.hxx>
25 #include <AIS_PerpendicularRelation.hxx>
26 #include <AIS_RadiusDimension.hxx>
27 #include <AIS_Shape.hxx>
28 #include <AIS_FixRelation.hxx>
29 #include <Prs3d_PointAspect.hxx>
31 const double tolerance = 1e-7;
33 const int CONSTRAINT_TEXT_HEIGHT = 28; /// the text height of the constraint
34 const int CONSTRAINT_TEXT_SELECTION_TOLERANCE = 20; /// the text selection tolerance
36 GeomAPI_AISObject::GeomAPI_AISObject()
37 : GeomAPI_Interface(new Handle(AIS_InteractiveObject)())
41 void GeomAPI_AISObject::createShape(std::shared_ptr<GeomAPI_Shape> theShape)
43 const TopoDS_Shape& aTDS =
44 (theShape && theShape->implPtr<TopoDS_Shape>()) ?
45 theShape->impl<TopoDS_Shape>() : TopoDS_Shape();
47 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
48 if (!anAIS.IsNull()) {
49 Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
51 // if the AIS object is displayed in the opened local context in some mode, additional
52 // AIS sub objects are created there. They should be rebuild for correct selecting.
53 // It is possible to correct it by closing local context before the shape set and opening
54 // after. Another workaround to thrown down the selection and reselecting the AIS.
55 // If there was a problem here, try the first solution with close/open local context.
58 aShapeAIS->Redisplay(Standard_True);
61 setImpl(new Handle(AIS_InteractiveObject)(new AIS_Shape(aTDS)));
64 void GeomAPI_AISObject::createDistance(std::shared_ptr<GeomAPI_Pnt> theStartPoint,
65 std::shared_ptr<GeomAPI_Pnt> theEndPoint,
66 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
67 std::shared_ptr<GeomAPI_Pln> thePlane, double theDistance)
72 if (theStartPoint->distance(theEndPoint) < tolerance)
73 aDist = theStartPoint->distance(theFlyoutPoint);
75 std::shared_ptr<GeomAPI_Lin> aLine = std::shared_ptr<GeomAPI_Lin>(
76 new GeomAPI_Lin(theStartPoint, theEndPoint));
77 aDist = aLine->distance(theFlyoutPoint);
80 std::shared_ptr<GeomAPI_XYZ> aLineDir = theEndPoint->xyz()->decreased(theStartPoint->xyz());
81 std::shared_ptr<GeomAPI_XYZ> aFOutDir = theFlyoutPoint->xyz()->decreased(
82 theStartPoint->xyz());
83 std::shared_ptr<GeomAPI_XYZ> aNorm = thePlane->direction()->xyz();
84 if (aLineDir->cross(aFOutDir)->dot(aNorm) < 0)
89 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
91 Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(theStartPoint->impl<gp_Pnt>(),
92 theEndPoint->impl<gp_Pnt>(),
93 thePlane->impl<gp_Pln>());
94 aDimAIS->SetCustomValue(theDistance);
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 anAspect->ArrowAspect()->SetLength(theDistance / 10.);
102 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
103 aDimAIS->SetDimensionAspect(anAspect);
104 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
105 aDimAIS->SetFlyout(aFlyout);
107 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
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);
117 aDimAIS->Redisplay(Standard_True);
122 void GeomAPI_AISObject::createRadius(std::shared_ptr<GeomAPI_Circ> theCircle,
123 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
126 std::shared_ptr<GeomAPI_Pnt> aCenter = theCircle->center();
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 std::shared_ptr<GeomAPI_Pnt> anAnchor = theCircle->project(theFlyoutPoint);
135 std::shared_ptr<GeomAPI_XYZ> anAnchorXYZ = anAnchor->xyz();
136 anAnchorXYZ = anAnchorXYZ->decreased(aCenter->xyz());
137 std::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());
143 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
144 if (anAIS.IsNull()) {
145 Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(theCircle->impl<gp_Circ>(),
146 anAnchor->impl<gp_Pnt>());
147 aDimAIS->SetCustomValue(theRadius);
149 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
150 anAspect->MakeArrows3d(Standard_False);
151 anAspect->MakeText3d(false);
152 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
153 anAspect->ArrowAspect()->SetLength(theRadius / 5.);
154 anAspect->MakeTextShaded(false);
155 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
156 aDimAIS->SetDimensionAspect(anAspect);
157 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
159 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
161 // update presentation
162 Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
163 if (!aDimAIS.IsNull()) {
164 aDimAIS->SetMeasuredGeometry(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
165 aDimAIS->SetCustomValue(theRadius);
166 aDimAIS->Redisplay(Standard_True);
171 void GeomAPI_AISObject::createParallel(std::shared_ptr<GeomAPI_Shape> theLine1,
172 std::shared_ptr<GeomAPI_Shape> theLine2,
173 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
174 std::shared_ptr<GeomAPI_Pln> thePlane)
176 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
177 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
178 if (anAIS.IsNull()) {
179 Handle(AIS_ParallelRelation) aParallel = new AIS_ParallelRelation(
180 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
182 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
184 setImpl(new Handle(AIS_InteractiveObject)(aParallel));
186 Handle(AIS_ParallelRelation) aParallel = Handle(AIS_ParallelRelation)::DownCast(anAIS);
187 if (!aParallel.IsNull()) {
188 aParallel->SetFirstShape(theLine1->impl<TopoDS_Shape>());
189 aParallel->SetSecondShape(theLine2->impl<TopoDS_Shape>());
190 aParallel->SetPlane(aPlane);
192 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
193 aParallel->Redisplay(Standard_True);
198 void GeomAPI_AISObject::createPerpendicular(std::shared_ptr<GeomAPI_Shape> theLine1,
199 std::shared_ptr<GeomAPI_Shape> theLine2,
200 std::shared_ptr<GeomAPI_Pln> thePlane)
202 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
203 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
204 if (anAIS.IsNull()) {
205 Handle(AIS_PerpendicularRelation) aPerpendicular = new AIS_PerpendicularRelation(
206 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
208 setImpl(new Handle(AIS_InteractiveObject)(aPerpendicular));
210 Handle(AIS_PerpendicularRelation) aPerpendicular = Handle(AIS_PerpendicularRelation)::DownCast(
212 if (!aPerpendicular.IsNull()) {
213 aPerpendicular->SetFirstShape(theLine1->impl<TopoDS_Shape>());
214 aPerpendicular->SetSecondShape(theLine2->impl<TopoDS_Shape>());
215 aPerpendicular->SetPlane(aPlane);
216 aPerpendicular->Redisplay(Standard_True);
222 void GeomAPI_AISObject::createFixed(std::shared_ptr<GeomAPI_Shape> theShape,
223 std::shared_ptr<GeomAPI_Pln> thePlane)
225 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
226 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
227 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
228 Handle(AIS_FixRelation) aFixPrs;
229 if (anAIS.IsNull()) {
230 aFixPrs = new AIS_FixRelation(aShape, aPlane);
232 setImpl(new Handle(AIS_InteractiveObject)(aFixPrs));
234 aFixPrs = Handle(AIS_FixRelation)::DownCast(anAIS);
235 if (!aFixPrs.IsNull()) {
236 aFixPrs->SetFirstShape(aShape);
237 aFixPrs->SetPlane(aPlane);
238 aFixPrs->Redisplay(Standard_True);
241 if (!aFixPrs.IsNull()) {
243 BRepBndLib::Add(aShape, aBox);
244 double aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
245 aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
246 gp_Pnt aXYZ1(aXmin, aXmax, aYmin);
247 gp_Pnt aXYZ2(aXmax, aYmax, aZmax);
248 double aDist = aXYZ1.Distance(aXYZ2);
249 if (aDist > Precision::Confusion()) {
250 aFixPrs->SetArrowSize(aDist/8.);
257 void GeomAPI_AISObject::setColor(const int& theColor)
259 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
262 Quantity_Color aColor((Quantity_NameOfColor) theColor);
263 anAIS->SetColor(aColor);
264 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
265 if (!aDimAIS.IsNull()) {
266 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
270 void GeomAPI_AISObject::setWidth(const double& theWidth)
272 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
275 anAIS->SetWidth(theWidth);
278 void GeomAPI_AISObject::setColor(int theR, int theG, int theB)
280 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
283 Quantity_Color aColor(theR / 255., theG / 255., theB / 255., Quantity_TOC_RGB);
284 anAIS->SetColor(aColor);
285 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
286 if (!aDimAIS.IsNull()) {
287 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
291 bool GeomAPI_AISObject::empty() const
293 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
294 ->impl<Handle(AIS_InteractiveObject)>();
300 int GeomAPI_AISObject::getShapeType() const
302 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
303 ->impl<Handle(AIS_InteractiveObject)>();
304 if (!anAIS.IsNull()) {
305 Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(anAIS);
306 if (!aAISShape.IsNull()) {
307 return aAISShape->Shape().ShapeType();
313 void GeomAPI_AISObject::setPointMarker(int theType, double theScale)
315 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
316 if (!anAIS.IsNull()) {
317 Handle(AIS_Drawer) aDrawer = anAIS->Attributes();
318 if (aDrawer->HasPointAspect()) {
319 Handle(Prs3d_PointAspect) aPA = aDrawer->PointAspect();
320 aPA->SetTypeOfMarker((Aspect_TypeOfMarker)theType);
321 aPA->SetScale(theScale);
323 Quantity_NameOfColor aCol = Quantity_NOC_YELLOW;
324 aDrawer->SetPointAspect(new Prs3d_PointAspect((Aspect_TypeOfMarker)theType, aCol, theScale));
330 void GeomAPI_AISObject::setLineStyle(int theStyle)
332 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
333 if (!anAIS.IsNull()) {
334 Handle(AIS_Drawer) aDrawer = anAIS->Attributes();
335 if (aDrawer->HasLineAspect())
336 aDrawer->LineAspect()->SetTypeOfLine((Aspect_TypeOfLine)theStyle);
337 if (aDrawer->HasWireAspect())
338 aDrawer->WireAspect()->SetTypeOfLine((Aspect_TypeOfLine)theStyle);
340 // Quantity_NameOfColor aCol = Quantity_NOC_RED;
341 // aDrawer->SetLineAspect(new Prs3d_LineAspect(aCol, (Aspect_TypeOfLine)theStyle, 1));