#include <GeomDataAPI_Point2D.h>
+#include <SketcherPrs_Factory.h>
+
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Result.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Lin2d.h>
#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_XY.h>
#include <Config_PropManager.h>
+#include <math.h>
+
+const double tolerance = 1e-7;
+
SketchPlugin_ConstraintLength::SketchPlugin_ConstraintLength()
{
+ myFlyoutUpdate = false;
}
void SketchPlugin_ConstraintLength::initAttributes()
//if(!aValueAttr->isInitialized()) {
// aValueAttr->setValue(aLenght);
//}
+
+ // the value should to be computed here, not in the getAISObject in order to change the model value
+ // inside the object transaction. This is important for creating a constraint by preselection.
+ // The display of the presentation in this case happens after the transaction commit
+ AttributePtr aFlyOutAttribute = data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
+ if (!aFlyOutAttribute->isInitialized()) {
+ compute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
+ }
}
}
+bool SketchPlugin_ConstraintLength::compute(const std::string& theAttributeId)
+{
+ if (theAttributeId != SketchPlugin_Constraint::FLYOUT_VALUE_PNT())
+ return false;
+
+ std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
+ std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, anEndPoint;
+ if (!getPoints(aPoint1, aPoint2, aStartPoint, anEndPoint))
+ return false;
+
+ std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(data()->attribute(theAttributeId));
+
+ std::shared_ptr<GeomAPI_Lin2d> aLine =
+ std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aStartPoint->pnt(), anEndPoint->pnt()));
+ if (fabs(aFlyOutAttr->x()) < tolerance && fabs(aFlyOutAttr->y()) < tolerance) {
+ double aDist = aPoint1->distance(aPoint2)/5.;
+ std::shared_ptr<GeomAPI_Pnt2d> aFPnt = aLine->shiftedLocation(aDist);
+ aFlyOutAttr->setValue(aFPnt);
+ }
+
+ return true;
+}
+
bool SketchPlugin_ConstraintLength::getPoints(
std::shared_ptr<GeomAPI_Pnt>& thePoint1, std::shared_ptr<GeomAPI_Pnt>& thePoint2,
std::shared_ptr<GeomDataAPI_Point2D>& theStartPoint,
AISObjectPtr SketchPlugin_ConstraintLength::getAISObject(AISObjectPtr thePrevious)
{
- std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
- std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, anEndPoint;
- if (!getPoints(aPoint1, aPoint2, aStartPoint, anEndPoint))
- return thePrevious; // not possible to show length because points are not defined
-
- std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
- std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
- std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = std::shared_ptr<GeomAPI_Pnt>();
- if (aFlyOutAttr->isInitialized()) {
- aFlyoutPnt = sketch()->to3D(aFlyOutAttr->x(), aFlyOutAttr->y());
- } else {
- std::shared_ptr<GeomAPI_Lin2d> aLine =
- std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aStartPoint->pnt(), anEndPoint->pnt()));
- double aDist = aPoint1->distance(aPoint2)/5.;
- std::shared_ptr<GeomAPI_Pnt2d> aFPnt = aLine->shiftedLocation(aDist);
- aFlyOutAttr->setValue(aFPnt);
- aFlyoutPnt = sketch()->to3D(aFPnt->x(), aFPnt->y());
- }
- // value calculation
- // TODO: has to be calculated on definition of reference object
- double aDistance = aPoint1->distance(aPoint2);
- std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
- ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
- double aValue = aDistance;
- if (aValueAttr->isInitialized())
- aValue = aValueAttr->value();
- else
- aValueAttr->setValue(aValue);
- // End TODO
+ if (!sketch())
+ return thePrevious;
AISObjectPtr anAIS = thePrevious;
- if (!anAIS)
- anAIS = AISObjectPtr(new GeomAPI_AISObject);
- anAIS->createDistance(aPoint1, aPoint2, aFlyoutPnt, aPlane, aValue);
-
- // Set color from preferences
- std::vector<int> aRGB =
- Config_PropManager::color("Visualization", "length_color", LENGTH_COLOR);
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this, sketch()->coordinatePlane());
+ }
+ std::vector<int> aRGB = Config_PropManager::color("Visualization", "sketch_dimension_color",
+ SKETCH_DIMENSION_COLOR);
anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]);
return anAIS;
}
if (!aData->isValid())
return;
+ AttributeRefAttrPtr aLineAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if (!aLineAttr || !aLineAttr->isObject())
+ return;
+ FeaturePtr aLine = ModelAPI_Feature::feature(aLineAttr->object());
+ if (!aLine || aLine->getKind() != SketchPlugin_Line::ID())
+ return;
+
+ // Recalculate a shift of flyout point in terms of local coordinates
+ std::shared_ptr<GeomAPI_XY> aDir(new GeomAPI_XY(theDeltaX, theDeltaY));
+ std::shared_ptr<GeomAPI_XY> aStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::START_ID()))->pnt()->xy();
+ std::shared_ptr<GeomAPI_XY> aEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::END_ID()))->pnt()->xy();
+ std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ double dX = aDir->dot(aLineDir->xy());
+ double dY = -aDir->cross(aLineDir->xy());
+
+ myFlyoutUpdate = true;
std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
- aPoint->move(theDeltaX, theDeltaY);
+ aPoint->setValue(aPoint->x() + dX, aPoint->y() + dY);
+ myFlyoutUpdate = false;
}
void SketchPlugin_ConstraintLength::attributeChanged(const std::string& theID) {
if (theID == SketchPlugin_Constraint::ENTITY_A())
{
std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
- ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
+ ModelAPI_AttributeDouble>(attribute(SketchPlugin_Constraint::VALUE()));
if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, anEndPoint;
aValueAttr->setValue(aLength);
}
}
+ } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
+ myFlyoutUpdate = true;
+ // Recalculate flyout point in local coordinates of the line:
+ // the X coordinate is a length of projection of the flyout point on the line
+ // the Y coordinate is a distance from the point to the line
+ std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+ AttributeRefAttrPtr aLineAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if (!aLineAttr || !aLineAttr->isObject())
+ return;
+ FeaturePtr aLine = ModelAPI_Feature::feature(aLineAttr->object());
+ if (!aLine || aLine->getKind() != SketchPlugin_Line::ID())
+ return;
+
+ std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
+ std::shared_ptr<GeomAPI_XY> aStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::START_ID()))->pnt()->xy();
+ std::shared_ptr<GeomAPI_XY> aEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLine->attribute(SketchPlugin_Line::END_ID()))->pnt()->xy();
+
+ std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
+ std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aStartPnt);
+ double X = aFlyoutDir->dot(aLineDir->xy());
+ double Y = -aFlyoutDir->cross(aLineDir->xy());
+ aFlyoutAttr->setValue(X, Y);
+ myFlyoutUpdate = false;
}
}