Salome HOME
Import of edges participating to the result of the sketch
authorazv <azv@opencascade.com>
Fri, 30 Jun 2017 12:06:48 +0000 (15:06 +0300)
committerazv <azv@opencascade.com>
Fri, 30 Jun 2017 12:06:48 +0000 (15:06 +0300)
Improve the Projection feature

12 files changed:
src/SketchAPI/SketchAPI_Projection.cpp
src/SketchAPI/SketchAPI_Projection.h
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Projection.cpp
src/SketchPlugin/SketchPlugin_Projection.h
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/Test/TestProjection.py
src/SketchPlugin/Test/TestProjectionIntoResult.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml

index 51628de970f564cb26fe6b3c148a90fde9d352ea..38e84be98560cfff64879f6bfe0364dd52d64037 100644 (file)
@@ -78,6 +78,12 @@ void SketchAPI_Projection::setByExternalName(const std::string& theExternalName)
   execute(true);
 }
 
+void SketchAPI_Projection::setIncludeToResult(bool theKeepResult)
+{
+  fillAttribute(theKeepResult, includeToResult());
+  execute(true);
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_SketchEntity> SketchAPI_Projection::createdFeature() const
 {
@@ -106,7 +112,9 @@ void SketchAPI_Projection::dump(ModelHighAPI_Dumper& theDumper) 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);
 
index e1b1570535b5bb28441715f35dc991a79c338033..e3926fc36ea541514bcfa010658a78999493f1b8 100644 (file)
@@ -52,13 +52,15 @@ public:
   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
@@ -69,6 +71,10 @@ public:
   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;
index b207823768c79c5295fb0764603af98862beb291..5f36a0872b89739ee9b13bbe9dfe7da691049ed7 100644 (file)
@@ -458,19 +458,25 @@ std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::string & theE
 
 //--------------------------------------------------------------------------------------
 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;
 }
 
 //--------------------------------------------------------------------------------------
index 107ec5b85becf5b53df162043c7beab256467c4b..3e531012dcfc64b7721e9d80aaa0c3d20335797e 100644 (file)
@@ -251,11 +251,13 @@ public:
   /// 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
index 152367cb51d095cd1aab11c945150389ac036e39..c22dad503fdf1786aa7951cb8d0cc3daab505cfc 100644 (file)
@@ -184,6 +184,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestFilletInteracting.py
                TestRectangle.py
                TestProjection.py
+               TestProjectionIntoResult.py
                TestSplit.py
                TestHighload.py
                TestSnowflake.py
index ef83cce1d2db49d8a2b7fc0c3302de40b4908eaa..d6b5654154c3aed42fefae4ff78c851dcda84218 100644 (file)
@@ -23,6 +23,7 @@
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
 #include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_ConstraintRigid.h>
 
@@ -39,6 +40,7 @@
 #include <GeomAPI_Lin.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_Vertex.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
 #include <GeomDataAPI_Point2D.h>
 
@@ -61,6 +63,8 @@ void SketchPlugin_Projection::initDerivedClassAttributes()
   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());
 }
 
@@ -100,19 +104,42 @@ void SketchPlugin_Projection::attributeChanged(const std::string& theID)
   }
 }
 
+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());
@@ -122,18 +149,15 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
 
   // 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();
@@ -145,7 +169,18 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
     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());
 
@@ -192,9 +227,13 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
     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>(
@@ -208,6 +247,9 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
     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);
index daffb87519eb1c175b9cd0edbbcc4aeac3131191..c5c3e83783bb4c0c9e7f567ea8f298ec8b3c172e 100644 (file)
@@ -55,6 +55,12 @@ public:
     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; }
index 6f5dc20a49b1c5c5a15b965a22f9f052e286da6a..b0660a958229009b031b28166fe51419621a8db7 100755 (executable)
@@ -43,6 +43,7 @@
 
 #include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_Feature.h>
+#include <SketchPlugin_Projection.h>
 #include <SketchPlugin_SketchEntity.h>
 #include <SketchPlugin_Tools.h>
 
@@ -102,10 +103,14 @@ void SketchPlugin_Sketch::execute()
     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())) {
index e16da117c74984d1221a4e4cd0f35e346a83cd0f..714ec64e781f6e130ac9066be7ee8d1fc5753903 100755 (executable)
@@ -977,18 +977,33 @@ bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute,
   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;
   }
@@ -1009,6 +1024,10 @@ bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute,
     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();
@@ -1017,11 +1036,8 @@ bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute,
   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;
@@ -1029,10 +1045,8 @@ bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute,
   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.");
index 4b358529c72f3a7fd3fda6f35d782606ad58f9bd..7e24e3ed5b3916a2794bcabc919992dafb416b42 100644 (file)
@@ -95,14 +95,17 @@ aSession.finishOperation()
 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)
diff --git a/src/SketchPlugin/Test/TestProjectionIntoResult.py b/src/SketchPlugin/Test/TestProjectionIntoResult.py
new file mode 100644 (file)
index 0000000..6ec5968
--- /dev/null
@@ -0,0 +1,141 @@
+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()
index 2adc38330e6afc056beda05662187e12095ec39c..a64b6a35337e6bbffd2df7a88601eac9aa721fd1 100644 (file)
@@ -479,12 +479,13 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
               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>