#include "SketcherPrs_Angle.h"
#include "SketcherPrs_Tools.h"
+#include "SketcherPrs_DimensionStyleListener.h"
#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_Constraint.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <TopExp.hxx>
#include <BRep_Tool.hxx>
+#include <Events_Error.h>
+
#define PI 3.1415926535897932
IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension);
IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Angle, AIS_AngleDimension);
-
SketcherPrs_Angle::SketcherPrs_Angle(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: AIS_AngleDimension(gp_Pnt(0,0,0), gp_Pnt(1,0,0), gp_Pnt(0,1,0)), myConstraint(theConstraint), myPlane(thePlane)
SetDimensionAspect(myAspect);
SetSelToleranceForText2d(SketcherPrs_Tools::getDefaultTextHeight());
+
+ myStyleListener = new SketcherPrs_DimensionStyleListener();
}
-void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
- const Handle(Prs3d_Presentation)& thePresentation,
- const Standard_Integer theMode)
+SketcherPrs_Angle::~SketcherPrs_Angle()
{
- DataPtr aData = myConstraint->data();
+ delete myStyleListener;
+}
+
+bool SketcherPrs_Angle::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
+ const std::shared_ptr<GeomAPI_Ax3>&/* thePlane*/)
+{
+ bool aReadyToDisplay = false;
+
+ DataPtr aData = theConstraint->data();
// Flyout point
std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
if (!aFlyoutAttr->isInitialized())
- return; // can not create a good presentation
-
- std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = myPlane->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
+ return aReadyToDisplay; // can not create a good presentation
AttributeRefAttrPtr anAttr1 = aData->refattr(SketchPlugin_Constraint::ENTITY_A());
if (!anAttr1->isInitialized())
- return;
+ return aReadyToDisplay;
AttributeRefAttrPtr anAttr2 = aData->refattr(SketchPlugin_Constraint::ENTITY_B());
if (!anAttr2->isInitialized())
- return;
+ return aReadyToDisplay;
// Get angle edges
ObjectPtr aObj1 = anAttr1->object();
std::shared_ptr<GeomAPI_Shape> aShape1 = SketcherPrs_Tools::getShape(aObj1);
std::shared_ptr<GeomAPI_Shape> aShape2 = SketcherPrs_Tools::getShape(aObj2);
- if (!aShape1 && !aShape2)
- return;
+ aReadyToDisplay = aShape1.get() && aShape2.get();
+ return aReadyToDisplay;
+}
+
+void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
+ const Handle(Prs3d_Presentation)& thePresentation,
+ const Standard_Integer theMode)
+{
+ DataPtr aData = myConstraint->data();
+
+ if (!IsReadyToDisplay(myConstraint, myPlane)) {
+ Events_Error::throwException("An empty AIS presentation: SketcherPrs_Angle");
+ return; // can not create a good presentation
+ }
+
+ std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
+ ModelAPI_AttributeInteger>(aData->attribute(SketchPlugin_ConstraintAngle::TYPE_ID()));
+ SketcherPrs_Tools::AngleType anAngleType = (SketcherPrs_Tools::AngleType)(aTypeAttr->value());
+
+ AttributeRefAttrPtr anAttr1 = aData->refattr(SketchPlugin_Constraint::ENTITY_A());
+ AttributeRefAttrPtr anAttr2 = aData->refattr(SketchPlugin_Constraint::ENTITY_B());
+
+ // Get angle edges
+ ObjectPtr aObj1 = anAttr1->object();
+ ObjectPtr aObj2 = anAttr2->object();
+
+ std::shared_ptr<GeomAPI_Shape> aShape1 = SketcherPrs_Tools::getShape(aObj1);
+ std::shared_ptr<GeomAPI_Shape> aShape2 = SketcherPrs_Tools::getShape(aObj2);
TopoDS_Shape aTEdge1 = aShape1->impl<TopoDS_Shape>();
TopoDS_Shape aTEdge2 = aShape2->impl<TopoDS_Shape>();
TopoDS_Edge aEdge1 = TopoDS::Edge(aTEdge1);
TopoDS_Edge aEdge2 = TopoDS::Edge(aTEdge2);
- SetMeasuredGeometry(aEdge1, aEdge2);
-
- // Compute intersection point
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices(aEdge1, aV1, aV2);
- gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
- gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
- std::shared_ptr<GeomAPI_Lin> aL1(new GeomAPI_Lin(aPnt1.X(), aPnt1.Y(), aPnt1.Z(),
- aPnt2.X(), aPnt2.Y(), aPnt2.Z()));
- TopExp::Vertices(aEdge2, aV1, aV2);
- aPnt1 = BRep_Tool::Pnt(aV1);
- aPnt2 = BRep_Tool::Pnt(aV2);
- std::shared_ptr<GeomAPI_Lin> aL2(new GeomAPI_Lin(aPnt1.X(), aPnt1.Y(), aPnt1.Z(),
- aPnt2.X(), aPnt2.Y(), aPnt2.Z()));
-
- std::shared_ptr<GeomAPI_Pnt> aInter = aL1->intersect(aL2);
- gp_Pnt aCenter = aInter->impl<gp_Pnt>();
-
- gp_Pnt aFLyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z());
- double aDist = aCenter.Distance(aFLyPnt);
+
+ double aDist = -1;
+
+ switch (anAngleType) {
+ case SketcherPrs_Tools::ANGLE_DIRECT: {
+ SetArrowVisible(Standard_False/*first*/, Standard_True/*second*/);
+ /*
+ std::shared_ptr<GeomAPI_Edge> anEdge1 = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape1));
+ std::shared_ptr<GeomAPI_Edge> anEdge2 = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aShape2));
+
+ std::shared_ptr<GeomAPI_Lin> aLin1 = anEdge1->line();
+ std::shared_ptr<GeomAPI_Lin> aLin2 = anEdge2->line();
+
+ std::shared_ptr<GeomAPI_Pnt> aCenterPnt = aLin1->intersect(aLin2);
+ std::shared_ptr<GeomAPI_Dir> aDir1 = aLin1->direction();
+ std::shared_ptr<GeomAPI_Dir> aDir2 = aLin2->direction();
+
+ const gp_Pnt& aCenterPoint = aCenterPnt->impl<gp_Pnt>();
+
+ const gp_Dir& aDirection1 = aDir1->impl<gp_Dir>();
+ const gp_Dir& aDirection2 = aDir2->impl<gp_Dir>();
+
+ gp_Pnt aFirstPoint = aCenterPoint.Translated (gp_Vec (aDirection1));
+ gp_Pnt aSecondPoint = aCenterPoint.Translated (gp_Vec (aDirection2));
+
+ SetMeasuredGeometry(aFirstPoint, aCenterPoint, aSecondPoint);*/
+ SetMeasuredGeometry(aEdge1, aEdge2, Standard_False);
+ bool isReversedPlanes = isAnglePlaneReversedToSketchPlane();
+ SetAngleReversed(!isReversedPlanes);
+ }
+ break;
+ case SketcherPrs_Tools::ANGLE_COMPLEMENTARY: {
+ SetArrowVisible(Standard_True/*first*/, Standard_False/*second*/);
+ // to calculate center, first and end points
+ SetAngleReversed(false);
+ SetMeasuredGeometry(aEdge1, aEdge2, Standard_False);
+ /// the first point will be moved, so it is necessary to find distance
+ /// after applying initial parameters of geometry but before correcting them
+ /// for the current type of angle(complementary)
+ aDist = calculateDistanceToFlyoutPoint();
+ /// invert the first edge according to the angle center
+ gp_Pnt aCenter = CenterPoint();
+ gp_Pnt aFirst = FirstPoint();
+ gp_Pnt aSecond = SecondPoint();
+ double anEdge1Length = aCenter.Distance(aFirst);
+ aFirst = aCenter.Translated (gp_Vec(aCenter, aFirst).Normalized() * (-anEdge1Length));
+ anEdge1Length = aCenter.Distance(aFirst);
+
+ SetMeasuredGeometry(aFirst, aCenter, aSecond);
+ }
+ break;
+ case SketcherPrs_Tools::ANGLE_BACKWARD: {
+ SetArrowVisible(Standard_False/*first*/, Standard_True/*second*/);
+
+ SetMeasuredGeometry(aEdge1, aEdge2, Standard_False);
+ bool isReversedPlanes = isAnglePlaneReversedToSketchPlane();
+ SetAngleReversed(isReversedPlanes);
+ }
+ break;
+ default:
+ break;
+ }
+ if (aDist < 0) /// it was not calculated yet
+ aDist = calculateDistanceToFlyoutPoint();
SetFlyout(aDist);
// Angle value is in degrees
- AttributeDoublePtr aVal = aData->real(SketchPlugin_Constraint::VALUE());
- SetCustomValue(aVal->value() * PI / 180.0);
+ AttributeDoublePtr aVal = aData->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+ SetCustomValue(aVal->value());
myAspect->SetExtensionSize(myAspect->ArrowAspect()->Length());
myAspect->SetArrowTailSize(myAspect->ArrowAspect()->Length());
+ SketcherPrs_Tools::setDisplaySpecialSymbol(this, aVal->usedParameters().size() > 0);
+ myStyleListener->updateDimensions(this, aVal);
+
AIS_AngleDimension::Compute(thePresentationManager, thePresentation, theMode);
}
}
AIS_AngleDimension::ComputeSelection(aSelection, aMode);
}
+
+bool SketcherPrs_Angle::isAnglePlaneReversedToSketchPlane()
+{
+ bool aReversed = false;
+ if (!myPlane.get())
+ return aReversed;
+
+ gp_Pln aPlane = GetPlane();
+ gp_Dir aDir = aPlane.Axis().Direction();
+ double aDot = myPlane->normal()->dot(
+ std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())));
+ return aDot < 0;
+}
+
+double SketcherPrs_Angle::calculateDistanceToFlyoutPoint()
+{
+ const gp_Pnt& aCenter = CenterPoint();
+ const gp_Pnt& aFirst = FirstPoint();
+ const gp_Pnt& aSecond = SecondPoint();
+
+ // Flyout point
+ DataPtr aData = myConstraint->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+ std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = myPlane->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
+
+ gp_Dir aBisector((aFirst.XYZ() + aSecond.XYZ()) * 0.5 - aCenter.XYZ());
+ gp_Pnt aFlyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z());
+ gp_XYZ aFlyDir = aFlyPnt.XYZ() - aCenter.XYZ();
+ double aDistance = aFlyDir.Dot(aBisector.XYZ());
+ // make a positive distance in order to AIS angle presentation is not reversed
+ aDistance = fabs(aDistance);
+ return aDistance;
+}