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_InteractiveContext.hxx>
24 #include <AIS_LengthDimension.hxx>
25 #include <AIS_ParallelRelation.hxx>
26 #include <AIS_PerpendicularRelation.hxx>
27 #include <AIS_RadiusDimension.hxx>
28 #include <AIS_Shape.hxx>
29 #include <AIS_FixRelation.hxx>
30 #include <Prs3d_PointAspect.hxx>
32 #include <Graphic3d_AspectLine3d.hxx>
34 const double tolerance = 1e-7;
36 const int CONSTRAINT_TEXT_HEIGHT = 28; /// the text height of the constraint
37 const int CONSTRAINT_TEXT_SELECTION_TOLERANCE = 20; /// the text selection tolerance
39 GeomAPI_AISObject::GeomAPI_AISObject()
40 : GeomAPI_Interface(new Handle(AIS_InteractiveObject)())
44 void GeomAPI_AISObject::createShape(std::shared_ptr<GeomAPI_Shape> theShape)
46 const TopoDS_Shape& aTDS =
47 (theShape && theShape->implPtr<TopoDS_Shape>()) ?
48 theShape->impl<TopoDS_Shape>() : TopoDS_Shape();
50 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
51 if (!anAIS.IsNull()) {
52 Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
54 // if the AIS object is displayed in the opened local context in some mode, additional
55 // AIS sub objects are created there. They should be rebuild for correct selecting.
56 // It is possible to correct it by closing local context before the shape set and opening
57 // after. Another workaround to thrown down the selection and reselecting the AIS.
58 // If there was a problem here, try the first solution with close/open local context.
61 aShapeAIS->Redisplay(Standard_True);
64 setImpl(new Handle(AIS_InteractiveObject)(new AIS_Shape(aTDS)));
67 void GeomAPI_AISObject::createDistance(std::shared_ptr<GeomAPI_Pnt> theStartPoint,
68 std::shared_ptr<GeomAPI_Pnt> theEndPoint,
69 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
70 std::shared_ptr<GeomAPI_Pln> thePlane, double theDistance)
75 if (theStartPoint->distance(theEndPoint) < tolerance)
76 aDist = theStartPoint->distance(theFlyoutPoint);
78 std::shared_ptr<GeomAPI_Lin> aLine = std::shared_ptr<GeomAPI_Lin>(
79 new GeomAPI_Lin(theStartPoint, theEndPoint));
80 aDist = aLine->distance(theFlyoutPoint);
83 std::shared_ptr<GeomAPI_XYZ> aLineDir = theEndPoint->xyz()->decreased(theStartPoint->xyz());
84 std::shared_ptr<GeomAPI_XYZ> aFOutDir = theFlyoutPoint->xyz()->decreased(
85 theStartPoint->xyz());
86 std::shared_ptr<GeomAPI_XYZ> aNorm = thePlane->direction()->xyz();
87 if (aLineDir->cross(aFOutDir)->dot(aNorm) < 0)
92 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
94 Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(theStartPoint->impl<gp_Pnt>(),
95 theEndPoint->impl<gp_Pnt>(),
96 thePlane->impl<gp_Pln>());
97 aDimAIS->SetCustomValue(theDistance);
99 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
100 anAspect->MakeArrows3d(Standard_False);
101 anAspect->MakeText3d(Standard_False);
102 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
103 anAspect->MakeTextShaded(Standard_True);
104 anAspect->ArrowAspect()->SetLength(theDistance / 10.);
105 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
106 aDimAIS->SetDimensionAspect(anAspect);
107 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
108 aDimAIS->SetFlyout(aFlyout);
110 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
112 // update presentation
113 Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
114 if (!aDimAIS.IsNull()) {
115 aDimAIS->SetMeasuredGeometry(theStartPoint->impl<gp_Pnt>(), theEndPoint->impl<gp_Pnt>(),
116 thePlane->impl<gp_Pln>());
117 aDimAIS->SetCustomValue(theDistance);
118 aDimAIS->SetFlyout(aFlyout);
120 aDimAIS->Redisplay(Standard_True);
125 void GeomAPI_AISObject::createRadius(std::shared_ptr<GeomAPI_Circ> theCircle,
126 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
129 std::shared_ptr<GeomAPI_Pnt> aCenter = theCircle->center();
131 // TODO: a bug in AIS_RadiusDimension:
132 // The anchor point can't be myCirc.Location() - an exception is raised.
133 // But we need exactly this case...
134 // We want to show a radius dimension starting from the circle centre and
135 // ending at the user-defined point.
136 // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
137 std::shared_ptr<GeomAPI_Pnt> anAnchor = theCircle->project(theFlyoutPoint);
138 std::shared_ptr<GeomAPI_XYZ> anAnchorXYZ = anAnchor->xyz();
139 anAnchorXYZ = anAnchorXYZ->decreased(aCenter->xyz());
140 std::shared_ptr<GeomAPI_Dir> aDeltaDir(new GeomAPI_Dir(anAnchorXYZ));
141 const double aDelta = 1e-3;
142 anAnchor->setX(anAnchor->x() + aDelta * aDeltaDir->x());
143 anAnchor->setY(anAnchor->y() + aDelta * aDeltaDir->y());
144 anAnchor->setZ(anAnchor->z() + aDelta * aDeltaDir->z());
146 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
147 if (anAIS.IsNull()) {
148 Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(theCircle->impl<gp_Circ>(),
149 anAnchor->impl<gp_Pnt>());
150 aDimAIS->SetCustomValue(theRadius);
152 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
153 anAspect->MakeArrows3d(Standard_False);
154 anAspect->MakeText3d(false);
155 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
156 anAspect->ArrowAspect()->SetLength(theRadius / 5.);
157 anAspect->MakeTextShaded(false);
158 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
159 aDimAIS->SetDimensionAspect(anAspect);
160 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
162 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
164 // update presentation
165 Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
166 if (!aDimAIS.IsNull()) {
167 aDimAIS->SetMeasuredGeometry(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
168 aDimAIS->SetCustomValue(theRadius);
169 aDimAIS->Redisplay(Standard_True);
174 void GeomAPI_AISObject::createParallel(std::shared_ptr<GeomAPI_Shape> theLine1,
175 std::shared_ptr<GeomAPI_Shape> theLine2,
176 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
177 std::shared_ptr<GeomAPI_Pln> thePlane)
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 Handle(AIS_ParallelRelation) aParallel = new AIS_ParallelRelation(
183 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
185 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
187 setImpl(new Handle(AIS_InteractiveObject)(aParallel));
189 Handle(AIS_ParallelRelation) aParallel = Handle(AIS_ParallelRelation)::DownCast(anAIS);
190 if (!aParallel.IsNull()) {
191 aParallel->SetFirstShape(theLine1->impl<TopoDS_Shape>());
192 aParallel->SetSecondShape(theLine2->impl<TopoDS_Shape>());
193 aParallel->SetPlane(aPlane);
195 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
196 aParallel->Redisplay(Standard_True);
201 void GeomAPI_AISObject::createPerpendicular(std::shared_ptr<GeomAPI_Shape> theLine1,
202 std::shared_ptr<GeomAPI_Shape> theLine2,
203 std::shared_ptr<GeomAPI_Pln> thePlane)
205 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
206 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
207 if (anAIS.IsNull()) {
208 Handle(AIS_PerpendicularRelation) aPerpendicular = new AIS_PerpendicularRelation(
209 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
211 setImpl(new Handle(AIS_InteractiveObject)(aPerpendicular));
213 Handle(AIS_PerpendicularRelation) aPerpendicular = Handle(AIS_PerpendicularRelation)::DownCast(
215 if (!aPerpendicular.IsNull()) {
216 aPerpendicular->SetFirstShape(theLine1->impl<TopoDS_Shape>());
217 aPerpendicular->SetSecondShape(theLine2->impl<TopoDS_Shape>());
218 aPerpendicular->SetPlane(aPlane);
219 aPerpendicular->Redisplay(Standard_True);
225 void GeomAPI_AISObject::createFixed(std::shared_ptr<GeomAPI_Shape> theShape,
226 std::shared_ptr<GeomAPI_Pln> thePlane)
228 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
229 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
230 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
231 Handle(AIS_FixRelation) aFixPrs;
232 if (anAIS.IsNull()) {
233 aFixPrs = new AIS_FixRelation(aShape, aPlane);
235 setImpl(new Handle(AIS_InteractiveObject)(aFixPrs));
237 aFixPrs = Handle(AIS_FixRelation)::DownCast(anAIS);
238 if (!aFixPrs.IsNull()) {
239 aFixPrs->SetFirstShape(aShape);
240 aFixPrs->SetPlane(aPlane);
241 aFixPrs->Redisplay(Standard_True);
244 if (!aFixPrs.IsNull()) {
246 BRepBndLib::Add(aShape, aBox);
247 double aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
248 aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
249 gp_Pnt aXYZ1(aXmin, aXmax, aYmin);
250 gp_Pnt aXYZ2(aXmax, aYmax, aZmax);
251 double aDist = aXYZ1.Distance(aXYZ2);
252 if (aDist > Precision::Confusion()) {
253 aFixPrs->SetArrowSize(aDist/8.);
258 void GeomAPI_AISObject::setColor(const int& theColor)
260 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
263 Quantity_Color aColor((Quantity_NameOfColor) theColor);
264 anAIS->SetColor(aColor);
265 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
266 if (!aDimAIS.IsNull()) {
267 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
269 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
270 aContext->SetColor(anAIS, aColor, false);
273 bool GeomAPI_AISObject::setWidth(const double& theWidth)
275 bool isChanged = false;
276 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
277 if (!anAIS.IsNull()) {
278 isChanged = anAIS->Width() != theWidth;
280 anAIS->SetWidth(theWidth);
285 bool GeomAPI_AISObject::setColor(int theR, int theG, int theB)
287 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
290 Quantity_Color aColor(theR / 255., theG / 255., theB / 255., Quantity_TOC_RGB);
291 Quantity_Color aCurrentColor;
292 anAIS->Color(aCurrentColor);
293 // do not set the same color to the presentation
294 if (aColor.IsEqual(aCurrentColor))
297 anAIS->SetColor(aColor);
298 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
299 if (!aDimAIS.IsNull()) {
300 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
302 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
303 aContext->SetColor(anAIS, aColor, false);
307 void GeomAPI_AISObject::getColor(int& theR, int& theG, int& theB)
309 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
313 Quantity_Color aColor = anAIS->Color();
314 theR = (int)(aColor.Red()*255.);
315 theG = (int)(aColor.Green()*255.);
316 theB = (int)(aColor.Blue()*255.);
319 bool GeomAPI_AISObject::empty() const
321 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
322 ->impl<Handle(AIS_InteractiveObject)>();
328 int GeomAPI_AISObject::getShapeType() const
330 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
331 ->impl<Handle(AIS_InteractiveObject)>();
332 if (!anAIS.IsNull()) {
333 Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(anAIS);
334 if (!aAISShape.IsNull()) {
335 return aAISShape->Shape().ShapeType();
341 void GeomAPI_AISObject::setPointMarker(int theType, double theScale)
343 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
344 if (!anAIS.IsNull()) {
345 Handle(AIS_Drawer) aDrawer = anAIS->Attributes();
346 if (aDrawer->HasPointAspect()) {
347 Handle(Prs3d_PointAspect) aPA = aDrawer->PointAspect();
348 aPA->SetTypeOfMarker((Aspect_TypeOfMarker)theType);
349 aPA->SetScale(theScale);
351 Quantity_NameOfColor aCol = Quantity_NOC_YELLOW;
352 aDrawer->SetPointAspect(new Prs3d_PointAspect((Aspect_TypeOfMarker)theType, aCol, theScale));
357 bool GeomAPI_AISObject::setLineStyle(int theStyle)
359 bool isChanged = false;
360 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
361 if (!anAIS.IsNull()) {
362 Handle(AIS_Drawer) aDrawer = anAIS->Attributes();
363 Handle(Prs3d_LineAspect) aLineAspect;
365 Aspect_TypeOfLine aType = (Aspect_TypeOfLine)theStyle;
366 if (aDrawer->HasLineAspect()) {
367 aLineAspect = aDrawer->LineAspect();
369 if (aDrawer->HasWireAspect()) {
370 aLineAspect = aDrawer->WireAspect();
372 Quantity_Color aCurrentColor;
373 Aspect_TypeOfLine aCurrentType;
374 Standard_Real aCurrentWidth;
375 aLineAspect->Aspect()->Values(aCurrentColor, aCurrentType, aCurrentWidth);
376 isChanged = aType != aCurrentType;
378 aLineAspect->SetTypeOfLine(aType);
385 bool GeomAPI_AISObject::setTransparensy(double theVal)
387 bool isChanged = false;
388 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
389 if (!anAIS.IsNull()) {
390 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
391 if (!aContext.IsNull()) {
392 double aCurrentValue = anAIS->Transparency();
393 isChanged = aCurrentValue != theVal;
395 aContext->SetTransparency(anAIS, theVal, false);