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 GeomAPI_AISObject::~GeomAPI_AISObject()
47 // This is necessary for correct deletion of Handle entity.
48 // Without this Handle does not decremented counter to 0
49 Handle(AIS_InteractiveObject) *anAIS = implPtr<Handle(AIS_InteractiveObject)>();
55 void GeomAPI_AISObject::createShape(std::shared_ptr<GeomAPI_Shape> theShape)
57 const TopoDS_Shape& aTDS =
58 (theShape && theShape->implPtr<TopoDS_Shape>()) ?
59 theShape->impl<TopoDS_Shape>() : TopoDS_Shape();
61 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
62 if (!anAIS.IsNull()) {
63 Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
65 // if the AIS object is displayed in the opened local context in some mode, additional
66 // AIS sub objects are created there. They should be rebuild for correct selecting.
67 // It is possible to correct it by closing local context before the shape set and opening
68 // after. Another workaround to thrown down the selection and reselecting the AIS.
69 // If there was a problem here, try the first solution with close/open local context.
72 aShapeAIS->Redisplay(Standard_True);
75 // Set default point as a '+' symbol
76 Handle(AIS_Shape) aShape = new AIS_Shape(aTDS);
77 Handle(Prs3d_Drawer) aDrawer = aShape->Attributes();
78 if (aDrawer->HasOwnPointAspect())
79 aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_PLUS);
81 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.));
82 setImpl(new Handle(AIS_InteractiveObject)(aShape));
86 std::shared_ptr<GeomAPI_Shape> GeomAPI_AISObject::getShape() const
88 std::shared_ptr<GeomAPI_Shape> aResult;
90 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
91 if (!anAIS.IsNull()) {
92 Handle(AIS_Shape) aShapeAIS = Handle(AIS_Shape)::DownCast(anAIS);
94 std::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape);
95 aResult->setImpl(new TopoDS_Shape(aShapeAIS->Shape()));
99 return std::shared_ptr<GeomAPI_Shape>();
102 void GeomAPI_AISObject::createDistance(std::shared_ptr<GeomAPI_Pnt> theStartPoint,
103 std::shared_ptr<GeomAPI_Pnt> theEndPoint,
104 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
105 std::shared_ptr<GeomAPI_Pln> thePlane, double theDistance)
108 if (theFlyoutPoint) {
110 if (theStartPoint->distance(theEndPoint) < tolerance)
111 aDist = theStartPoint->distance(theFlyoutPoint);
113 std::shared_ptr<GeomAPI_Lin> aLine = std::shared_ptr<GeomAPI_Lin>(
114 new GeomAPI_Lin(theStartPoint, theEndPoint));
115 aDist = aLine->distance(theFlyoutPoint);
118 std::shared_ptr<GeomAPI_XYZ> aLineDir = theEndPoint->xyz()->decreased(theStartPoint->xyz());
119 std::shared_ptr<GeomAPI_XYZ> aFOutDir = theFlyoutPoint->xyz()->decreased(
120 theStartPoint->xyz());
121 std::shared_ptr<GeomAPI_XYZ> aNorm = thePlane->direction()->xyz();
122 if (aLineDir->cross(aFOutDir)->dot(aNorm) < 0)
127 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
128 if (anAIS.IsNull()) {
129 Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(theStartPoint->impl<gp_Pnt>(),
130 theEndPoint->impl<gp_Pnt>(),
131 thePlane->impl<gp_Pln>());
132 aDimAIS->SetCustomValue(theDistance);
134 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
135 anAspect->MakeArrows3d(Standard_False);
136 anAspect->MakeText3d(Standard_False);
137 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
138 anAspect->MakeTextShaded(Standard_True);
139 anAspect->ArrowAspect()->SetLength(theDistance / 10.);
140 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
141 aDimAIS->SetDimensionAspect(anAspect);
142 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
143 aDimAIS->SetFlyout(aFlyout);
145 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
147 // update presentation
148 Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
149 if (!aDimAIS.IsNull()) {
150 aDimAIS->SetMeasuredGeometry(theStartPoint->impl<gp_Pnt>(), theEndPoint->impl<gp_Pnt>(),
151 thePlane->impl<gp_Pln>());
152 aDimAIS->SetCustomValue(theDistance);
153 aDimAIS->SetFlyout(aFlyout);
155 aDimAIS->Redisplay(Standard_True);
160 bool GeomAPI_AISObject::isEmptyDistanceGeometry()
162 bool anEmpty = false;
164 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
165 if (!anAIS.IsNull()) {
166 Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
167 if (!aDimAIS.IsNull()) {
168 anEmpty = !aDimAIS->IsValid();
175 void GeomAPI_AISObject::createRadius(std::shared_ptr<GeomAPI_Circ> theCircle,
176 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
179 std::shared_ptr<GeomAPI_Pnt> aCenter = theCircle->center();
181 // TODO: a bug in AIS_RadiusDimension:
182 // The anchor point can't be myCirc.Location() - an exception is raised.
183 // But we need exactly this case...
184 // We want to show a radius dimension starting from the circle centre and
185 // ending at the user-defined point.
186 // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
187 std::shared_ptr<GeomAPI_Pnt> anAnchor = theCircle->project(theFlyoutPoint);
188 std::shared_ptr<GeomAPI_XYZ> anAnchorXYZ = anAnchor->xyz();
189 anAnchorXYZ = anAnchorXYZ->decreased(aCenter->xyz());
190 std::shared_ptr<GeomAPI_Dir> aDeltaDir(new GeomAPI_Dir(anAnchorXYZ));
191 const double aDelta = 1e-3;
192 anAnchor->setX(anAnchor->x() + aDelta * aDeltaDir->x());
193 anAnchor->setY(anAnchor->y() + aDelta * aDeltaDir->y());
194 anAnchor->setZ(anAnchor->z() + aDelta * aDeltaDir->z());
196 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
197 if (anAIS.IsNull()) {
198 Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(theCircle->impl<gp_Circ>(),
199 anAnchor->impl<gp_Pnt>());
200 aDimAIS->SetCustomValue(theRadius);
202 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
203 anAspect->MakeArrows3d(Standard_False);
204 anAspect->MakeText3d(false);
205 anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
206 anAspect->ArrowAspect()->SetLength(theRadius / 5.);
207 anAspect->MakeTextShaded(false);
208 aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
209 aDimAIS->SetDimensionAspect(anAspect);
210 aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
212 setImpl(new Handle(AIS_InteractiveObject)(aDimAIS));
214 // update presentation
215 Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
216 if (!aDimAIS.IsNull()) {
217 aDimAIS->SetMeasuredGeometry(theCircle->impl<gp_Circ>(), anAnchor->impl<gp_Pnt>());
218 aDimAIS->SetCustomValue(theRadius);
219 aDimAIS->Redisplay(Standard_True);
224 void GeomAPI_AISObject::createParallel(std::shared_ptr<GeomAPI_Shape> theLine1,
225 std::shared_ptr<GeomAPI_Shape> theLine2,
226 std::shared_ptr<GeomAPI_Pnt> theFlyoutPoint,
227 std::shared_ptr<GeomAPI_Pln> thePlane)
229 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
230 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
231 if (anAIS.IsNull()) {
232 Handle(AIS_ParallelRelation) aParallel = new AIS_ParallelRelation(
233 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
235 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
237 setImpl(new Handle(AIS_InteractiveObject)(aParallel));
239 Handle(AIS_ParallelRelation) aParallel = Handle(AIS_ParallelRelation)::DownCast(anAIS);
240 if (!aParallel.IsNull()) {
241 aParallel->SetFirstShape(theLine1->impl<TopoDS_Shape>());
242 aParallel->SetSecondShape(theLine2->impl<TopoDS_Shape>());
243 aParallel->SetPlane(aPlane);
245 aParallel->SetPosition(theFlyoutPoint->impl<gp_Pnt>());
246 aParallel->Redisplay(Standard_True);
251 void GeomAPI_AISObject::createPerpendicular(std::shared_ptr<GeomAPI_Shape> theLine1,
252 std::shared_ptr<GeomAPI_Shape> theLine2,
253 std::shared_ptr<GeomAPI_Pln> thePlane)
255 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
256 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
257 if (anAIS.IsNull()) {
258 Handle(AIS_PerpendicularRelation) aPerpendicular = new AIS_PerpendicularRelation(
259 theLine1->impl<TopoDS_Shape>(), theLine2->impl<TopoDS_Shape>(), aPlane);
261 setImpl(new Handle(AIS_InteractiveObject)(aPerpendicular));
263 Handle(AIS_PerpendicularRelation) aPerpendicular = Handle(AIS_PerpendicularRelation)::DownCast(
265 if (!aPerpendicular.IsNull()) {
266 aPerpendicular->SetFirstShape(theLine1->impl<TopoDS_Shape>());
267 aPerpendicular->SetSecondShape(theLine2->impl<TopoDS_Shape>());
268 aPerpendicular->SetPlane(aPlane);
269 aPerpendicular->Redisplay(Standard_True);
275 void GeomAPI_AISObject::createFixed(std::shared_ptr<GeomAPI_Shape> theShape,
276 std::shared_ptr<GeomAPI_Pln> thePlane)
278 Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
279 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
280 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
281 Handle(AIS_FixRelation) aFixPrs;
282 if (anAIS.IsNull()) {
283 aFixPrs = new AIS_FixRelation(aShape, aPlane);
285 setImpl(new Handle(AIS_InteractiveObject)(aFixPrs));
287 aFixPrs = Handle(AIS_FixRelation)::DownCast(anAIS);
288 if (!aFixPrs.IsNull()) {
289 aFixPrs->SetFirstShape(aShape);
290 aFixPrs->SetPlane(aPlane);
291 aFixPrs->Redisplay(Standard_True);
294 if (!aFixPrs.IsNull()) {
296 BRepBndLib::Add(aShape, aBox);
297 double aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
298 aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
299 gp_Pnt aXYZ1(aXmin, aXmax, aYmin);
300 gp_Pnt aXYZ2(aXmax, aYmax, aZmax);
301 double aDist = aXYZ1.Distance(aXYZ2);
302 if (aDist > Precision::Confusion()) {
303 aFixPrs->SetArrowSize(aDist/8.);
308 void GeomAPI_AISObject::setColor(const int& theColor)
310 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
313 Quantity_Color aColor((Quantity_NameOfColor) theColor);
314 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
315 if (!aDimAIS.IsNull()) {
316 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
318 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
319 aContext->SetColor(anAIS, aColor, false);
322 double GeomAPI_AISObject::width()
325 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
326 if (!anAIS.IsNull()) {
327 aWidth = anAIS->Width();
332 bool GeomAPI_AISObject::setWidth(const double& theWidth)
334 bool isChanged = false;
335 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
336 if (!anAIS.IsNull()) {
337 isChanged = anAIS->Width() != theWidth;
339 anAIS->SetWidth(theWidth);
344 bool GeomAPI_AISObject::setColor(int theR, int theG, int theB)
346 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
349 Quantity_Color aColor(theR / 255., theG / 255., theB / 255., Quantity_TOC_RGB);
350 Quantity_Color aCurrentColor;
351 anAIS->Color(aCurrentColor);
352 // do not set the same color to the presentation
353 if (aColor.IsEqual(aCurrentColor))
356 Handle(AIS_Dimension) aDimAIS = Handle(AIS_Dimension)::DownCast(anAIS);
357 if (!aDimAIS.IsNull()) {
358 aDimAIS->DimensionAspect()->SetCommonColor(aColor);
360 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
361 aContext->SetColor(anAIS, aColor, false);
365 void GeomAPI_AISObject::getColor(int& theR, int& theG, int& theB)
367 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
371 Quantity_Color aColor = anAIS->Color();
372 theR = (int)(aColor.Red()*255.);
373 theG = (int)(aColor.Green()*255.);
374 theB = (int)(aColor.Blue()*255.);
377 bool GeomAPI_AISObject::empty() const
379 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
380 ->impl<Handle(AIS_InteractiveObject)>();
386 int GeomAPI_AISObject::getShapeType() const
388 Handle(AIS_InteractiveObject) anAIS = const_cast<GeomAPI_AISObject*>(this)
389 ->impl<Handle(AIS_InteractiveObject)>();
390 if (!anAIS.IsNull()) {
391 Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(anAIS);
392 if (!aAISShape.IsNull()) {
393 const TopoDS_Shape aShape = aAISShape->Shape();
394 if (!aShape.IsNull())
395 return aShape.ShapeType();
401 void GeomAPI_AISObject::setPointMarker(int theType, double theScale)
403 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
404 if (!anAIS.IsNull()) {
405 Handle(Prs3d_Drawer) aDrawer = anAIS->Attributes();
406 if (aDrawer->HasOwnPointAspect()) {
407 Handle(Prs3d_PointAspect) aPA = aDrawer->PointAspect();
408 aPA->SetTypeOfMarker((Aspect_TypeOfMarker)theType);
409 aPA->SetScale(theScale);
411 Quantity_NameOfColor aCol = Quantity_NOC_YELLOW;
412 aDrawer->SetPointAspect(new Prs3d_PointAspect((Aspect_TypeOfMarker)theType, aCol, theScale));
417 bool GeomAPI_AISObject::setLineStyle(int theStyle)
419 bool isChanged = false;
420 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
421 if (!anAIS.IsNull()) {
422 Handle(Prs3d_Drawer) aDrawer = anAIS->Attributes();
423 Handle(Prs3d_LineAspect) aLineAspect;
425 Aspect_TypeOfLine aType = (Aspect_TypeOfLine)theStyle;
426 if (aDrawer->HasOwnLineAspect()) {
427 aLineAspect = aDrawer->LineAspect();
429 if (aDrawer->HasOwnWireAspect()) {
430 aLineAspect = aDrawer->WireAspect();
432 Quantity_Color aCurrentColor;
433 Aspect_TypeOfLine aCurrentType;
434 Standard_Real aCurrentWidth;
435 aLineAspect->Aspect()->Values(aCurrentColor, aCurrentType, aCurrentWidth);
436 isChanged = aType != aCurrentType;
438 aLineAspect->SetTypeOfLine(aType);
444 bool GeomAPI_AISObject::setTransparensy(double theVal)
446 bool isChanged = false;
447 Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
448 if (!anAIS.IsNull()) {
449 Handle(AIS_InteractiveContext) aContext = anAIS->GetContext();
450 if (!aContext.IsNull()) {
451 double aCurrentValue = anAIS->Transparency();
452 isChanged = aCurrentValue != theVal;
454 aContext->SetTransparency(anAIS, theVal, false);
456 anAIS->SetTransparency(theVal);