* Improve the Projection feature by an option to break the link with the original shape.
* Update unit-tests for ellipse's projection, because of solved OCCT issue #31016.
Handle(Geom_Curve) aCurve = theCurve->impl<Handle_Geom_Curve>();
Handle(Geom_Plane) aPlane = new Geom_Plane(myPlane->impl<gp_Ax3>());
- Handle(Geom_Curve) aProj = GeomProjLib::Project(aCurve, aPlane);
+ Handle(Geom_Curve) aProj =
+ GeomProjLib::ProjectOnPlane(aCurve, aPlane, aPlane->Axis().Direction(), false);
GeomCurvePtr aProjCurve(new GeomAPI_Curve);
aProjCurve->setImpl(new Handle_Geom_Curve(aProj));
aCaseId = QString::fromStdString(aStringAttr->value());
else
aCaseId = QString::fromStdString(aDefVal.empty() ? aStringAttr->value() : aDefVal);
- myIsFirst = false;
+ if (myIsFirst)
+ storeValueCustom();
int idx = myCaseIds.indexOf(aCaseId);
if (idx == -1)
idx = currentPageIndex();
#include <ModuleBase_WidgetRadiobox.h>
#include <ModuleBase_PageBase.h>
+#include <Config_WidgetAPI.h>
+
#include <QFormLayout>
#include <QRadioButton>
#include <QFrame>
#include <QButtonGroup>
-
ModuleBase_WidgetRadiobox::ModuleBase_WidgetRadiobox(QWidget* theParent,
const Config_WidgetAPI* theData)
: ModuleBase_PagedContainer(theParent, theData)
myGroup = new QButtonGroup(this);
myGroup->setExclusive(true);
+ myVerticalAlignment = theData->getProperty("align_subs").find("vert") == 0;
+
connect(myGroup, SIGNAL(buttonToggled(int, bool)), SLOT(onPageChanged()));
}
//QFrame* aFrame = dynamic_cast<QFrame*>(thePage);
QWidget* aPage = thePage->pageWidget();
- myLayout->addRow(aWgt, aPage);
+ if (myVerticalAlignment) {
+ myLayout->addRow(aWgt);
+ myLayout->addRow(aPage);
+ } else
+ myLayout->addRow(aWgt, aPage);
myGroup->addButton(aButton, myGroup->buttons().count());
bool isDefault = theCaseId.toStdString() == getDefaultValue();
private:
QFormLayout* myLayout;
QButtonGroup* myGroup;
+ bool myVerticalAlignment;
};
#endif
\ No newline at end of file
for (aIt = aRefsToMe.cbegin(); aIt != aRefsToMe.cend(); ++aIt) {
if ((*aIt)->id() == SketchPlugin_Projection::PROJECTED_FEATURE_ID()) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
- if (aFeature.get()) {
+ if (aFeature.get() && !aFeature->isMacro()) {
anAttr = aFeature->data()->boolean(SketchPlugin_Projection::INCLUDE_INTO_RESULT());
if (anAttr.get())
return anAttr->value();
%feature("kwargs") SketchAPI_BSpline::controlPolygon;
%feature("kwargs") SketchAPI_Ellipse::construction;
%feature("kwargs") SketchAPI_EllipticArc::construction;
-%feature("kwargs") SketchAPI_Sketch::addSpline;
-%feature("kwargs") SketchAPI_Sketch::addInterpolation;
%feature("kwargs") SketchAPI_Sketch::addApproximation;
+%feature("kwargs") SketchAPI_Sketch::addInterpolation;
+%feature("kwargs") SketchAPI_Sketch::addProjection;
+%feature("kwargs") SketchAPI_Sketch::addSpline;
%feature("kwargs") SketchAPI_Sketch::setAngle;
// shared pointers
}
}
-SketchAPI_Projection::SketchAPI_Projection(
- const std::shared_ptr<ModelAPI_Feature> & theFeature,
- const std::wstring & theExternalName)
-: SketchAPI_SketchEntity(theFeature)
-{
- if (initialize()) {
- setByExternalName(theExternalName);
- }
-}
-
SketchAPI_Projection::~SketchAPI_Projection()
{
execute(true);
}
-void SketchAPI_Projection::setByExternalName(const std::wstring& theExternalName)
+void SketchAPI_Projection::setIncludeToResult(bool theKeepResult)
{
- setExternalFeature(ModelHighAPI_Selection("EDGE", theExternalName));
+ fillAttribute(theKeepResult, includeToResult());
+ execute(true);
}
-void SketchAPI_Projection::setIncludeToResult(bool theKeepResult)
+void SketchAPI_Projection::setKeepReferenceToOriginal(bool theKeepRefToOriginal)
{
- fillAttribute(theKeepResult, includeToResult());
+ // the Fixed constraint should be assigned explicitly
+ fillAttribute(false, feature()->boolean(SketchPlugin_Projection::MAKE_FIXED()));
+ fillAttribute(theKeepRefToOriginal ? "true" : "false",
+ feature()->string(SketchPlugin_Projection::KEEP_REFERENCE_ID()));
execute(true);
}
SKETCHAPI_EXPORT
SketchAPI_Projection(const std::shared_ptr<ModelAPI_Feature> & theFeature,
const ModelHighAPI_Selection & theExternalFeature);
- /// Constructor with values
- SKETCHAPI_EXPORT
- SketchAPI_Projection(const std::shared_ptr<ModelAPI_Feature> & theFeature,
- const std::wstring & theExternalName);
/// Destructor
SKETCHAPI_EXPORT
virtual ~SketchAPI_Projection();
SKETCHAPI_EXPORT
void setExternalFeature(const ModelHighAPI_Selection & theExternalLine);
- /// Set by external name
- SKETCHAPI_EXPORT
- void setByExternalName(const std::wstring & theExternalName);
-
/// Set flag to include projection to result or not
SKETCHAPI_EXPORT
void setIncludeToResult(bool theKeepResult);
+ /// Set flag to keep the reference to the original shape
+ SKETCHAPI_EXPORT
+ void setKeepReferenceToOriginal(bool theKeepRefToOriginal);
+
/// Returns created feature
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_SketchEntity> createdFeature() const;
//--------------------------------------------------------------------------------------
std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
const ModelHighAPI_Selection & theExternalFeature,
- bool theKeepResult)
-{
- std::shared_ptr<ModelAPI_Feature> aFeature =
- compositeFeature()->addFeature(SketchPlugin_Projection::ID());
- ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalFeature));
- aProjection->setIncludeToResult(theKeepResult);
- return aProjection;
-}
-
-std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
- const std::wstring & theExternalName,
- bool theKeepResult)
+ bool keepResult,
+ bool keepRefToOriginal)
{
std::shared_ptr<ModelAPI_Feature> aFeature =
compositeFeature()->addFeature(SketchPlugin_Projection::ID());
- ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalName));
- aProjection->setIncludeToResult(theKeepResult);
+ ProjectionPtr aProjection(new SketchAPI_Projection(aFeature));
+ aProjection->setIncludeToResult(keepResult);
+ aProjection->setKeepReferenceToOriginal(keepRefToOriginal);
+ aProjection->setExternalFeature(theExternalFeature);
return aProjection;
}
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_Projection> addProjection(
const ModelHighAPI_Selection & theExternalFeature,
- bool theKeepResult = false);
-
- /// Add projection
- SKETCHAPI_EXPORT
- std::shared_ptr<SketchAPI_Projection> addProjection(const std::wstring & theExternalName,
- bool theKeepResult = false);
+ bool keepResult = false,
+ bool keepRefToOriginal = true);
/// Add mirror
SKETCHAPI_EXPORT
def test_arc_by_projection(self):
""" Test 10. Create arc by projection of external feature
"""
- self.sketch.addProjection("[Cylinder_2_1/Face_1][Cylinder_2_1/Face_3]")
+ self.sketch.addProjection(model.selection("EDGE", "[Cylinder_2_1/Face_1][Cylinder_2_1/Face_3]"))
model.do()
anArc = SketchAPI.SketchAPI_Arc(model.lastSubFeature(self.sketch, "SketchArc"))
TestProjectionEllipticArc.py
TestProjectionIntoResult.py
TestProjectionUpdate.py
+ TestProjectionWithoutReference.py
TestRectangle.py
TestRemainingDoF.py
TestRemoveBSpline.py
return false;
}
- data()->blockSendAttributeUpdated(true);
+ bool aWasBlocked = data()->blockSendAttributeUpdated(true);
GeomPnt2dPtr aCenter2d = aCenterAttr->pnt();
GeomPnt2dPtr aFocus2d = aFocusAttr->pnt();
GeomDir2dPtr aMajorDir2d(new GeomAPI_Dir2d(aFocus2d->x() - aCenter2d->x(),
AttributeDoublePtr aMajorRadiusAttr = real(MAJOR_RADIUS_ID());
double aFocalDist = aCenter2d->distance(aFocus2d);
double aMajorRadius = sqrt(aFocalDist * aFocalDist + aMinorRadius * aMinorRadius);
- aMajorRadiusAttr->setValue(aMajorRadius);
+ if (!aMajorRadiusAttr->isInitialized() ||
+ fabs(aMajorRadiusAttr->value() - aMajorRadius) > tolerance)
+ aMajorRadiusAttr->setValue(aMajorRadius);
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(SECOND_FOCUS_ID()))
->setValue(2.0 * aCenter2d->x() - aFocus2d->x(), 2.0 * aCenter2d->y() - aFocus2d->y());
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(MINOR_AXIS_END_ID()))
->setValue(aCenter2d->x() + aMinorDir2d->x() * aMinorRadius,
aCenter2d->y() + aMinorDir2d->y() * aMinorRadius);
- data()->blockSendAttributeUpdated(false);
+ data()->blockSendAttributeUpdated(aWasBlocked);
return true;
}
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeDoubleArray.h>
#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeString.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
#include <cmath>
static const double tolerance = 1.e-7;
+static const std::string THE_KEEP_REF("true");
+
+static bool isKeepReference(AttributeStringPtr theAttr)
+{
+ return !theAttr || !theAttr->isInitialized() || theAttr->value() == THE_KEEP_REF;
+}
SketchPlugin_Projection::SketchPlugin_Projection()
{
data()->addAttribute(EXTERNAL_FEATURE_ID(), ModelAPI_AttributeSelection::typeId());
data()->addAttribute(PROJECTED_FEATURE_ID(), ModelAPI_AttributeRefAttr::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PROJECTED_FEATURE_ID());
data()->attribute(PROJECTED_FEATURE_ID())->setIsArgument(false);
data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID());
}
+void SketchPlugin_Projection::initDerivedClassAttributes2()
+{
+ AttributePtr aKeepRefAttr =
+ data()->addAttribute(KEEP_REFERENCE_ID(), ModelAPI_AttributeString::typeId());
+ if (!aKeepRefAttr->isInitialized()) {
+ std::dynamic_pointer_cast<ModelAPI_AttributeString>(aKeepRefAttr)->setValue(THE_KEEP_REF);
+ }
+
+ data()->addAttribute(MAKE_FIXED(), ModelAPI_AttributeBoolean::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), MAKE_FIXED());
+
+ data()->addAttribute(FIXED_CONSTRAINT_ID(), ModelAPI_AttributeReference::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FIXED_CONSTRAINT_ID());
+ data()->attribute(FIXED_CONSTRAINT_ID())->setIsArgument(false);
+}
+
void SketchPlugin_Projection::execute()
{
AttributeRefAttrPtr aRefAttr = data()->refattr(PROJECTED_FEATURE_ID());
return;
FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object());
- if (!lastResult().get()) {
+ if (isKeepReference(string(KEEP_REFERENCE_ID())) && !lastResult().get()) {
bool hasProjResult = aProjection->lastResult().get() != NULL;
ResultConstructionPtr aConstr = document()->createConstruction(data());
if (hasProjResult)
computeProjection(EXTERNAL_FEATURE_ID());
}
+bool SketchPlugin_Projection::isMacro() const
+{
+ if (!data() || !data()->isValid())
+ return false;
+
+ AttributeStringPtr aKeepRefAttr =
+ const_cast<SketchPlugin_Projection*>(this)->string(KEEP_REFERENCE_ID());
+ return !isKeepReference(aKeepRefAttr);
+}
+
void SketchPlugin_Projection::attributeChanged(const std::string& theID)
{
if ((theID == EXTERNAL_FEATURE_ID() || theID == EXTERNAL_ID()) && !myIsComputing) {
if (!isProjected)
return; // projection is not computed, stop processing
- aProjection->boolean(COPY_ID())->setValue(true);
+ bool keepBackRef = isKeepReference(string(KEEP_REFERENCE_ID()));
+
+ aProjection->boolean(COPY_ID())->setValue(keepBackRef);
aProjection->execute();
aRefAttr->setObject(aProjection);
restoreCurrentFeature();
- if (theID == EXTERNAL_FEATURE_ID()) {
- selection(EXTERNAL_ID())->selectValue(aExtFeature);
+ AttributeBooleanPtr aMakeFixedAttr = boolean(MAKE_FIXED());
+ bool isMakeFixed = aMakeFixedAttr && aMakeFixedAttr->isInitialized() && aMakeFixedAttr->value();
+
+ AttributeReferencePtr aFixedConstrAttr = reference(FIXED_CONSTRAINT_ID());
+ FeaturePtr aFixedConstraint;
+ if (aFixedConstrAttr && aFixedConstrAttr->isInitialized())
+ aFixedConstraint = ModelAPI_Feature::feature(aFixedConstrAttr->value());
- if (aResult) {
- aResult->setShape(aProjection->lastResult()->shape());
- setResult(aResult);
- GeomShapePtr anEmptyVal;
- aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), anEmptyVal);
+ if (keepBackRef) {
+ if (theID == EXTERNAL_FEATURE_ID()) {
+ selection(EXTERNAL_ID())->selectValue(aExtFeature);
- static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES);
- ModelAPI_EventCreator::get()->sendUpdated(aProjection, anEvent, false);
+ if (aResult) {
+ aResult->setShape(aProjection->lastResult()->shape());
+ setResult(aResult);
+ GeomShapePtr anEmptyVal;
+ aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), anEmptyVal);
+ }
}
}
+ else if (isMakeFixed) {
+ // fix the projected entity with the Fixed constraint
+ if (!aFixedConstraint)
+ aFixedConstraint = sketch()->addFeature(SketchPlugin_ConstraintRigid::ID());
+ aFixedConstraint->refattr(SketchPlugin_Constraint::ENTITY_A())->setObject(
+ aProjection->lastResult());
+ }
+
+
+ // remove Fixed constraint in case of redundance
+ if (aFixedConstraint && (keepBackRef || !isMakeFixed)) {
+ document()->removeFeature(aFixedConstraint);
+ aFixedConstraint = FeaturePtr();
+ }
+ aFixedConstrAttr->setValue(aFixedConstraint);
+
+ static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES);
+ ModelAPI_EventCreator::get()->sendUpdated(aProjection, anEvent, false);
}
bool SketchPlugin_Projection::rebuildProjectedFeature(
return MY_INCLUDE;
}
+ static const std::string& KEEP_REFERENCE_ID()
+ {
+ static std::string ID("keep_reference");
+ return ID;
+ }
+
+ static const std::string& MAKE_FIXED()
+ {
+ static std::string ID("make_fixed");
+ return ID;
+ }
+
+ static const std::string& FIXED_CONSTRAINT_ID()
+ {
+ static std::string ID("fixed_constraint");
+ return ID;
+ }
+
/// Returns true because projected feature is always external
virtual bool isFixed()
{ return true; }
/// Called on change of any argument-attribute of this object: for external point
SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+ /// Returns true if this feature is used as macro: creates other features and then removed.
+ /// This feature may change its macro-state according to selected item.
+ /// \returns false by default
+ SKETCHPLUGIN_EXPORT virtual bool isMacro() const;
+
/// Use plugin manager for features creation
SketchPlugin_Projection();
/// \brief Initializes attributes of derived class.
virtual void initDerivedClassAttributes();
+ /// \brief Initializes attributes of keeping the reference to the original shape.
+ virtual void initDerivedClassAttributes2();
+
private:
/// \brief Find projection of a feature onto sketch plane
void computeProjection(const std::string& theID);
anAttr = data()->addAttribute(PARENT_ID(), ModelAPI_AttributeReference::typeId());
anAttr->setIsArgument(false);
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PARENT_ID());
+
+ // initialize the rest of attributes
+ initDerivedClassAttributes2();
}
/// \brief Initializes attributes of derived class.
virtual void initDerivedClassAttributes(){};
+ /// \brief Initializes attributes of derived class which were added recently.
+ virtual void initDerivedClassAttributes2(){};
+
};
#endif
std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
std::shared_ptr<GeomAPI_Dir> anEllipseNormal = anEllipse->normal();
double aDot = fabs(aNormal->dot(anEllipseNormal));
- aValid = fabs(aDot - 1.0) <= tolerance * tolerance;
+ aValid = aDot >= tolerance * tolerance;
if (!aValid)
theError.arg(anEdge->isClosed() ? "Error: Ellipse is orthogonal to the sketch plane."
: "Error: Elliptic Arc is orthogonal to the sketch plane.");
<translation>Edges in selected point has tangent constraint</translation>
</message>
</context>
-
+
+ <context>
+ <name>SketchProjection</name>
+ <message>
+ <source>Project feature onto sketch plane</source>
+ <translation>Project feature onto sketch plane</translation>
+ </message>
+ <message>
+ <source>Projection</source>
+ <translation>Projection</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:ExternalFeature</name>
+ <message>
+ <source>Attribute "%1" is not initialized.</source>
+ <translation>Select external edge or vertex.</translation>
+ </message>
+ <message>
+ <source>Object</source>
+ <translation>Object</translation>
+ </message>
+ <message>
+ <source>Select external edge or vertex.</source>
+ <translation>Select external edge or vertex.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:IncludeToResult</name>
+ <message>
+ <source>Include into the sketch result</source>
+ <translation>Include into the sketch result</translation>
+ </message>
+ <message>
+ <source>Include projected feature into the sketch result</source>
+ <translation>Include projected feature into the sketch result</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:keep_reference</name>
+ <message>
+ <source>A sketch entity will be created without connection to the selected shape.</source>
+ <translation>A sketch entity will be created without connection to the selected shape.</translation>
+ </message>
+ <message>
+ <source>The reference to the original curve is stored. So it can be changed later.</source>
+ <translation>The reference to the original curve is stored. So it can be changed later.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:make_fixed</name>
+ <message>
+ <source>Assign the Fixed constraint to the result of projection</source>
+ <translation>Assign the Fixed constraint to the result of projection</translation>
+ </message>
+ <message>
+ <source>Make projected curve fixed</source>
+ <translation>Make projected curve fixed</translation>
+ </message>
+ </context>
<context>
<name>SketchProjection:ExternalFeature:SketchPlugin_ProjectionValidator</name>
<message>
<translation>Error: Selected object is not supported for projection.</translation>
</message>
</context>
- <context>
- <name>SketchProjection:Model_FeatureValidator</name>
- <message>
- <source>Attribute "%1" is not initialized.</source>
- <translation></translation>
- </message>
- </context>
<!-- SketchCurveFitting -->
<context>
</message>
</context>
- <context>
- <name>SketchProjection:ExternalFeature:SketchPlugin_ProjectionValidator</name>
- <message>
- <source>The attribute with the %1 type is not processed</source>
- <translation>Un argument de type %1 de la fonctionnalité de projection n'est pas pris en charge</translation>
- </message>
- <message>
- <source>The attribute %1 should be an edge</source>
- <translation>L'attribut %1 doit être une arête</translation>
- </message>
- <message>
- <source>There is no sketch referring to the current feature</source>
- <translation>La fonction de projection n'a pas d'esquisse</translation>
- </message>
- <message>
- <source>The attribute %1 should be an edge or vertex</source>
- <translation>L'élément projeté doit être une arête ou un sommet</translation>
- </message>
- <message>
- <source>Unable to project feature from the same sketch</source>
- <translation>Les fonctions de l'esquisse en cours ne peuvent pas être projetées</translation>
- </message>
- <message>
- <source>Error: Line is orthogonal to the sketch plane.</source>
- <translation>Erreur: La ligne est orthogonale au plan d'esquisse.</translation>
- </message>
- <message>
- <source>Error: Circle is orthogonal to the sketch plane.</source>
- <translation>Erreur: Le cercle est orthogonal au plan d'esquisse.</translation>
- </message>
- <message>
- <source>Error: Arc is orthogonal to the sketch plane.</source>
- <translation>Erreur: L'arc est orthogonal au plan d'esquisse.</translation>
- </message>
- <message>
- <source>Error: Ellipse is orthogonal to the sketch plane.</source>
- <translation>Erreur: L'ellipse est orthogonale au plan d'esquisse.</translation>
- </message>
- <message>
- <source>Error: Elliptic Arc is orthogonal to the sketch plane.</source>
- <translation>Erreur: L'arc d'ellipse est orthogonal au plan d'esquisse.</translation>
- </message>
- <message>
- <source>Error: Selected object is not supported for projection.</source>
- <translation>Erreur: L'objet sélectionné n'est pas pris en charge pour la projection.</translation>
- </message>
- </context>
- <context>
- <name>SketchProjection:Model_FeatureValidator</name>
- <message>
- <source>Attribute "%1" is not initialized.</source>
- <translation>L'attribut "%1" n'est pas initialisé.</translation>
- </message>
- </context>
- <context>
- <name>SketchProjection:ExternalFeature</name>
- <message>
- <source>Attribute "%1" is not initialized.</source>
- <translation>L'attribut "%1" n'est pas initialisé.</translation>
- </message>
- <message>
- <source>Object</source>
- <translation>Objet</translation>
- </message>
- <message>
- <source>Select external edge or vertex.</source>
- <translation>Sélectionnez une arête externe ou un sommet.</translation>
- </message>
- </context>
-
<context>
<name>Sketch</name>
<message>
<translation>Inclure la fonctionnalité projetée dans le résultat de l'esquisse</translation>
</message>
</context>
+ <context>
+ <name>SketchProjection:keep_reference</name>
+ <message>
+ <source>A sketch entity will be created without connection to the selected shape.</source>
+ <translation>Une entité d'esquisse sera créée sans connexion à la forme sélectionnée.</translation>
+ </message>
+ <message>
+ <source>The reference to the original curve is stored. So it can be changed later.</source>
+ <translation>La référence à la courbe d'origine est stockée. Elle peut donc être modifiée ultérieurement.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:make_fixed</name>
+ <message>
+ <source>Assign the Fixed constraint to the result of projection</source>
+ <translation>Affectez la contrainte Fixe au résultat de la projection</translation>
+ </message>
+ <message>
+ <source>Make projected curve fixed</source>
+ <translation>Fixer la courbe projetée</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:ExternalFeature:SketchPlugin_ProjectionValidator</name>
+ <message>
+ <source>The attribute with the %1 type is not processed</source>
+ <translation>Un argument de type %1 de la fonctionnalité de projection n'est pas pris en charge</translation>
+ </message>
+ <message>
+ <source>The attribute %1 should be an edge</source>
+ <translation>L'attribut %1 doit être une arête</translation>
+ </message>
+ <message>
+ <source>There is no sketch referring to the current feature</source>
+ <translation>La fonction de projection n'a pas d'esquisse</translation>
+ </message>
+ <message>
+ <source>The attribute %1 should be an edge or vertex</source>
+ <translation>L'élément projeté doit être une arête ou un sommet</translation>
+ </message>
+ <message>
+ <source>Unable to project feature from the same sketch</source>
+ <translation>Les fonctions de l'esquisse en cours ne peuvent pas être projetées</translation>
+ </message>
+ <message>
+ <source>Error: Line is orthogonal to the sketch plane.</source>
+ <translation>Erreur: La ligne est orthogonale au plan d'esquisse.</translation>
+ </message>
+ <message>
+ <source>Error: Circle is orthogonal to the sketch plane.</source>
+ <translation>Erreur: Le cercle est orthogonal au plan d'esquisse.</translation>
+ </message>
+ <message>
+ <source>Error: Arc is orthogonal to the sketch plane.</source>
+ <translation>Erreur: L'arc est orthogonal au plan d'esquisse.</translation>
+ </message>
+ <message>
+ <source>Error: Ellipse is orthogonal to the sketch plane.</source>
+ <translation>Erreur: L'ellipse est orthogonale au plan d'esquisse.</translation>
+ </message>
+ <message>
+ <source>Error: Elliptic Arc is orthogonal to the sketch plane.</source>
+ <translation>Erreur: L'arc d'ellipse est orthogonal au plan d'esquisse.</translation>
+ </message>
+ <message>
+ <source>Error: Selected object is not supported for projection.</source>
+ <translation>Erreur: L'objet sélectionné n'est pas pris en charge pour la projection.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:Model_FeatureValidator</name>
+ <message>
+ <source>Attribute "%1" is not initialized.</source>
+ <translation>L'attribut "%1" n'est pas initialisé.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchProjection:ExternalFeature</name>
+ <message>
+ <source>Attribute "%1" is not initialized.</source>
+ <translation>Sélectionnez une arête externe ou un sommet.</translation>
+ </message>
+ <message>
+ <source>Object</source>
+ <translation>Objet</translation>
+ </message>
+ <message>
+ <source>Select external edge or vertex.</source>
+ <translation>Sélectionnez une arête externe ou un sommet.</translation>
+ </message>
+ </context>
<context>
<name>SketchRectangle</name>
from GeomAPI import *
+circle = SketchCircle_2.results()[-1].resultSubShapePair()[0].shape()
+assert(circle.isEdge() and circle.edge().isCircle())
ellipse1 = SketchEllipse_1.results()[-1].resultSubShapePair()[0].shape()
assert(ellipse1.isEdge() and ellipse1.edge().isEllipse())
ellipse2 = SketchEllipse_2.results()[-1].resultSubShapePair()[0].shape()
assert(ellipse2.isEdge() and ellipse2.edge().isEllipse())
-# TODO [limitation]: projection of an ellipse to non-parallel plane is forbiden (OCCT issue #31016)
-assert(Sketch_2.feature().error() != "")
-
assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+"""
+ Test projection without the reference to the source geometry.
+"""
+
+import unittest
+
+from salome.shaper import model
+from GeomAPI import *
+from ModelAPI import *
+
+__updated__ = "2020-07-07"
+
+CURVES = []
+PLANE = None
+
+class TestProjectionWithoutRef(unittest.TestCase):
+ def setUp(self):
+ model.begin()
+ self.myDocument = model.moduleDocument()
+ self.mySketch = model.addSketch(partSet, model.selection("FACE", PLANE.name()))
+ self.myDOF = 0
+ self.myNbPoints = 1
+ self.myNbLines = 1
+ self.myNbCircles = 0
+ self.myNbArcs = 0
+ self.myNbEllipses = 2
+ self.myNbEllipticArcs = 2
+ self.myNbSplines = 1
+ self.myNbPeriodicSplines = 1
+ self.myNbProjections = 0
+ self.myNbFixedConstraints = 0
+ self.myNbEdgesInSketch = 0
+
+ def tearDown(self):
+ self.checkDOF()
+ model.end()
+ model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
+ model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
+ model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
+ model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
+ model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
+ model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", self.myNbEllipticArcs)
+ model.testNbSubFeatures(self.mySketch, "SketchBSpline", self.myNbSplines)
+ model.testNbSubFeatures(self.mySketch, "SketchBSplinePeriodic", self.myNbPeriodicSplines)
+ model.testNbSubFeatures(self.mySketch, "SketchProjection", self.myNbProjections)
+ model.testNbSubFeatures(self.mySketch, "SketchConstraintRigid", self.myNbFixedConstraints)
+ nbEdges = 0
+ exp = GeomAPI_ShapeExplorer(self.mySketch.defaultResult().shape(), GeomAPI_Shape.EDGE)
+ while exp.more(): nbEdges += 1; exp.next()
+ self.assertEqual(self.myNbEdgesInSketch, nbEdges)
+
+ def checkDOF(self):
+ self.assertEqual(model.dof(self.mySketch), self.myDOF)
+
+
+ def test_projection_withref_includeintoresult(self):
+ """ Test 1. Projection with the reference to the original shapes. Projected curves are composed into the sketch result.
+ """
+ for c in CURVES:
+ self.mySketch.addProjection(c, keepResult = True)
+ self.myNbProjections = len(CURVES)
+ self.myNbEdgesInSketch = len(CURVES) - 1
+
+ def test_projection_withref_notincludeintoresult(self):
+ """ Test 2. Projection with the reference to the original shapes. Projected curves are NOT included into the sketch result.
+ """
+ for c in CURVES:
+ self.mySketch.addProjection(c, keepResult = False)
+ self.myNbProjections = len(CURVES)
+
+ def test_projection_withoutref_noconstraints(self):
+ """ Test 3. Projection without the reference to the original shapes. No additional constraints applied.
+ """
+ for c in CURVES:
+ self.mySketch.addProjection(c, keepRefToOriginal = False)
+ model.do()
+ self.myNbEdgesInSketch = len(CURVES) - 1
+ self.myDOF += 2 + 4 + 5 + 7 + 5 + 7 + 6 * 2 + 6 * 2
+
+ def test_projection_withoutref_fixed(self):
+ """ Test 4. Projection without the reference to the original shapes. Additionally, Fixed constraints applied.
+ """
+ model.end()
+ # use the low-level API to access the necessary attributes
+ session = ModelAPI_Session.get()
+ for c in CURVES:
+ session.startOperation()
+ proj = featureToCompositeFeature(self.mySketch.feature()).addFeature("SketchProjection")
+ proj.boolean("IncludeToResult").setValue(False)
+ proj.string("keep_reference").setValue("False")
+ proj.boolean("make_fixed").setValue(True)
+ c.fillAttribute(proj.selection("ExternalFeature"))
+ session.finishOperation()
+ self.myNbEdgesInSketch = len(CURVES) - 1
+ self.myNbFixedConstraints = len(CURVES)
+ model.begin()
+
+
+if __name__ == "__main__":
+ model.begin()
+ partSet = model.moduleDocument()
+ Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+ SketchPoint_1 = Sketch_1.addPoint(35, -40)
+ CURVES.append(model.selection("VERTEX", Sketch_1.name() + "/" + SketchPoint_1.name()))
+ SketchLine_1 = Sketch_1.addLine(20, -15, 40, 15)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchLine_1.name()))
+ SketchCircle_1 = Sketch_1.addCircle(65, -30, 20)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchCircle_1.defaultResult().data().name()))
+ SketchArc_1 = Sketch_1.addArc(60, 15, 80, 0, 50, 33, False)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchArc_1.defaultResult().data().name()))
+ SketchEllipse_1 = Sketch_1.addEllipse(25, 30, 40, 30, 10)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchEllipse_1.defaultResult().data().name()))
+ SketchEllipticArc_1 = Sketch_1.addEllipticArc(40, 70, 55, 70, 45, 50, 25, 56, False)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchEllipticArc_1.defaultResult().data().name()))
+ SketchBSpline_1_poles = [(95, -50), (130, -10), (100, 10), (125, 45), (90, 70), (55, 45)]
+ SketchBSpline_1 = Sketch_1.addSpline(poles = SketchBSpline_1_poles)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchBSpline_1.name()))
+ SketchBSplinePeriodic_1_poles = [(95, 80), (135, 90), (145, 55), (130, 30), (125, 70), (105, 60)]
+ SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = SketchBSplinePeriodic_1_poles, periodic = True)
+ CURVES.append(model.selection("EDGE", Sketch_1.name() + "/" + SketchBSplinePeriodic_1.name()))
+ model.do()
+ PLANE = model.addPlane(partSet, model.selection("FACE", "XOY"), model.selection("EDGE", "OY"), 45)
+ model.end()
+
+ test_program = unittest.main(exit=False)
+ assert test_program.result.wasSuccessful(), "Test failed"
+ assert model.checkPythonDump()
use_sketch_plane="false">
<validator id="SketchPlugin_ProjectionValidator"/>
</sketch_shape_selector>
- <boolvalue id="IncludeToResult" label="Include into the sketch result" default="true" tooltip="Include projected feature into the sketch result"
- change_visual_attributes="true"/>
+ <radiobox id="keep_reference"
+ align_subs="vertical">
+ <radio id="true"
+ title="Keep reference to the original shape"
+ tooltip="The reference to the original curve is stored. So it can be changed later.">
+ <boolvalue id="IncludeToResult"
+ label="Include into the sketch result"
+ default="true"
+ tooltip="Include projected feature into the sketch result"
+ change_visual_attributes="true"/>
+ </radio>
+ <radio id="false"
+ title="Break connection with the original shape"
+ tooltip="A sketch entity will be created without connection to the selected shape.">
+ <boolvalue id="make_fixed"
+ label="Make projected curve fixed"
+ default="true"
+ tooltip="Assign the Fixed constraint to the result of projection"/>
+ </radio>
+ </radiobox>
<validator id="PartSet_ProjectionSelection"/>
</feature>
for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
aRefIt != aRefs.end(); ++aRefIt) {
FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
- if (anOwner && anOwner->getKind() == theFeatureKind)
+ if (anOwner && !anOwner->isMacro() && anOwner->getKind() == theFeatureKind)
return true;
}
return false;