execute(true);
}
+void SketchAPI_Projection::setIncludeToResult(bool theKeepResult)
+{
+ fillAttribute(theKeepResult, includeToResult());
+ execute(true);
+}
+
//--------------------------------------------------------------------------------------
std::shared_ptr<SketchAPI_SketchEntity> SketchAPI_Projection::createdFeature() const
{
const std::string& aSketchName = theDumper.parentName(aBase);
AttributeSelectionPtr anExternal = externalFeature();
- theDumper << aBase << " = " << aSketchName << ".addProjection(" << anExternal << ")" << std::endl;
+ AttributeBooleanPtr isIncludeToRes = includeToResult();
+ theDumper << aBase << " = " << aSketchName << ".addProjection("
+ << anExternal << ", " << isIncludeToRes << ")" << std::endl;
// dump "auxiliary" flag if necessary
SketchAPI_SketchEntity::dump(theDumper);
SKETCHAPI_EXPORT
virtual ~SketchAPI_Projection();
- INTERFACE_3(SketchPlugin_Projection::ID(),
+ INTERFACE_4(SketchPlugin_Projection::ID(),
externalFeature, SketchPlugin_Projection::EXTERNAL_FEATURE_ID(),
ModelAPI_AttributeSelection, /** External feature */,
projectedFeature, SketchPlugin_Projection::PROJECTED_FEATURE_ID(),
ModelAPI_AttributeRefAttr, /** Projected feature */,
external, SketchPlugin_Projection::EXTERNAL_ID(),
- ModelAPI_AttributeSelection, /** External */
+ ModelAPI_AttributeSelection, /** External */,
+ includeToResult, SketchPlugin_Projection::INCLUDE_INTO_RESULT(),
+ ModelAPI_AttributeBoolean, /** Include into result */
)
/// Set external feature
SKETCHAPI_EXPORT
void setByExternalName(const std::string & theExternalName);
+ /// Set flag to include projection to result or not
+ SKETCHAPI_EXPORT
+ void setIncludeToResult(bool theKeepResult);
+
/// Returns created feature
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_SketchEntity> createdFeature() const;
//--------------------------------------------------------------------------------------
std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
- const ModelHighAPI_Selection & theExternalFeature)
+ const ModelHighAPI_Selection & theExternalFeature,
+ bool theKeepResult)
{
std::shared_ptr<ModelAPI_Feature> aFeature =
compositeFeature()->addFeature(SketchPlugin_Projection::ID());
- return ProjectionPtr(new SketchAPI_Projection(aFeature, theExternalFeature));
+ ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalFeature));
+ aProjection->setIncludeToResult(theKeepResult);
+ return aProjection;
}
std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
- const std::string & theExternalName)
+ const std::string & theExternalName,
+ bool theKeepResult)
{
std::shared_ptr<ModelAPI_Feature> aFeature =
compositeFeature()->addFeature(SketchPlugin_Projection::ID());
- return ProjectionPtr(new SketchAPI_Projection(aFeature, theExternalName));
+ ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalName));
+ aProjection->setIncludeToResult(theKeepResult);
+ return aProjection;
}
//--------------------------------------------------------------------------------------
/// Add projection
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_Projection> addProjection(
- const ModelHighAPI_Selection & theExternalFeature);
+ const ModelHighAPI_Selection & theExternalFeature,
+ bool theKeepResult = false);
/// Add projection
SKETCHAPI_EXPORT
- std::shared_ptr<SketchAPI_Projection> addProjection(const std::string & theExternalName);
+ std::shared_ptr<SketchAPI_Projection> addProjection(const std::string & theExternalName,
+ bool theKeepResult = false);
/// Add mirror
SKETCHAPI_EXPORT
TestFilletInteracting.py
TestRectangle.py
TestProjection.py
+ TestProjectionIntoResult.py
TestSplit.py
TestHighload.py
TestSnowflake.py
#include <SketchPlugin_Arc.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
#include <SketchPlugin_Sketch.h>
#include <SketchPlugin_ConstraintRigid.h>
#include <GeomAPI_Lin.h>
#include <GeomAPI_Pnt.h>
#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_Vertex.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomDataAPI_Point2D.h>
data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
+ data()->addAttribute(INCLUDE_INTO_RESULT(), ModelAPI_AttributeBoolean::typeId());
+
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID());
}
}
}
+static bool isValidProjectionType(FeaturePtr theProjection,
+ GeomEdgePtr theEdge,
+ GeomVertexPtr theVertex)
+{
+ if (theVertex && theProjection->getKind() == SketchPlugin_Point::ID())
+ return true;
+ if (theEdge) {
+ if (theEdge->isLine() && theProjection->getKind() == SketchPlugin_Line::ID())
+ return true;
+ else if (theEdge->isCircle() && theProjection->getKind() == SketchPlugin_Circle::ID())
+ return true;
+ else if (theEdge->isArc() && theProjection->getKind() == SketchPlugin_Arc::ID())
+ return true;
+ }
+ return false;
+}
+
void SketchPlugin_Projection::computeProjection(const std::string& theID)
{
AttributeSelectionPtr aExtFeature =
std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(attribute(EXTERNAL_FEATURE_ID()));
- std::shared_ptr<GeomAPI_Edge> anEdge;
- if (aExtFeature && aExtFeature->value() && aExtFeature->value()->isEdge()) {
- anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aExtFeature->value()));
- } else if (aExtFeature->context() && aExtFeature->context()->shape() &&
- aExtFeature->context()->shape()->isEdge()) {
- anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aExtFeature->context()->shape()));
+ GeomShapePtr aShape;
+ GeomEdgePtr anEdge;
+ GeomVertexPtr aVertex;
+ if (aExtFeature)
+ aShape = aExtFeature->value();
+ if (!aShape && aExtFeature->context())
+ aShape = aExtFeature->context()->shape();
+ if (aShape) {
+ if (aShape->isEdge())
+ anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
+ else if (aShape->isVertex())
+ aVertex = GeomVertexPtr(new GeomAPI_Vertex(aShape));
}
- if (!anEdge.get())
+ if (!anEdge && !aVertex)
return;
AttributeRefAttrPtr aRefAttr = data()->refattr(PROJECTED_FEATURE_ID());
// if the type of feature differs with already selected, remove it and create once again
bool hasPrevProj = aProjection.get() != 0;
- if (hasPrevProj) {
- if ((anEdge->isLine() && aProjection->getKind() != SketchPlugin_Line::ID()) ||
- (anEdge->isCircle() && aProjection->getKind() != SketchPlugin_Circle::ID()) ||
- (anEdge->isArc() && aProjection->getKind() != SketchPlugin_Arc::ID())) {
- DocumentPtr aDoc = sketch()->document();
-
- std::set<FeaturePtr> aFeaturesToBeRemoved;
- aFeaturesToBeRemoved.insert(aProjection);
- ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
- aProjection = FeaturePtr();
- aRefAttr->setObject(aProjection);
- }
+ if (hasPrevProj && !isValidProjectionType(aProjection, anEdge, aVertex)) {
+ DocumentPtr aDoc = sketch()->document();
+
+ std::set<FeaturePtr> aFeaturesToBeRemoved;
+ aFeaturesToBeRemoved.insert(aProjection);
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
+ aProjection = FeaturePtr();
+ aRefAttr->setObject(aProjection);
+ hasPrevProj = false;
}
std::shared_ptr<GeomAPI_Pln> aSketchPlane = sketch()->plane();
aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
}
- if (anEdge->isLine()) {
+ if (aVertex) {
+ std::shared_ptr<GeomAPI_Pnt> aPrjPnt = aSketchPlane->project(aVertex->point());
+ std::shared_ptr<GeomAPI_Pnt2d> aPntInSketch = sketch()->to2D(aPrjPnt);
+
+ if (!hasPrevProj)
+ aProjection = sketch()->addFeature(SketchPlugin_Point::ID());
+
+ // update coordinates of projection
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aProjection->attribute(SketchPlugin_Point::COORD_ID()))->setValue(aPntInSketch);
+ }
+ else if (anEdge->isLine()) {
std::shared_ptr<GeomAPI_Pnt> aFirst = aSketchPlane->project(anEdge->firstPoint());
std::shared_ptr<GeomAPI_Pnt> aLast = aSketchPlane->project(anEdge->lastPoint());
std::shared_ptr<GeomAPI_Pnt> aCenter = aSketchPlane->project(aCircle->center());
std::shared_ptr<GeomAPI_Pnt2d> aCenterInSketch = sketch()->to2D(aCenter);
+ bool isInversed = aCircle->normal()->dot(aSketchPlane->direction()) < 0.;
+
if (!hasPrevProj)
aProjection = sketch()->addFeature(SketchPlugin_Arc::ID());
+ bool aWasBlocked = aProjection->data()->blockSendAttributeUpdated(true);
+
// update attributes of projection
std::shared_ptr<GeomDataAPI_Point2D> aCenterPnt =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aStartPnt->setValue(aFirstInSketch);
aEndPnt->setValue(aLastInSketch);
aCenterPnt->setValue(aCenterInSketch);
+ aProjection->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(isInversed);
+
+ aProjection->data()->blockSendAttributeUpdated(aWasBlocked, false);
}
aProjection->boolean(COPY_ID())->setValue(true);
return MY_PROJ_FEATURE_ID;
}
+ static const std::string& INCLUDE_INTO_RESULT()
+ {
+ static std::string MY_INCLUDE("IncludeToResult");
+ return MY_INCLUDE;
+ }
+
/// Returns true because projected feature is always external
virtual bool isFixed()
{ return true; }
#include <SketchPlugin_Sketch.h>
#include <SketchPlugin_Feature.h>
+#include <SketchPlugin_Projection.h>
#include <SketchPlugin_SketchEntity.h>
#include <SketchPlugin_Tools.h>
if (aFeature) {
if (!aFeature->sketch()) // on load document the back references are missed
aFeature->setSketch(this);
- // do not include the external edges into the result
+ // do not include into the result the external edges with disabled flag "Include into result"
if (aFeature->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())) {
- if (aFeature->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->context())
- continue;
+ if (aFeature->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->context()) {
+ AttributeBooleanPtr aKeepResult =
+ aFeature->boolean(SketchPlugin_Projection::INCLUDE_INTO_RESULT());
+ if (!aKeepResult || !aKeepResult->value())
+ continue;
+ }
}
// do not include the construction entities in the result
if (aFeature->data()->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())) {
AttributeSelectionPtr aFeatureAttr =
std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
std::shared_ptr<GeomAPI_Edge> anEdge;
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature;
if (aFeatureAttr.get()) {
GeomShapePtr aVal = aFeatureAttr->value();
ResultPtr aRes = aFeatureAttr->context();
- if(aFeatureAttr->value() && aFeatureAttr->value()->isEdge()) {
+ if(aVal && aVal->isEdge()) {
anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aFeatureAttr->value()));
- } else if(aFeatureAttr->context() && aFeatureAttr->context()->shape() &&
- aFeatureAttr->context()->shape()->isEdge()) {
+ } else if(aRes && aRes->shape() && aRes->shape()->isEdge()) {
anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aFeatureAttr->context()->shape()));
}
+
+ // try to convert result to sketch feature
+ if (aRes) {
+ aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(ModelAPI_Feature::feature(aRes));
+ }
}
if (!anEdge) {
- theError = "The attribute %1 should be an edge";
+ // check a vertex has been selected
+ if (aFeatureAttr->value() && aFeatureAttr->value()->isVertex())
+ return true;
+ else {
+ ResultPtr aRes = aFeatureAttr->context();
+ if (aRes && aRes->shape() && aRes->shape()->isVertex())
+ return true;
+ }
+
+ theError = "The attribute %1 should be an edge or vertex";
theError.arg(theAttribute->id());
return false;
}
theError = "There is no sketch referring to the current feature";
return false;
}
+ if (aSketchFeature && aSketch.get() == aSketchFeature->sketch()) {
+ theError = "Unable to project feature from the same sketch";
+ return false;
+ }
std::shared_ptr<GeomAPI_Pln> aPlane = aSketch->plane();
std::shared_ptr<GeomAPI_Dir> aNormal = aPlane->direction();
if (anEdge->isLine()) {
std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
std::shared_ptr<GeomAPI_Dir> aLineDir = aLine->direction();
- std::shared_ptr<GeomAPI_Pnt> aLineLoc = aLine->location();
- double aDot = aNormal->dot(aLineDir);
- double aDist = aLineLoc->xyz()->decreased(anOrigin->xyz())->dot(aNormal->xyz());
- bool aValid = (fabs(aDot) >= tolerance && fabs(aDot) < 1.0 - tolerance) ||
- (fabs(aDot) < tolerance && fabs(aDist) > tolerance);
+ double aDot = fabs(aNormal->dot(aLineDir));
+ bool aValid = fabs(aDot - 1.0) >= tolerance * tolerance;
if (!aValid)
theError = "Error: Edge is already in the sketch plane.";
return aValid;
else if (anEdge->isCircle() || anEdge->isArc()) {
std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
std::shared_ptr<GeomAPI_Dir> aCircNormal = aCircle->normal();
- std::shared_ptr<GeomAPI_Pnt> aCircCenter = aCircle->center();
double aDot = fabs(aNormal->dot(aCircNormal));
- double aDist = aCircCenter->xyz()->decreased(anOrigin->xyz())->dot(aNormal->xyz());
- bool aValid = fabs(aDot - 1.0) < tolerance * tolerance && fabs(aDist) > tolerance;
+ bool aValid = fabs(aDot - 1.0) < tolerance * tolerance;
if (!aValid)
theError.arg(anEdge->isCircle() ? "Error: Cirlce is already in the sketch plane."
: "Error: Arc is already in the sketch plane.");
aSession.startOperation()
aLineProjector = aSketchFeature.addFeature("SketchProjection")
aLineProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchLine_1")
+aLineProjector.boolean("IncludeToResult").setValue(False)
aLineProjector.execute()
aCircleProjector = aSketchFeature.addFeature("SketchProjection")
aCircleProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchCircle_1_2")
+aCircleProjector.boolean("IncludeToResult").setValue(False)
aCircleProjector.execute()
anArcProjector = aSketchFeature.addFeature("SketchProjection")
anArcProjector.selection("ExternalFeature").selectSubShape("EDGE", "Sketch_1/Edge-SketchArc_1_2")
+anArcProjector.boolean("IncludeToResult").setValue(False)
anArcProjector.execute()
aSession.finishOperation()
assert (model.dof(aSketchFeature) == 0)
--- /dev/null
+from salome.shaper import model
+from GeomAPI import *
+
+#==============================================================================
+# Auxiliary functions
+#==============================================================================
+
+# Project all features from 'theProjected' list.
+# Argument 'theFailed' shows indices of projections which should fail because of validator
+def testProjections(theDocument, theSketch, theProjected, theFailed):
+ # generate list of projected features
+ ind = 0
+ edgeProj = set()
+ for type, name in theProjected:
+ proj = theSketch.addProjection(model.selection(type, name), True)
+ assert(bool(proj.feature().error() != '') == bool(ind in theFailed))
+ if proj.feature().error() != '':
+ if proj.createdFeature() is not None:
+ theDocument.removeFeature(proj.createdFeature().feature())
+ theDocument.removeFeature(proj.feature())
+ model.do()
+ elif type == "EDGE":
+ edgeProj.add(proj)
+ ind += 1
+ model.do()
+ model.testNbSubShapes(theSketch, GeomAPI_Shape.EDGE, [len(edgeProj)])
+
+ # exclude some edges from result
+ NB_TO_EXCLUDE = 2
+ num = 0
+ for proj in edgeProj:
+ proj.setIncludeToResult(False)
+ num += 1
+ if num >= NB_TO_EXCLUDE:
+ break
+ model.do()
+ model.testNbSubShapes(theSketch, GeomAPI_Shape.EDGE, [len(edgeProj) - num])
+
+
+#==============================================================================
+# Initial model
+#==============================================================================
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-187.9303398287678, -363.2915373234726, 182.2190183849013)
+SketchArc_1 = Sketch_1.addArc(-229.9631763073051, -65.7360230979784, -105.4201011859997, -97.06956797196608, -326.3502666769664, 19.13032715412109, False)
+SketchLine_1 = Sketch_1.addLine(-438.4308780225287, -71.00741660505224, 161.0737545348623, -582.1237015141244)
+SketchPoint_1 = Sketch_1.addPoint(-446.0706301668712, -312.4620987423343)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_2 = Sketch_2.addLine(27.19276215608871, 61.51157581079401, 72.96621462024476, 0)
+SketchLine_3 = Sketch_2.addLine(model.selection("EDGE", "PartSet/OZ"))
+SketchLine_4 = Sketch_2.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintCoincidence_1 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_4.result())
+SketchLine_5 = Sketch_2.addLine(72.96621462024476, 0, 0, 0)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_3.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_2.addLine(0, 0, 0, 61.51157581079401)
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_3.startPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_3.result())
+SketchLine_7 = Sketch_2.addLine(0, 61.51157581079401, 27.19276215608871, 61.51157581079401)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchLine_7.endPoint())
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_7.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_2r-SketchLine_5r-SketchLine_6r-SketchLine_7r")], model.selection(), 100, 0)
+model.do()
+
+#==============================================================================
+# Tests
+#==============================================================================
+
+aProjectedList = [("EDGE", "Sketch_1/Edge-SketchCircle_1_2"),
+ ("EDGE", "Sketch_1/Edge-SketchArc_1_2"),
+ ("EDGE", "Sketch_1/Edge-SketchLine_1"),
+ ("VERTEX", "Sketch_1/Vertex-SketchPoint_1"),
+ #
+ ("VERTEX", "Sketch_1/Vertex-SketchCircle_1"),
+ ("VERTEX", "Sketch_1/Vertex-SketchLine_1e"),
+ ("VERTEX", "Sketch_1/Vertex-SketchLine_1s"),
+ ("VERTEX", "Sketch_1/Vertex-SketchArc_1_2s"),
+ ("VERTEX", "Sketch_1/Vertex-SketchArc_1_2e"),
+ ("VERTEX", "Sketch_1/Vertex-SketchArc_1"),
+ #
+ ("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"),
+ ("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"),
+ #
+ ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"),
+ #
+ ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1"),
+ #
+ ("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"),
+ ("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1")
+ ]
+
+# Test projection to the same plane
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"))
+aFailedIDs = set([21, 29])
+testProjections(Part_1_doc, Sketch_3, aProjectedList, aFailedIDs)
+
+# Test projection to parallel plane
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+testProjections(Part_1_doc, Sketch_4, aProjectedList, aFailedIDs)
+
+# Test projection to lower base of the prism
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/From_Face_1"))
+aFailedIDs = set([0, 1, 22, 23, 24, 25])
+testProjections(Part_1_doc, Sketch_5, aProjectedList, aFailedIDs)
+
+# Test projection to upper base of the prism
+Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
+testProjections(Part_1_doc, Sketch_6, aProjectedList, aFailedIDs)
+
+# Test projection to orthogonal side face of the prism
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
+aFailedIDs = set([0, 1, 18, 20, 26, 28])
+testProjections(Part_1_doc, Sketch_7, aProjectedList, aFailedIDs)
+
+# Test projection to slope side face of the prism
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+aFailedIDs = set([0, 1])
+testProjections(Part_1_doc, Sketch_8, aProjectedList, aFailedIDs)
+
+model.end()
id="ExternalFeature"
label="Edge"
tooltip="Select external edge."
- shape_types="edge"
+ shape_types="edge vertex"
use_external="true"
can_create_external="false"
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"/>
<validator id="PartSet_ProjectionSelection"/>
</feature>
</group>