map<string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = myAttrs.begin();
for(; anAttrsIter != myAttrs.end(); anAttrsIter++) {
if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
+ aResult.push_back(anAttrsIter->second);
}
}
return aResult;
bool ModuleBase_WidgetFeature::setFeature(const FeaturePtr& theFeature)
{
- if (!theFeature && myFeatureKinds.contains(theFeature->getKind().c_str()))
+ if (!theFeature || !myFeatureKinds.contains(theFeature->getKind().c_str()))
return false;
//bool isBlocked = this->blockSignals(true);
return SM_FirstPoint;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintDistancePrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- return aPoint2D;
-}
-
boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintDistancePrs::featurePoint
(const PartSet_SelectionMode& theMode)
{
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
protected:
/// Returns the feature point in the selection mode position.
/// \param theMode the current operation selection mode. The feature attribute depends on the mode
return SM_FirstPoint;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintLengthPrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- return aPoint2D;
-}
-
boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintLengthPrs::featurePoint
(const PartSet_SelectionMode& theMode)
{
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
protected:
/// Returns the feature point in the selection mode position.
/// \param theMode the current operation selection mode. The feature attribute depends on the mode
return SM_FirstPoint;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintRadiusPrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- return aPoint2D;
-}
-
boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintRadiusPrs::featurePoint
(const PartSet_SelectionMode& theMode)
{
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
/// Project the view point on the feature. The output coordinates belong to the feature
/// \param theFeature a feature
/// \param theSketch the sketch feature
return aMode;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureArcPrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- if (!theFeature || theFeature->getKind() != getKind())
- return aPoint2D;
-
- boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(ARC_ATTR_CENTER));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
- fabs(aPoint->y() - theY) < Precision::Confusion()) {
- aPoint2D = aPoint;
- }
- if (!aPoint2D) {
- aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(ARC_ATTR_START));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
- fabs(aPoint->y() - theY) < Precision::Confusion())
- aPoint2D = aPoint;
- }
- if (!aPoint2D) {
- aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(ARC_ATTR_END));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
- fabs(aPoint->y() - theY) < Precision::Confusion())
- aPoint2D = aPoint;
- }
- return aPoint2D;
-}
-
void PartSet_FeatureArcPrs::projectPointOnFeature(FeaturePtr theFeature, FeaturePtr theSketch,
gp_Pnt& thePoint, Handle(V3d_View) theView,
double& theX, double& theY)
static void projectPointOnFeature(FeaturePtr theFeature, FeaturePtr theSketch, gp_Pnt& thePoint,
Handle_V3d_View theView, double& theX, double& theY);
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
-
/// Computes the feature's radius
/// \param theFeature an arc feature
/// \return the double value
return aMode;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureCirclePrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- if (!theFeature || theFeature->getKind() != getKind())
- return aPoint2D;
-
- boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(CIRCLE_ATTR_CENTER));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() )
- aPoint2D = aPoint;
-
- return aPoint2D;
-}
-
void PartSet_FeatureCirclePrs::projectPointOnFeature(FeaturePtr theFeature, FeaturePtr theSketch,
gp_Pnt& thePoint, Handle(V3d_View) theView,
double& theX, double& theY)
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
/// Project the view point on the feature. The output coordinates belong to the feature
/// \param theFeature a feature
/// \param theSketch the sketch feature
}
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- if (!theFeature || theFeature->getKind() != getKind())
- return aPoint2D;
-
- boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
- fabs(aPoint->y() - theY) < Precision::Confusion())
- aPoint2D = aPoint;
- else {
- aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
- fabs(aPoint->y() - theY) < Precision::Confusion())
- aPoint2D = aPoint;
- }
- return aPoint2D;
-}
-
boost::shared_ptr<GeomAPI_Lin2d> PartSet_FeatureLinePrs::createLin2d(FeaturePtr theFeature)
{
boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin;
const gp_Pnt& thePoint, Handle_V3d_View theView,
double& theX, double& theY);
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
-
/// Creates a lin 2d object on a base of the line feature
/// \param theFeature the line feature
static boost::shared_ptr<GeomAPI_Lin2d> createLin2d(FeaturePtr theFeature);
return aMode;
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeaturePointPrs::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- if (!theFeature || theFeature->getKind() != getKind())
- return aPoint2D;
-
- boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(POINT_ATTR_COORD));
- if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() )
- aPoint2D = aPoint;
-
- return aPoint2D;
-}
-
boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeaturePointPrs::featurePoint
(const PartSet_SelectionMode& theMode)
{
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
-
protected:
/// Returns the feature point in the selection mode position.
/// \param theMode the current operation selection mode. The feature attribute depends on the mode
/// \return next attribute selection mode
virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const = 0;
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- virtual boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY) = 0;
-
protected:
/// Returns the operation feature
/// \return the feature
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Arc.h>
#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintRadius.h>
+#include <SketchPlugin_ConstraintParallel.h>
+#include <SketchPlugin_ConstraintPerpendicular.h>
#include <GeomAPI_Pnt2d.h>
bool PartSet_OperationFeatureCreate::canProcessKind(const std::string& theId)
{
return theId == SKETCH_LINE_KIND || theId == SKETCH_POINT_KIND ||
- theId == SKETCH_CONSTRAINT_DISTANCE_KIND || theId == SKETCH_CIRCLE_KIND /*||
- theId == SKETCH_ARC_KIND*/;
+ theId == SKETCH_CIRCLE_KIND /*||
+ theId == SKETCH_ARC_KIND*/ ||
+ theId == SKETCH_CONSTRAINT_DISTANCE_KIND ||
+ theId == SKETCH_CONSTRAINT_LENGTH_KIND ||
+ theId == SKETCH_CONSTRAINT_RADIUS_KIND ||
+ theId == SKETCH_CONSTRAINT_PARALLEL_KIND ||
+ theId == SKETCH_CONSTRAINT_PERPENDICULAR_KIND;
}
bool PartSet_OperationFeatureCreate::canBeCommitted() const
}
void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature,
- const std::string& theAttribute, double theX, double theY)
+ const std::string& theAttribute,
+ double theClickedX, double theClickedY)
{
// find a feature point by the selection mode
//boost::shared_ptr<GeomDataAPI_Point2D> aPoint = featurePoint(theMode);
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ boost::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
- if (!aPoint)
+ if (!aFeaturePoint)
return;
// get all sketch features. If the point with the given coordinates belong to any sketch feature,
std::list<FeaturePtr > aFeatures = aRefList->list();
std::list<FeaturePtr >::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
+ std::list<boost::shared_ptr<ModelAPI_Attribute> > anAttiributes;
+ boost::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = boost::shared_ptr<GeomAPI_Pnt2d>
+ (new GeomAPI_Pnt2d(theClickedX, theClickedY));
for (; anIt != aLast; anIt++)
{
FeaturePtr aFeature = *anIt;
- boost::shared_ptr<GeomDataAPI_Point2D> aFPoint;// = aFeature->findPoint(theX, theY);
+ // find the given point in the feature attributes
+ anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type());
+ std::list<boost::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
+ aLast = anAttiributes.end();
+ boost::shared_ptr<GeomDataAPI_Point2D> aFPoint;
+ for (;anIt!=aLast && !aFPoint; anIt++) {
+ boost::shared_ptr<GeomDataAPI_Point2D> aCurPoint =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
+ if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())
+ aFPoint = aCurPoint;
+ }
if (aFPoint)
- PartSet_Tools::createConstraint(theSketch, aFPoint, aPoint);
+ PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint);
}
}
-boost::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findPoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- boost::shared_ptr<PartSet_FeaturePrs> aFeaturePrs = PartSet_Tools::createFeaturePrs(
- theFeature->getKind(), FeaturePtr(), theFeature);
-
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
- if (aFeaturePrs)
- aPoint2D = aFeaturePrs->findPoint(theFeature, theX, theY);
-
- return aPoint2D;
-}
-
boost::shared_ptr<GeomAPI_Pln> PartSet_Tools::sketchPlane(FeaturePtr theSketch)
{
boost::shared_ptr<GeomAPI_Pln> aPlane;
/// \param theSketch a sketch feature
/// \param theFeature a source feature
/// \param theAttribute a name of the requried attribute attribute
- /// \param theX the horizontal coordnate of the point
- /// \param theY the vertical coordnate of the point
+ /// \param theClickedX the horizontal coordnate of the point
+ /// \param theClickedY the vertical coordnate of the point
static void setConstraints(FeaturePtr theSketch, FeaturePtr theFeature,
- const std::string& theAttribute, double theX, double theY);
-
- /// Find a point in the line with given coordinates
- /// \param theFeature the line feature
- /// \param theX the horizontal point coordinate
- /// \param theY the vertical point coordinate
- static boost::shared_ptr<GeomDataAPI_Point2D> findPoint(FeaturePtr theFeature, double theX,
- double theY);
+ const std::string& theAttribute, double theClickedX, double theClickedY);
/// Create a sketch plane instance
/// \param theSketch a sketch feature
boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr_B =
boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_B));
- AttributeDoublePtr anAttribute =
+ AttributeDoublePtr anAttr_Value =
boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_VALUE));
-
- if (anAttr_A && anAttr_B && anAttribute->value() == 0)
+ if (anAttr_A && anAttr_B && !anAttr_Value->isInitialized())
{
FeaturePtr aFeature_A = anAttr_A->feature();
FeaturePtr aFeature_B = anAttr_B->feature();
double aValue = 40; // TODO
- anAttribute->setValue(aValue);
+ anAttr_Value->setValue(aValue);
}
}
#include "SketchPlugin_ConstraintLength.h"
#include <SketchPlugin_Line.h>
+#include <GeomDataAPI_Point2D.h>
+
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Data.h>
{
data()->addAttribute(CONSTRAINT_ATTR_VALUE, ModelAPI_AttributeDouble::type());
data()->addAttribute(CONSTRAINT_ATTR_FLYOUT_VALUE, ModelAPI_AttributeDouble::type());
+ data()->addAttribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT, GeomDataAPI_Point2D::type());
data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
}
return anAIS;
}
+void SketchPlugin_ConstraintLength::move(double theDeltaX, double theDeltaY)
+{
+ boost::shared_ptr<ModelAPI_Data> aData = data();
+ if (!aData->isValid())
+ return;
+
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT));
+ aPoint1->setValue(aPoint1->x() + theDeltaX, aPoint1->y() + theDeltaY);
+}
+
/// Returns the AIS preview
SKETCHPLUGIN_EXPORT virtual Handle_AIS_InteractiveObject getAISShape(Handle_AIS_InteractiveObject thePrevious);
+ /// Moves the feature
+ /// \param theDeltaX the delta for X coordinate is moved
+ /// \param theDeltaY the delta for Y coordinate is moved
+ SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
+
/// \brief Use plugin manager for features creation
SketchPlugin_ConstraintLength();
};
// compute a start point in 3D view
boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_START));
- boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
// compute an end point in 3D view
boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_END));
- boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
- // make linear edge
- boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
- setPreview(anEdge);
+ if (aStartAttr->isInitialized() && anEndAttr->isInitialized()) {
+ boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
+ boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+ // make linear edge
+ boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
+ setPreview(anEdge);
+ }
}
return getPreview();
}
<plugin>
<workbench id="Sketch">
<group id="Basic">
- <feature id="Sketch" nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance" title="Sketch" tooltip="Create a new sketch or edit an existing sketch" icon=":icons/sketch.png">
+ <feature id="Sketch" nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular" title="Sketch" tooltip="Create a new sketch or edit an existing sketch" icon=":icons/sketch.png">
<label title="Select a plane on which to create a sketch" tooltip="Select a plane on which to create a sketch"/>
<!--icon=":pictures/x_point.png"-->
</feature>
<label title="Select point and another feature (point or point on line) between which to calculate distance" tooltip="Select point and another feature (point or point on line) between which to calculate distance"/>
<feature_selector id="ConstraintEntityA" keysequence="SketchPoint" internal="1"/>
<feature_selector id="ConstraintEntityB" keysequence="SketchPoint" internal="1"/>
- <point_selector id="ConstraintFlyoutValuePnt" title="Flyout point" tooltip="Flyout" internal="1"/>
- <doublevalue_editor id="ConstraintValue" min="0" step="1.0" tooltip="Constraint value"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <doublevalue_editor id="ConstraintValue"/>
</feature>
<feature id="SketchConstraintLength" title="Length of a line" tooltip="Create constraint for the given length of a line segment">
<label title="Select a line entity on which to calculate lenght" tooltip="Select a line entity on which to calculate lenght"/>
+ <feature_selector id="ConstraintEntityA" keysequence="SketchLine" internal="1"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <doublevalue_editor id="ConstraintValue"/>
</feature>
<feature id="SketchConstraintRadius" title="Radius of a circle or an arc" tooltip="Create constraint for the given radius of a circle or an arc">
<label title="Select two points on a circle or an arc of circle on which to calculate radius" tooltip="Select two points on a circle or an arc of circle on which to calculate radius"/>
+ <feature_selector id="ConstraintEntityA" keysequence="SketchPoint" internal="1"/>
+ <point_selector id="CirclePoint" internal="1"/>
+ <doublevalue_editor id="ConstraintValue"/>
+ </feature>
+ <feature id="SketchConstraintParallel" title="Parallelism of a lines" tooltip="Create constraint defining two parallel lines">
+ <feature_selector id="ConstraintEntityA" keysequence="SketchLine" internal="1"/>
+ <feature_selector id="ConstraintEntityB" keysequence="SketchLine" internal="1"/>
+ </feature>
+ <feature id="SketchConstraintPerpendicular" title="Orthgonality of a lines" tooltip="Create constraint defining two perpendicular lines">
+ <feature_selector id="ConstraintEntityA" keysequence="SketchLine" internal="1"/>
+ <feature_selector id="ConstraintEntityB" keysequence="SketchLine" internal="1"/>
</feature>
- <feature id="SketchConstraintParallel" title="Parallelism of a lines" tooltip="Create constraint defining two parallel lines" internal="1"/>
- <feature id="SketchConstraintPerpendicular" title="Orthgonality of a lines" tooltip="Create constraint defining two perpendicular lines" internal="1"/>
</group>
</workbench>
</plugin>
boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
);
- if (!anAttr || !anAttr->isFeature()) continue;
+ if (!anAttr || !anAttr->isFeature() || !anAttr->feature()) continue;
const std::string& aKind = anAttr->feature()->getKind();
if (aKind.compare(SKETCH_LINE_KIND) == 0)
{