]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Make selection of results as arguments of extrusion working correctly
authormpv <mpv@opencascade.com>
Thu, 19 Mar 2015 08:04:29 +0000 (11:04 +0300)
committermpv <mpv@opencascade.com>
Thu, 19 Mar 2015 08:04:29 +0000 (11:04 +0300)
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_ResultConstruction.cpp
src/Model/Model_ResultConstruction.h
src/ModelAPI/ModelAPI_Feature.cpp
src/ModelAPI/ModelAPI_ResultConstruction.h

index c84c007022746d820ed0ec06947376a4902cb232..873753a8cf44bca3be2d580c85217b98e77e2478 100644 (file)
@@ -42,14 +42,9 @@ void FeaturesPlugin_Extrusion::execute()
   AttributeSelectionListPtr aFaceRefs = selectionList(FeaturesPlugin_Extrusion::LIST_ID());
 
   // for each selected face generate a result
-  int anIndex = 0;
+  int anIndex = 0, aResultIndex = 0;
   for(; anIndex < aFaceRefs->size(); anIndex++) {
     std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = aFaceRefs->value(anIndex);
-    if (!aFaceRef.get())
-      continue;
-    std::shared_ptr<GeomAPI_Shape> aFace = aFaceRef->value();
-    if (!aFace.get())
-      continue;
     ResultPtr aContextRes = aFaceRef->context();
     std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
     if (!aContext.get()) {
@@ -57,37 +52,58 @@ void FeaturesPlugin_Extrusion::execute()
       setError(aContextError);
       break;
     }
-
     double aSize = real(FeaturesPlugin_Extrusion::SIZE_ID())->value();
     if (boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value())
       aSize = -aSize;
 
-    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
-    GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
-    if(!aFeature.isDone()) {
-      static const std::string aFeatureError = "Extrusion algorithm failed";  
-      setError(aFeatureError);
-      break;
+    std::shared_ptr<GeomAPI_Shape> aValueFace = aFaceRef->value();
+    int aFacesNum = -1; // this mean that "aFace" is used
+    ResultConstructionPtr aConstruction =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes);
+    if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces
+      if (aConstruction.get()) {
+        aFacesNum = aConstruction->facesNum();
+      } else {
+        static const std::string aFaceError = "Can not find basis for extrusion";
+        setError(aFaceError);
+        break;
+      }
     }
 
-    // Check if shape is valid
-    if (aFeature.shape()->isNull()) {
-      static const std::string aShapeError = "Resulting shape is Null";     
-      setError(aShapeError);
-      break;
+    for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      std::shared_ptr<GeomAPI_Shape> aFace = 
+        aFacesNum == -1 ? aValueFace : aConstruction->face(aFaceIndex);
+      GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
+      if(!aFeature.isDone()) {
+        static const std::string aFeatureError = "Extrusion algorithm failed";  
+        setError(aFeatureError);
+        break;
+      }
+
+      // Check if shape is valid
+      if (aFeature.shape()->isNull()) {
+        static const std::string aShapeError = "Resulting shape is Null";     
+        setError(aShapeError);
+        break;
+      }
+      if(!aFeature.isValid()) {
+        std::string aFeatureError = "Warning: resulting shape is not valid";  
+        setError(aFeatureError);
+        break;
+      }  
+      //LoadNamingDS
+      LoadNamingDS(aFeature, aResultBody, aFace, aContext);
+
+      setResult(aResultBody, aResultIndex);
+      aResultIndex++;
+
+      if (aFacesNum == -1)
+        break;
     }
-    if(!aFeature.isValid()) {
-      std::string aFeatureError = "Warning: resulting shape is not valid";  
-      setError(aFeatureError);
-      break;
-    }  
-    //LoadNamingDS
-    LoadNamingDS(aFeature, aResultBody, aFace, aContext);
-
-    setResult(aResultBody, anIndex);
   }
   // remove the rest results if there were produced in the previous pass
-  removeResults(anIndex);
+  removeResults(aResultIndex);
 }
 
 //============================================================================
index b6fe2ea028578e269b300a87f7eb16a00a6f94f5..03ccb8984e47be420ea1d0c204d1374a0dc98cda 100644 (file)
@@ -61,6 +61,7 @@ using namespace std;
 static const int kSTART_VERTEX_DELTA = 1000000;
 // identifier that there is simple reference: selection equals to context
 Standard_GUID kSIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb29");
+Standard_GUID kCONSTUCTION_SIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb28");
 
 // on this label is stored:
 // TNaming_NamedShape - selected shape
@@ -73,19 +74,18 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   const std::shared_ptr<GeomAPI_Shape>& theSubShape)
 {
   const std::shared_ptr<GeomAPI_Shape>& anOldShape = value();
-  bool isOldShape = 
+  bool isOldContext = theContext == myRef.value();
+  bool isOldShape = isOldContext &&
     (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape)));
   if (isOldShape) return; // shape is the same, so context is also unchanged
   // update the referenced object if needed
-  bool isOldContext = theContext == myRef.value();
-
-
   if (!isOldContext)
     myRef.setValue(theContext);
 
   // do noth use naming if selected shape is result shape itself, but not sub-shape
   TDF_Label aSelLab = selectionLabel();
   aSelLab.ForgetAttribute(kSIMPLE_REF_ID);
+  aSelLab.ForgetAttribute(kCONSTUCTION_SIMPLE_REF_ID);
   if (theContext->groupName() == ModelAPI_ResultBody::group()) {
     // do not select the whole shape for body:it is already must be in the data framework
     if (theContext->shape().get() && theContext->shape()->isEqual(theSubShape)) {
@@ -95,7 +95,13 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
       selectBody(theContext, theSubShape);
     }
   } else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) {
-    selectConstruction(theContext, theSubShape);
+    if (!theSubShape.get()) {
+      // to sub, so the whole result is selected
+      aSelLab.ForgetAllAttributes(true);
+      TDataStd_UAttribute::Set(aSelLab, kCONSTUCTION_SIMPLE_REF_ID);
+    } else {
+      selectConstruction(theContext, theSubShape);
+    }
   }
   myIsInitialized = true;
 
@@ -123,6 +129,9 @@ std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
         return aResult; // empty result
       return aContext->shape();
     }
+    if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value
+        return aResult; // empty result
+    }
 
     Handle(TNaming_NamedShape) aSelection;
     if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
@@ -188,6 +197,9 @@ bool Model_AttributeSelection::update()
   if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape
     return aContext->shape() && !aContext->shape()->isNull();
   }
+  if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, not sub-shape
+    return aContext->shape() && !aContext->shape()->isNull();
+  }
 
   if (aContext->groupName() == ModelAPI_ResultBody::group()) {
     // body: just a named shape, use selection mechanism from OCCT
@@ -222,7 +234,7 @@ bool Model_AttributeSelection::update()
         return false;
       }
 
-      if (aShapeType == TopAbs_FACE) {
+      if (aShapeType == TopAbs_FACE) { // compound is for the whole sketch selection
         // If this is a wire with plane defined thin it is a sketch-like object
         std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
         GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
@@ -611,8 +623,11 @@ std::string Model_AttributeSelection::namingName()
   std::shared_ptr<GeomAPI_Shape> aSubSh = value();
   ResultPtr aCont = context();
   aName = "Undefined name";
-  if(!aSubSh.get() || aSubSh->isNull() || !aCont.get() || aCont->shape()->isNull()) 
+  if(!aCont.get() || aCont->shape()->isNull()) 
     return aName;
+  if (!aSubSh.get() || aSubSh->isNull()) { // no subshape, so just the whole feature name
+    return aCont->data()->name();
+  }
   TopoDS_Shape aSubShape = aSubSh->impl<TopoDS_Shape>();
   TopoDS_Shape aContext  = aCont->shape()->impl<TopoDS_Shape>();
 #ifdef DEB_NAMING
index a0f3b9306ed2281a13ef5fe3c7c96d4596f6b44f..17b20df98dc4eff497b1eb03ed3bfbbbbaf72e09 100644 (file)
@@ -8,6 +8,8 @@
 
 #include <ModelAPI_AttributeIntArray.h>
 #include <Config_PropManager.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
 
 void Model_ResultConstruction::initAttributes()
 {
@@ -26,7 +28,13 @@ void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::str
 
 void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
 {
-  myShape = theShape;
+  if (myShape != theShape) {
+    myShape = theShape;
+    if (theShape.get() && (!myShape.get() || !theShape->isEqual(myShape))) {
+      myFacesUpToDate = false;
+      myFaces.clear();
+    }
+  }
 }
 
 std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
@@ -37,6 +45,7 @@ std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
 Model_ResultConstruction::Model_ResultConstruction()
 {
   myIsInHistory = true;
+  myFacesUpToDate = false;
   setIsConcealed(false);
 }
 
@@ -44,3 +53,27 @@ void Model_ResultConstruction::setIsInHistory(const bool isInHistory)
 {
   myIsInHistory = isInHistory;
 }
+
+int Model_ResultConstruction::facesNum()
+{
+  if (!myFacesUpToDate) {
+    std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr = 
+      std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(myShape);
+    std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
+    GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
+      aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
+    std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFIter = aFaces.begin();
+    for(; aFIter != aFaces.end(); aFIter++) {
+      std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
+      if (aFace.get())
+        myFaces.push_back(aFace);
+    }
+    myFacesUpToDate = true;
+  }
+  return myFaces.size();
+}
+
+std::shared_ptr<GeomAPI_Face> Model_ResultConstruction::face(const int theIndex)
+{
+  return myFaces[theIndex];
+}
index 8292e09bc12b12f9d8492199dac11d759b57e142..84f048f6d3a98c27228084747208a29fd61cee01 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "Model.h"
 #include <ModelAPI_ResultConstruction.h>
+#include <vector>
 
 /**\class Model_ResultConstruction
  * \ingroup DataModel
@@ -21,6 +22,8 @@ class Model_ResultConstruction : public ModelAPI_ResultConstruction
 {
   std::shared_ptr<ModelAPI_Feature> myOwner;  ///< owner of this result
   std::shared_ptr<GeomAPI_Shape> myShape;  ///< shape of this result created "on the fly"
+  bool myFacesUpToDate; ///< is true if faces in myuFaces are computed and up to date
+  std::vector<std::shared_ptr<GeomAPI_Face> > myFaces; ///< stores the up to date faces if they exist
   bool myIsInHistory;
  public:
   /// default color for a result construction
@@ -51,6 +54,11 @@ class Model_ResultConstruction : public ModelAPI_ResultConstruction
   /// Sets the flag that it must be displayed in history (default is true)
   MODEL_EXPORT virtual void setIsInHistory(const bool myIsInHistory);
 
+  /// if the construction result may be used as faces, this method returns not zero number of faces
+  MODEL_EXPORT virtual int facesNum();
+  /// if the construction result may be used as faces, this method returns face by zero based index
+  MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Face> face(const int theIndex);
+
  protected:
   /// Makes a body on the given feature
   Model_ResultConstruction();
index e158d48a0853f3b6f9603d39fbbd4469515d8fe3..b08640fdaca719c62267526845c5dd7de5f5fa11 100644 (file)
@@ -97,7 +97,7 @@ void ModelAPI_Feature::removeResults(const int theSinceIndex)
   }
 
   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
-  for(int anIndex = 0; anIndex < theSinceIndex; anIndex++)
+  for(int anIndex = 0; anIndex < theSinceIndex && aResIter != myResults.end(); anIndex++)
     aResIter++;
   std::list<std::shared_ptr<ModelAPI_Result> >::iterator aNextIter = aResIter;
   for(; aNextIter != myResults.end(); aNextIter++) {
index 85a8d81baa5df9534704a2471a1a1142f82df388..6040b35a599aded5b57267c02746a2632b79a6df 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "ModelAPI_Result.h"
 #include <GeomAPI_Shape.h>
+#include <GeomAPI_Face.h>
 
 #include <string>
 
@@ -37,6 +38,11 @@ class ModelAPI_ResultConstruction : public ModelAPI_Result
 
   /// Sets the flag that it must be displayed in history (default is true)
   virtual void setIsInHistory(const bool isInHistory) = 0;
+
+  /// if the construction result may be used as faces, this method returns not zero number of faces
+  virtual int facesNum() = 0;
+  /// if the construction result may be used as faces, this method returns face by zero based index
+  virtual std::shared_ptr<GeomAPI_Face> face(const int theIndex) = 0;
 };
 
 //! Pointer on feature object