]> SALOME platform Git repositories - modules/shaper.git/blobdiff - src/Model/Model_AttributeSelection.cpp
Salome HOME
Implementation of naming parametrisation of sketch result
[modules/shaper.git] / src / Model / Model_AttributeSelection.cpp
index f55ee9f5e685e305a7dd8794b0e77bc01bd74467..f919cecd6e0d3ef9f75d6ecda22548d997f9a18b 100644 (file)
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_CompositeFeature.h>
 #include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
 
 #include <TNaming_Selector.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Tool.hxx>
 #include <TNaming_Builder.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TDataStd_ReferenceList.hxx>
+#include <TDataStd_IntPackedMap.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TDF_LabelMap.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <TColStd_MapOfTransient.hxx>
 
 using namespace std;
 
@@ -75,6 +82,101 @@ void Model_AttributeSelection::setObject(const boost::shared_ptr<ModelAPI_Object
   myRef.setObject(theObject);
 }
 
+bool Model_AttributeSelection::update()
+{
+  ResultPtr aContext = context();
+  if (aContext->groupName() == ModelAPI_ResultBody::group()) {
+    // body: just a named shape, use selection mechanism from OCCT
+    TNaming_Selector aSelector(myRef.myRef->Label());
+    TDF_LabelMap aScope; // empty means the whole document
+    return aSelector.Solve(aScope) == Standard_True;
+   
+  } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
+    // construction: identification by the results indexes, recompute faces and
+    // take the face that more close by the indexes
+    boost::shared_ptr<GeomAPI_Wire> aWirePtr = boost::dynamic_pointer_cast<GeomAPI_Wire>(
+      boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext)->shape());
+    if (aWirePtr && aWirePtr->hasPlane()) {
+        // If this is a wire with plane defined thin it is a sketch-like object
+      std::list<boost::shared_ptr<GeomAPI_Shape> > aFaces;
+      GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
+        aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
+      if (aFaces.empty()) // no faces, update can not work correctly
+        return false;
+      // if there is no edges indexes, any face can be used: take the first
+      boost::shared_ptr<Model_Data> aData = 
+        boost::dynamic_pointer_cast<Model_Data>(owner()->data());
+      TDF_Label aLab = aData->label();
+      Handle(TDataStd_IntPackedMap) aSubIds;
+      boost::shared_ptr<GeomAPI_Shape> aNewSelected;
+      if (!aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), aSubIds) || aSubIds->Extent() == 0) {
+        aNewSelected = *(aFaces.begin());
+      } else { // searching for most looks-like initial face by the indexes
+        // prepare edges of the current resut for the fast searching
+        TColStd_MapOfTransient allCurves;
+        FeaturePtr aContextFeature = owner()->document()->feature(aContext);
+        CompositeFeaturePtr aComposite = 
+          boost::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aContextFeature);
+        if (!aComposite) // must be composite at least for the current implementation
+          return false;
+        const int aSubNum = aComposite->numberOfSubs();
+        for(int a = 0; a < aSubNum; a++) {
+          if (aSubIds->Contains(aComposite->subFeatureId(a))) {
+            FeaturePtr aSub = aComposite->subFeature(a);
+            const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+            std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+            for(; aRes != aResults.cend(); aRes++) {
+              ResultConstructionPtr aConstr = 
+                boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+              if (aConstr->shape()) {
+                const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+                TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+                if (!anEdge.IsNull()) {
+                  Standard_Real aFirst, aLast;
+                  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+                  allCurves.Add(aCurve);
+                }
+              }
+            }
+          }
+        }
+        // iterate new result faces and searching for these edges
+        std::list<boost::shared_ptr<GeomAPI_Shape> >::iterator aFacesIter = aFaces.begin();
+        double aBestFound = 0; // best percentage of found edges
+        for(; aFacesIter != aFaces.end(); aFacesIter++) {
+          int aFound = 0, aNotFound = 0;
+          TopExp_Explorer anEdgesExp((*aFacesIter)->impl<TopoDS_Shape>(), TopAbs_EDGE);
+          for(; anEdgesExp.More(); anEdgesExp.Next()) {
+            TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current());
+            if (!anEdge.IsNull()) {
+              Standard_Real aFirst, aLast;
+              Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+              if (allCurves.Contains(aCurve)) {
+                aFound++;
+              } else {
+                aNotFound++;
+              }
+            }
+          }
+          if (aFound + aNotFound != 0) {
+            double aPercentage = double(aFound) / double(aFound + aNotFound);
+            if (aPercentage > aBestFound) {
+              aBestFound = aPercentage;
+              aNewSelected = *aFacesIter;
+            }
+          }
+        }
+        if (aNewSelected) { // store this new selection
+          selectConstruction(aContext, aNewSelected);
+          return true;
+        }
+      }
+    }
+  }
+  return false; // unknown case
+}
+
+
 void Model_AttributeSelection::selectBody(
     const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
 {
@@ -112,12 +214,15 @@ void Model_AttributeSelection::selectConstruction(
   TDF_Label aLab = aData->label();
   // identify the reuslts of sub-object of the composite by edges
   const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
-  TopTools_MapOfShape allEdges;
+  TColStd_MapOfTransient allCurves;
   for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) {
-    allEdges.Add(anEdgeExp.Current());
+    TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current());
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+    allCurves.Add(aCurve);
   }
   // iterate and store the result ids of sub-elements
-  Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set(aLab);
+  Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
   const int aSubNum = aComposite->numberOfSubs();
   for(int a = 0; a < aSubNum; a++) {
     FeaturePtr aSub = aComposite->subFeature(a);
@@ -129,10 +234,15 @@ void Model_AttributeSelection::selectConstruction(
         boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
       if (aConstr->shape()) {
         const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
-        if (allEdges.Contains(aResShape)) {
-          boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
-          TDF_Label aSubLab = aSubData->label();
-          aRefs->Append(aSubLab);
+        TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+        if (!anEdge.IsNull()) {
+          Standard_Real aFirst, aLast;
+          Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+          if (allCurves.Contains(aCurve)) {
+            boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
+            TDF_Label aSubLab = aSubData->label();
+            aRefs->Add(aComposite->subFeatureId(a));
+          }
         }
       }
     }