]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix issues and add unitary test
authorJérôme <jerome.lucas@cesgenslab.fr>
Mon, 12 Oct 2020 14:04:05 +0000 (16:04 +0200)
committerJérôme <jerome.lucas@cesgenslab.fr>
Mon, 12 Oct 2020 14:04:05 +0000 (16:04 +0200)
15 files changed:
src/Events/Events_Listener.cpp
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Fillet.cpp
src/FeaturesAPI/FeaturesAPI_Fillet.h
src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.cpp
src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.h
src/FeaturesPlugin/Test/TestFillet_MultiRadius.py [new file with mode: 0644]
src/FeaturesPlugin/fillet_widget.xml
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h
src/PythonAPI/model/features/__init__.py

index 593f26974d95bba938fc2ac346ee91b8554f6576..267e6db6ba0b49e4870b9146bb1719371cbe7cf4 100644 (file)
@@ -34,7 +34,6 @@ void Events_Listener::groupWhileFlush(const std::shared_ptr<Events_Message>& the
     std::shared_ptr<Events_MessageGroup> aStored =
       std::dynamic_pointer_cast<Events_MessageGroup>(aMyGroup->second);
     aStored->Join(aGroup);
-    //std::cout<<"Add to group "<<theMessage->eventID().eventText()<<std::endl;
     return;
   }
 }
index c5c0c28de3deb44d36ee70e0fb651764ee1e2b15..be460f967837c6507fa7e86c979806dafc72f1e9 100644 (file)
@@ -42,8 +42,8 @@
 %feature("kwargs") addCommon;
 %feature("kwargs") addCut;
 %feature("kwargs") addFillet;
-%feature("kwargs") addFilletMultiRadiusBypoint;
-%feature("kwargs") addFilletMultiRadiusByCurv;
+%feature("kwargs") addFilletMultiRadiusBycurvAbs;
+%feature("kwargs") addFilletMultiRadiusByPoints;
 %feature("kwargs") addFuse;
 %feature("kwargs") addIntersection;
 %feature("kwargs") addMultiRotation;
index 9d41827881318fba4830bceda573497209d10017..49af22190750de2008023a0184165a42d3c09ebc 100644 (file)
@@ -186,15 +186,16 @@ FeaturesAPI_Fillet2D::FeaturesAPI_Fillet2D(const std::shared_ptr<ModelAPI_Featur
 
         if (!aShape.get()) {
           aShape = aContext->shape();
-        } 
+        }
         aPoints.push_back(aShape);
     }
+    myvalues()->setSize( aPoints.size() +2, 2 );
     std::list<ModelHighAPI_Double>::const_iterator aRowsRadiusIter = theRadius.begin();
-    ModelAPI_AttributeTables::Value aVal; 
+    ModelAPI_AttributeTables::Value aVal;
     aVal.myDouble = 0.0;
-    myvaluescurv()->setValue(aVal, 0, 0 );
-    aVal.myDouble = aRowsRadiusIter->value(); 
-    myvaluescurv()->setValue(aVal, 0, 1 );
+    myvalues()->setValue(aVal, 0, 0 );
+    aVal.myDouble = aRowsRadiusIter->value();
+    myvalues()->setValue(aVal, 0, 1 );
     aRowsRadiusIter++;
     int aRowIndex = 1;
     ListOfShape::const_iterator aPointsIt = aPoints.begin();
@@ -203,41 +204,43 @@ FeaturesAPI_Fillet2D::FeaturesAPI_Fillet2D(const std::shared_ptr<ModelAPI_Featur
       std::shared_ptr<GeomAPI_Pnt> aPntCurv = aCurve->project(aPnt);
       double res = (aPntCurv->distance(first) / taille);
        aVal.myDouble = res;
-      myvaluescurv()->setValue(aVal, aRowIndex, 0 );
-      aVal.myDouble = aRowsRadiusIter->value(); 
-      myvaluescurv()->setValue(aVal, aRowIndex, 1 );
+      myvalues()->setValue(aVal, aRowIndex, 0 );
+      aVal.myDouble = aRowsRadiusIter->value();
+      myvalues()->setValue(aVal, aRowIndex, 1 );
       aRowIndex++;
     }
     aVal.myDouble = 1.0;
-    myvaluescurv()->setValue(aVal, aRowIndex, 0 );
-    aVal.myDouble = aRowsRadiusIter->value(); 
-    myvaluescurv()->setValue(aVal, aRowIndex, 1 );
+    myvalues()->setValue(aVal, aRowIndex, 0 );
+    aVal.myDouble = aRowsRadiusIter->value();
+    myvalues()->setValue(aVal, aRowIndex, 1 );
     execIfBaseNotEmpty();
   }
 }
 
 FeaturesAPI_Fillet2D::FeaturesAPI_Fillet2D(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                           const ModelHighAPI_Selection & theedgeselected,
+                                           const std::list<ModelHighAPI_Selection>& theBaseObjects,
                                            const std::list<ModelHighAPI_Double>& thepointCurvCood,
                                            const std::list<ModelHighAPI_Double>& theRadius)
   : FeaturesAPI_Fillet(theFeature)
 {
   if (initialize()) {
     fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES(), mycreationMethod);
-    fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA(), mycreationMethodmulti);
-    fillAttribute(theedgeselected, edgeselected());
+    fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA(),
+                  mycreationMethodmulti);
+    fillAttribute(theBaseObjects, mybaseObjects);
 
-    int aRowIndex = 0; 
-    myvaluescurv()->setSize( thepointCurvCood.size(), 2 );  
-    std::list<ModelHighAPI_Double>::const_iterator aRowsCoodIter = thepointCurvCood.begin(); 
-    std::list<ModelHighAPI_Double>::const_iterator aRowsRadiusIter = theRadius.begin(); 
-    for(; aRowsCoodIter != thepointCurvCood.end(); aRowsCoodIter++, aRowsRadiusIter++, aRowIndex++) { 
-      ModelAPI_AttributeTables::Value aVal; 
+    int aRowIndex = 0;
+    myvaluescurv()->setSize( thepointCurvCood.size(), 2 );
+    std::list<ModelHighAPI_Double>::const_iterator aRowsCoodIter = thepointCurvCood.begin();
+    std::list<ModelHighAPI_Double>::const_iterator aRowsRadiusIter = theRadius.begin();
+    for(; aRowsCoodIter != thepointCurvCood.end();
+          aRowsCoodIter++, aRowsRadiusIter++, aRowIndex++) {
+      ModelAPI_AttributeTables::Value aVal;
       aVal.myDouble = aRowsCoodIter->value();
       myvaluescurv()->setValue(aVal, aRowIndex, 0 );
-      aVal.myDouble = aRowsRadiusIter->value(); 
+      aVal.myDouble = aRowsRadiusIter->value();
       myvaluescurv()->setValue(aVal, aRowIndex, 1 );
-    } 
+    }
     execIfBaseNotEmpty();
   }
 }
@@ -255,7 +258,7 @@ void FeaturesAPI_Fillet2D::setBase(const std::list<ModelHighAPI_Selection>& theB
 }
 
 void FeaturesAPI_Fillet2D::setRadius(const ModelHighAPI_Double& theRadius)
-{ 
+{
   fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS(), mycreationMethod);
   fillAttribute(theRadius, myradius);
 
@@ -264,7 +267,7 @@ void FeaturesAPI_Fillet2D::setRadius(const ModelHighAPI_Double& theRadius)
 
 void FeaturesAPI_Fillet2D::setRadius(const ModelHighAPI_Double& theRadius1,
                                      const ModelHighAPI_Double& theRadius2)
-{ 
+{
   fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS(), mycreationMethod);
   fillAttribute(theRadius1, mystartRadius);
   fillAttribute(theRadius2, myendRadius);
@@ -279,48 +282,52 @@ void FeaturesAPI_Fillet2D::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionListPtr anAttrObjects =
     aBase->selectionList(FeaturesPlugin_Fillet::OBJECT_LIST_ID());
-  
 
-  if ( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value() 
+
+  if ( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value()
         == FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES() )
   {
     AttributeSelectionPtr anAttrEdgeSelec =
     aBase->selection(FeaturesPlugin_Fillet::EDGE_SELECTED_ID());
 
-    if( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES())->value() 
+    if( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES())->value()
           == FeaturesPlugin_Fillet::CREATION_METHOD_BY_POINTS() )
-    {        
+    {
+
       AttributeSelectionListPtr anAttrPoint =
           aBase->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
-      AttributeTablesPtr anAttrTable = 
+      AttributeTablesPtr anAttrTable =
           aBase->tables(FeaturesPlugin_Fillet::VALUES_ID());
-      theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrEdgeSelec;
-      theDumper << ", " << anAttrPoint << ", ";
+      theDumper << aBase << " = model.addFilletMultiRadiusByPoints(" << aDocName;
+      theDumper << ", " << anAttrEdgeSelec;
+      theDumper << ", " << anAttrPoint ;
       theDumper<<", [";
       for(int aRow = 0; aRow < myvalues()->rows(); aRow++) {
-        if (aRow != 0)
+        if (aRow != 0){
           theDumper<<", ";
+        }
         theDumper<<myvalues()->value(aRow, 1).myDouble;
       }
       theDumper<<"]";
 
     }else{
-      AttributeTablesPtr anAttrTable = 
+      AttributeTablesPtr anAttrTable =
           aBase->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
-      theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrEdgeSelec;
+      theDumper << aBase << " = model.addFilletMultiRadiusBycurvAbs(" << aDocName;
+      theDumper << ", " << anAttrObjects;
       theDumper << ", ";
       theDumper<<"[";
-      for(int aRow = 1; aRow < myvalues()->rows()-1; aRow++) {
-        if (aRow != 1)
+      for(int aRow = 0; aRow < myvaluescurv()->rows(); aRow++) {
+        if (aRow != 0)
           theDumper<<", ";
-        theDumper<<myvalues()->value(aRow, 0).myDouble;
+        theDumper<<myvaluescurv()->value(aRow, 0).myDouble;
       }
       theDumper<<"],";
       theDumper<<"[";
-      for(int aRow = 0; aRow < myvalues()->rows(); aRow++) {
+      for(int aRow = 0; aRow < myvaluescurv()->rows(); aRow++) {
         if (aRow != 0)
           theDumper<<", ";
-        theDumper<<myvalues()->value(aRow, 1).myDouble;
+        theDumper<<myvaluescurv()->value(aRow, 1).myDouble;
       }
       theDumper<<"]";
     }
@@ -378,7 +385,7 @@ FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
   return aFillet;
 }
 
-FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+FilletPtr addFilletMultiRadiusByPoints(const std::shared_ptr<ModelAPI_Document>& thePart,
                     const ModelHighAPI_Selection & theedgeselected,
                     const std::list<ModelHighAPI_Selection>& thepoint,
                     const std::list<ModelHighAPI_Double>& theRadius,
@@ -396,8 +403,8 @@ FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
   return aFillet;
 }
 
-FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
-                    const ModelHighAPI_Selection & theedgeselected,
+FilletPtr addFilletMultiRadiusBycurvAbs(const std::shared_ptr<ModelAPI_Document>& thePart,
+                    const std::list<ModelHighAPI_Selection>& theBaseObjects,
                     const std::list<ModelHighAPI_Double>& thepointCurvCood,
                     const std::list<ModelHighAPI_Double>& theRadius,
                     const bool keepSubResults)
@@ -409,7 +416,7 @@ FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
 
   FilletPtr aFillet;
 
-  aFillet.reset(new FeaturesAPI_Fillet2D(aFeature, theedgeselected, thepointCurvCood, theRadius));
+  aFillet.reset(new FeaturesAPI_Fillet2D(aFeature, theBaseObjects, thepointCurvCood, theRadius));
 
   return aFillet;
 }
\ No newline at end of file
index 258d6e8ee59376f1206a7889bb58258fb91c9d5e..367ec3523d5d864bac526c438499269d46a06cf3 100644 (file)
@@ -137,11 +137,11 @@ public:
                                 const ModelHighAPI_Selection& theedgeselected,
                                 const std::list<ModelHighAPI_Selection>& thepoint,
                                 const std::list<ModelHighAPI_Double>& theRadius);
-  
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_Fillet2D(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                const ModelHighAPI_Selection& theedgeselected,
+                                const std::list<ModelHighAPI_Selection>& theBaseObjects,
                                 const std::list<ModelHighAPI_Double>& thepointCurvCood,
                                 const std::list<ModelHighAPI_Double>& theRadius);
   /// Destructor.
@@ -163,13 +163,13 @@ public:
                            /** Base objects */,
               arraypointradiusbypoint, FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS(),
                            ModelAPI_AttributeSelectionList,
-                           /** Base objects */, 
+                           /** Base objects */,
               myvalues, FeaturesPlugin_Fillet::VALUES_ID(),
                            ModelAPI_AttributeTables,
                            /** table for methode multi-radiuses by point */,
               myvaluescurv, FeaturesPlugin_Fillet::VALUES_CURV_ID(),
                            ModelAPI_AttributeTables,
-                           /** table for methode multi-radiuses by curviliean coodinate */,              
+                           /** table for methode multi-radiuses by curviliean coodinate */,
               radius, FeaturesPlugin_Fillet::RADIUS_ID(),
                       ModelAPI_AttributeDouble,
                       /** Value of the fixed radius fillet */,
@@ -213,7 +213,7 @@ FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
 /// \ingroup CPPHighAPI
 /// \brief Create Fillet feature.
 FEATURESAPI_EXPORT
-FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+FilletPtr addFilletMultiRadiusByPoints(const std::shared_ptr<ModelAPI_Document>& thePart,
                     const ModelHighAPI_Selection & theedgeselected,
                     const std::list<ModelHighAPI_Selection>& thepoint,
                     const std::list<ModelHighAPI_Double>& theRadius,
@@ -223,10 +223,10 @@ FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
 /// \ingroup CPPHighAPI
 /// \brief Create Fillet feature.
 FEATURESAPI_EXPORT
-FilletPtr addFillet( const std::shared_ptr<ModelAPI_Document>& thePart,
-                     const ModelHighAPI_Selection & theedgeselected,
+FilletPtr addFilletMultiRadiusBycurvAbs( const std::shared_ptr<ModelAPI_Document>& thePart,
+                     const std::list<ModelHighAPI_Selection>& theBaseObjects,
                      const std::list<ModelHighAPI_Double>& thepointCurvCood,
                      const std::list<ModelHighAPI_Double>& theRadius,
                      const bool keepSubResults= false);
-  
+
 #endif // FeaturesAPI_Fillet_H_
index 79292632e7660350e1ffffa1089f8669e465e7c2..eb8794a033891a9115dba2ad81d1885087e9a467 100644 (file)
@@ -76,6 +76,7 @@ void FeaturesPlugin_Fillet::initAttributes()
   data()->addAttribute(ARRAY_POINT_RADIUS_BY_POINTS(), ModelAPI_AttributeSelectionList::typeId());
 
   data()->addAttribute(CREATION_METHOD_BY_POINTS(), ModelAPI_AttributeString::typeId());
+  
   data()->addAttribute(CREATION_METHOD_BY_CURVILEAR_ABSCISSA(), ModelAPI_AttributeString::typeId());
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_RADIUS_ID());
@@ -85,27 +86,53 @@ void FeaturesPlugin_Fillet::initAttributes()
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_MULTIPLES_RADIUSES());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_BY_CURVILEAR_ABSCISSA());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_BY_POINTS());
+  tables(VALUES_ID())->setSize(2,2);
+  tables(VALUES_CURV_ID())->setSize(2,2);
+  ModelAPI_AttributeTables::Value aVar;
+  aVar.myDouble = 0.0;  
+  tables(VALUES_ID())->setValue(aVar,0,0);
+  tables(VALUES_CURV_ID())->setValue(aVar,0,0);
+  aVar.myDouble = 1;
+  tables(VALUES_ID())->setValue(aVar,0,1);
+  tables(VALUES_CURV_ID())->setValue(aVar,0,1);
+
+  tables(VALUES_ID())->setValue(aVar,1,0);
+  tables(VALUES_CURV_ID())->setValue(aVar,1,0);
+  aVar.myDouble = 2;
+  tables(VALUES_ID())->setValue(aVar,1,1);
+  tables(VALUES_CURV_ID())->setValue(aVar,1,1);
 
   initVersion(aSelectionList);
 }
 
 AttributePtr FeaturesPlugin_Fillet::objectsAttribute()
-{
+{ 
   return attribute(OBJECT_LIST_ID());
 }
 
 void FeaturesPlugin_Fillet::attributeChanged(const std::string& theID)
 {
   if (theID == EDGE_SELECTED_ID() 
-      && string(CREATION_METHOD())->value() == CREATION_METHOD_MULTIPLES_RADIUSES()) {
-    
+      && string(CREATION_METHOD())->value() == CREATION_METHOD_MULTIPLES_RADIUSES()
+      && string(CREATION_METHOD_MULTIPLES_RADIUSES())->value() == CREATION_METHOD_BY_POINTS()) {
+      
     AttributeSelectionPtr anEdges =
       std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(attribute(EDGE_SELECTED_ID()));
     AttributeSelectionListPtr array = selectionList(OBJECT_LIST_ID());
     if(array->isInitialized())
       array->clear();
-    array->append(anEdges->namingName() );
+    array->append(anEdges->context(), anEdges->value()); // anEdges->namingName() );
+
+  }
+  if( theID == OBJECT_LIST_ID() && 
+          !(string(CREATION_METHOD())->value() == CREATION_METHOD_MULTIPLES_RADIUSES()
+            && string(CREATION_METHOD_MULTIPLES_RADIUSES())->value() == CREATION_METHOD_BY_POINTS() ) ){
+      
+      data()->selection(EDGE_SELECTED_ID())->setValue(ObjectPtr(),GeomShapePtr());
+
   }
+
+  data()->execState(ModelAPI_StateMustBeUpdated);
 }
 
 const std::string& FeaturesPlugin_Fillet::modifiedShapePrefix() const
@@ -128,8 +155,6 @@ GeomMakeShapePtr FeaturesPlugin_Fillet::performOperation(const GeomShapePtr& the
   std::shared_ptr<GeomAlgoAPI_Fillet> aFilletBuilder;
   
   ListOfShape aFilletEdges = extractEdges(theEdges);
-
-  std::cout << "coucou aCreationMethod->value() = " <<  aCreationMethod->value()<< std::endl;
   if ( aCreationMethod->value() == CREATION_METHOD_MULTIPLES_RADIUSES() )
   {
 
@@ -153,7 +178,6 @@ GeomMakeShapePtr FeaturesPlugin_Fillet::performOperation(const GeomShapePtr& the
         aVal = aTablesAttr->value(k, 1);
         radiuses.push_back(aVal.myDouble);
     }
-
     aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, coodCurv,radiuses));
 
   }else
index e68b35d69835509a0fc3d73c1980fcfc0fb24181..92db78d538772232e892a3562219ba2f57c01c30 100644 (file)
@@ -112,6 +112,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorConcealedResult);
   aFactory->registerValidator("FeaturesPlugin_ValidatorFilletSelection",
                               new FeaturesPlugin_ValidatorFilletSelection);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorFilletSelectionEdge",
+                              new FeaturesPlugin_ValidatorFilletSelectionEdge);
   aFactory->registerValidator("FeaturesPlugin_ValidatorFillet1DSelection",
                               new FeaturesPlugin_ValidatorFillet1DSelection);
   aFactory->registerValidator("FeaturesPlugin_ValidatorCircular",
index 9235d933e78d40e886dc4902e2f84649f016f7e3..2245dc5ce79ab750ab493c7b5d79be90f90715ac 100644 (file)
@@ -971,7 +971,63 @@ bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAtt
 
   return true;
 }
+//==================================================================================================
+bool FeaturesPlugin_ValidatorFilletSelectionEdge::isValid(const AttributePtr& theAttribute,
+                                                      const std::list<std::string>& theArguments,
+                                                      Events_InfoMessage& theError) const
+{
+  AttributeSelectionPtr anAttrSelection =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+  if(!anAttrSelection.get()) {
+// LCOV_EXCL_START
+    theError =
+      "Error: Empty attribute selection.";
+    return false;
+// LCOV_EXCL_STOP
+  }
+
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  // Check all selected entities are sub-shapes of single solid
+  GeomShapePtr aBaseSolid;
+  ResultPtr aContext = anAttrSelection->context();
+  if(!aContext.get()) {
+    FeaturePtr aContFeat = anAttrSelection->contextFeature();
+    if (!aContFeat.get() || !aContFeat->results().size() ||
+      aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
+      theError = "Error: Empty selection context.";
+      return false;
+    }
+    if (aContFeat->results().size() == 1)
+      aContext = aContFeat->firstResult();
+    else {
+       theError = "Error: Too many shapes selected.";
+      return false;
+    }
+  }
+
+  ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true);
+  GeomShapePtr anOwner = aContext->shape();
+  GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner;
+
+  if (!anOwner) {
+    theError = "Error: wrong feature is selected.";
+    return false;
+  }
+
+  if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
+    anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
+    theError = "Error: Not all selected shapes are sub-shapes of solids.";
+    return false;
+  }
 
+  if (!aBaseSolid)
+    aBaseSolid = aTopLevelOwner;
+  else if (!aBaseSolid->isEqual(aTopLevelOwner)) {
+    theError = "Error: Sub-shapes of different solids have been selected.";
+    return false;
+  }
+  return true;
+}
 
 //==================================================================================================
 bool FeaturesPlugin_ValidatorFillet1DSelection::isValid(const AttributePtr& theAttribute,
index 951d4c52f969eb17ce2924d31fe0b5732e43c242..619a4b5205c4b7d647b2de368f96f0e02a96c4c8 100644 (file)
@@ -188,6 +188,22 @@ public:
                        Events_InfoMessage& theError) const;
 };
 
+/// \class FeaturesPlugin_ValidatorFilletSelectionEdge
+/// \ingroup Validators
+/// \brief Validates selection Edge for fillet operation with method multi radius.
+class FeaturesPlugin_ValidatorFilletSelectionEdge: public ModelAPI_AttributeValidator
+{
+public:
+  /// \return True if the attribute is valid. It checks whether the selection
+  /// is acceptable for boolean operation.
+  /// \param[in] theAttribute an attribute to check.
+  /// \param[in] theArguments a filter parameters.
+  /// \param[out] theError error message.
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments,
+                       Events_InfoMessage& theError) const;
+};
+
 /// \class FeaturesPlugin_ValidatorFillet1DSelection
 /// \ingroup Validators
 /// \brief Validates selection for 1d-fillet operation.
index 377873745d103202efc9b31f8e35faaf59a415ac..ff9e6856a04720dbec385694ea79f7f87562d83e 100644 (file)
@@ -66,6 +66,38 @@ const char* MYFirstCol = "Shape";
 const char* MYTrue = "True";
 const char* MYFalse = "False";
 
+class TextFieldDoubleValidator : public QDoubleValidator {
+public:
+       TextFieldDoubleValidator (QObject * parent = 0) : QDoubleValidator(parent) {}
+       TextFieldDoubleValidator (double bottom, double top, int decimals, QObject * parent) :
+       QDoubleValidator(bottom, top, decimals, parent) {}
+
+       QValidator::State validate(QString & s, int & pos) const {
+           if (s.isEmpty() || s.startsWith("0.") || s == "0" ){//|| s.startsWith("-")) {
+               // allow empty field or minus sign
+               return QValidator::Intermediate;
+           }
+           // check length of decimal places
+           QChar point = locale().decimalPoint();
+           if(s.indexOf(point) != -1) {
+               int lengthDecimals = s.length() - s.indexOf(point) - 1;
+               if (lengthDecimals > decimals()) {
+                   return QValidator::Invalid;
+               }
+           }
+
+           // check range of value
+           bool isNumber;
+           double value = locale().toDouble(s, &isNumber);
+           if (isNumber && bottom() <= value && value <= top()) {
+               return QValidator::Acceptable;
+           }
+           return QValidator::Invalid;
+       }
+
+};
+
+
 
 DataArrayItemDelegate::DataArrayItemDelegate(bool theTypeMethode)
   : QStyledItemDelegate(), myTypeMethodePoint(theTypeMethode)
@@ -90,13 +122,19 @@ QWidget* DataArrayItemDelegate::createEditor(QWidget* theParent,
                                                                           theOption,
                                                                           theIndex));
     if (aLineEdt) {
-      if( theIndex.column() == 2 )
-        aLineEdt->setValidator(new QDoubleValidator(0.0 , 10000.0, 6, aLineEdt));
-      else
-        aLineEdt->setValidator(new QDoubleValidator(0.00001 , 0.9999, 6, aLineEdt));
+      if( theIndex.column() == 1 ){
+        TextFieldDoubleValidator* doubleVal =
+                    new TextFieldDoubleValidator(0.00001 , 0.99, 6, aLineEdt);
+        doubleVal->setNotation(TextFieldDoubleValidator::StandardNotation);
+        aLineEdt->setValidator(doubleVal);
+      }
+      else{
+        QDoubleValidator* doubleVal = new QDoubleValidator(0.0 , 10000.0, 6, aLineEdt);
+        doubleVal->setNotation(QDoubleValidator::StandardNotation);
+        aLineEdt->setValidator(doubleVal);
+      }
       aEditor = aLineEdt;
     }
-    
   }
 
   connect(aEditor, SIGNAL(textEdited(const QString&)),
@@ -131,48 +169,49 @@ ModuleBase_WidgetSelector(theParent, theWorkshop, theData), myHeaderEditor(0),
   aRadiusesFrame->setFrameShape(QFrame::Box);
   aRadiusesFrame->setFrameStyle(QFrame::StyledPanel);
   QVBoxLayout* aRadiusesLayout = new QVBoxLayout();
-  
+
 
   myDataTbl = new QTableWidget(2, 3, aRadiusesFrame);
 
   myDelegate = new DataArrayItemDelegate(myTypeMethodeBypoint);
 
-  myDataTbl->installEventFilter(this);
+  //JL_CGLB myDataTbl->installEventFilter(this);
   myDataTbl->setItemDelegate(myDelegate);
 
   myDataTbl->verticalHeader()->hide();
   myDataTbl->setRowHeight(0, 25);
-  myDataTbl->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
-  
//JL_CGLB  myDataTbl->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
+
   if(myTypeMethodeBypoint){
     myfirstRowValue.push_back("Start extremity");
-    myfirstRowValue.push_back("0"); 
-    myfirstRowValue.push_back("0.5"); 
-    myLastRowValue.push_back("End extremity"); 
-    myLastRowValue.push_back("1"); 
-    myLastRowValue.push_back("0.5"); 
+    myfirstRowValue.push_back("0");
+    myfirstRowValue.push_back("1");
+    myLastRowValue.push_back("End extremity");
+    myLastRowValue.push_back("1");
+    myLastRowValue.push_back("2");
   }else{
     myfirstRowValue.push_back("0");
-    myfirstRowValue.push_back("0"); 
-    myfirstRowValue.push_back("1"); 
-    myLastRowValue.push_back("1"); 
-    myLastRowValue.push_back("1"); 
-    myLastRowValue.push_back("2"); 
+    myfirstRowValue.push_back("0");
+    myfirstRowValue.push_back("1");
+    myLastRowValue.push_back("1");
+    myLastRowValue.push_back("1");
+    myLastRowValue.push_back("2");
   }
-  
+
   if(myTypeMethodeBypoint)
     myDataTbl->hideColumn(1);
   else
     myDataTbl->hideColumn(0);
-  
+
   QStringList aHeaders;
   aHeaders << "Point";
-  aHeaders << "Curvilinear Abscissa";
+  aHeaders << "Curvilinear \n Abscissa";
   aHeaders << "Radius";
 
+
   myDataTbl->setHorizontalHeaderLabels(aHeaders);
+  //myDataTbl->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
+
   QTableWidgetItem* aItem;
   for(int j =0; j<3;j++)
   {
@@ -188,8 +227,6 @@ ModuleBase_WidgetSelector(theParent, theWorkshop, theData), myHeaderEditor(0),
 
   connect(myDataTbl, SIGNAL(cellChanged(int, int)), SLOT(onTableEdited(int, int)));
 
-  myDataTbl->horizontalHeader()->viewport()->installEventFilter(this);
-  
   aRadiusesLayout->addWidget(myDataTbl);
   ///========================
 
@@ -212,7 +249,7 @@ ModuleBase_WidgetSelector(theParent, theWorkshop, theData), myHeaderEditor(0),
   font.setPointSize(12);
   myRemoveBtn->setFont(font);
   aBtnLayout->addWidget(myRemoveBtn);
-  
+
   aRadiusesFrame->setLayout(aRadiusesLayout ) ;
   aMainLayout->addWidget(aRadiusesFrame);
 
@@ -241,7 +278,6 @@ QIntList FeaturesPlugin_WidgetFilletMultiRadiuses::shapeTypes() const
 //**********************************************************************************
 void FeaturesPlugin_WidgetFilletMultiRadiuses::deactivate()
 {
-
   ModuleBase_WidgetSelector::deactivate();
   storeValueCustom();
 }
@@ -249,51 +285,7 @@ void FeaturesPlugin_WidgetFilletMultiRadiuses::deactivate()
 //**********************************************************************************
 bool FeaturesPlugin_WidgetFilletMultiRadiuses::eventFilter(QObject* theObject, QEvent* theEvent)
 {
-  QObject* aObject = 0;
-
-  if (myDataTbl->horizontalHeader()->viewport() == theObject) {
-      aObject = theObject;
-  }
-  if (aObject) {
-    if (theEvent->type() == QEvent::MouseButtonDblClick) {
-      if (myHeaderEditor) { //delete previous editor
-        myHeaderEditor->deleteLater();
-        myHeaderEditor = 0;
-      }
-      QMouseEvent* aMouseEvent = static_cast<QMouseEvent*>(theEvent);
-      QHeaderView* aHeader = static_cast<QHeaderView*>(aObject->parent());
-      QTableWidget* aTable = static_cast<QTableWidget*>(aHeader->parentWidget());
-
-      int aShift = aTable->horizontalScrollBar()->value();
-      int aPos = aMouseEvent->x();
-      int aIndex = aHeader->logicalIndex(aHeader->visualIndexAt(aPos));
-      if (aIndex > 0) {
-        QRect aRect;
-        aRect.setLeft(aHeader->sectionPosition(aIndex));
-        aRect.setWidth(aHeader->sectionSize(aIndex));
-        aRect.setTop(0);
-        aRect.setHeight(aHeader->height());
-        aRect.adjust(1, 1, -1, -1);
-        aRect.translate(-aShift, 0);
-
-        myHeaderEditor = new QLineEdit(aHeader->viewport());
-        myHeaderEditor->move(aRect.topLeft());
-        myHeaderEditor->resize(aRect.size());
-        myHeaderEditor->setFrame(false);
-        QString aText = aHeader->model()->
-          headerData(aIndex, aHeader->orientation()).toString();
-        myHeaderEditor->setText(aText);
-        myHeaderEditor->setFocus();
-        //myEditIndex = aIndex; //save for future use
-        myHeaderEditor->installEventFilter(this); //catch focus out event
-        //if user presses Enter it should close editor
-        connect(myHeaderEditor, SIGNAL(returnPressed()), aTable, SLOT(setFocus()));
-        myHeaderEditor->show();
-        return true;
-      }
-    }
-  } else if (theEvent->type() == QEvent::FocusIn) {
-    
+  if (theEvent->type() == QEvent::FocusIn) {
     QTableWidget* aTable = dynamic_cast<QTableWidget*>(theObject);
     if (aTable) {
       ModuleBase_IPropertyPanel* aPanel = myWorkshop->propertyPanel();
@@ -303,18 +295,13 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::eventFilter(QObject* theObject, Q
     }
   }
   else if (theEvent->type() == QEvent::Show ) {
-
-   /* ModuleBase_IPropertyPanel* aPanel = myWorkshop->propertyPanel();
-    if (aPanel->activeWidget() != this) {
-      aPanel->activateWidget(this, false);
-    }*/
     DataPtr aData = myFeature->data();
     if( myTypeMethodeBypoint )
       aData->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES())
             ->setValue(FeaturesPlugin_Fillet::CREATION_METHOD_BY_POINTS() );
     else
       aData->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES())
-            ->setValue(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA() );
+          ->setValue(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA() );
   }
   return ModuleBase_WidgetSelector::eventFilter(theObject, theEvent);
 }
@@ -330,7 +317,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::storeValueCustom()
 
   if(myTypeMethodeBypoint)
     aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_ID());
-  else  
+  else
     aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
 
   // Store data-
@@ -344,7 +331,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::storeValueCustom()
       QString aTblVal = myDataTbl->item(i, j+1)->text();
       aTablesAttr->setValue( getValue( aTblVal ), i, j);
     }
-  } 
+  }
 
   return true;
 }
@@ -352,7 +339,6 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::storeValueCustom()
 //**********************************************************************************
 bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
 {
-
   if ( !mySetSelection) {
     mySetSelection = true;
     return false;
@@ -361,17 +347,18 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
 
   AttributeTablesPtr aTablesAttr;
 
-  if(myTypeMethodeBypoint)
+  if(myTypeMethodeBypoint){
     aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_ID());
-  else  
+  }
+  else{
     aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
+  }
 
   AttributeSelectionPtr anEdges =
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(aData->attribute(FeaturesPlugin_Fillet::EDGE_SELECTED_ID()));
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
+      aData->attribute(FeaturesPlugin_Fillet::EDGE_SELECTED_ID()));
 
-  
-  
-  std::map<double,std::pair<QString,QString>> aValuesSort; 
+  std::map<double,std::pair<QString,QString>> aValuesSort;
 
   double res;
   int aRows = 0;
@@ -379,7 +366,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
   if(myTypeMethodeBypoint)
   {
     if( !anEdges->isInitialized() )
-      return;
+      return false;
 
     GeomEdgePtr anEdge = GeomEdgePtr(new GeomAPI_Edge( anEdges->value()));
     GeomPointPtr first =  anEdge->firstPoint();
@@ -388,9 +375,10 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
 
     std::shared_ptr<GeomAPI_Curve> aCurve(new GeomAPI_Curve(anEdges->value()));
 
-    // Load points 
-    AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
-    AttributeDoubleArrayPtr aArrayAttr; 
+    // Load points
+    AttributeSelectionListPtr aSelectionListAttr =
+        aData->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
+    AttributeDoubleArrayPtr aArrayAttr;
     ListOfShape aPoints;
 
     std::set<GeomShapePtr> aContexts;
@@ -403,7 +391,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
 
         if (!aShape.get()) {
           aShape = aContext->shape();
-        } 
+        }
 
         aPoints.push_back(aShape);
     }
@@ -418,32 +406,32 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
       QString aName = QString::fromStdWString(attsel->namingName());
       QString aRad = findRadius( QString::number(res) );
       if ( aValuesSort.find( res ) == aValuesSort.end() )
-        aValuesSort[ res ] = std::make_pair(aName, aRad ); 
+        aValuesSort[ res ] = std::make_pair(aName, aRad );
       i++;
-    } 
-    
-    res = 0.0; 
-    aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], findRadius( QString::number(res) )) ; 
+    }
+
+    res = 0.0;
+    aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], findRadius( QString::number(res) ));
     res = 1.0;
-    aValuesSort[ res ] = std::make_pair (myLastRowValue[0], findRadius( QString::number(res) )) ; 
+    aValuesSort[ res ] = std::make_pair (myLastRowValue[0], findRadius( QString::number(res) ));
     aRows =  aValuesSort.size();
   }else{
 
     ModelAPI_AttributeTables::Value aVal;
-   if (aTablesAttr->isInitialized()){
-        
+    if (aTablesAttr->isInitialized()){
         for (int anIndex = 0; anIndex < aTablesAttr->rows(); ++anIndex) {
           aVal = aTablesAttr->value(anIndex,0);
           double curv = getValueText(aVal).toDouble();
-         if ( aValuesSort.find( curv ) == aValuesSort.end() )
-            aValuesSort[ curv ] = std::make_pair(getValueText(aVal), findRadius(getValueText(aVal)));
+          if ( aValuesSort.find( curv ) == aValuesSort.end() )
+            aValuesSort[ curv ] = std::make_pair(getValueText(aVal),
+                                                 findRadius(getValueText(aVal)));
         }
-        aRows = aTablesAttr->rows();
+        aRows = aValuesSort.size();
     }else{
-      res = 0.0; 
-      aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], myfirstRowValue[2]) ; 
+      res = 0.0;
+      aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], myfirstRowValue[2]);
       res = 1.0;
-      aValuesSort[ res ] = std::make_pair (myLastRowValue[0], myLastRowValue[2]) ; 
+      aValuesSort[ res ] = std::make_pair (myLastRowValue[0], myLastRowValue[2]);
       aRows = 2;
     }
 
@@ -452,19 +440,20 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
   QTableWidgetItem* aItem = 0;
   myDataTbl->blockSignals(true);
   aItem = myDataTbl->item( myDataTbl->rowCount() -1, 0 );
-  aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+  aItem->setFlags(Qt::NoItemFlags
+                | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
   aItem = myDataTbl->item( myDataTbl->rowCount() -1, 1 );
-  aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
-
+  aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable
+                | Qt::ItemIsEnabled | Qt::ItemIsEditable);
 
   myDataTbl->setRowCount(aRows);
-  
-  itValuesSort = aValuesSort.begin(); 
+
+  itValuesSort = aValuesSort.begin();
 
   for (int k = 0; k < aRows; k++, ++itValuesSort ) {
 
     std::pair<QString,QString> elem = itValuesSort->second;
-    QString aCurv = QString::number(itValuesSort->first); 
+    QString aCurv = QString::number(itValuesSort->first);
 
     aItem = myDataTbl->item(k, 0);
     if (aItem) {
@@ -480,7 +469,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
           aItem = new QTableWidgetItem(aCurv);
           myDataTbl->setItem(k, 1, aItem);
     }
-   aItem = myDataTbl->item(k, 2);
+    aItem = myDataTbl->item(k, 2);
     if (aItem) {
           aItem->setText( elem.second);
     } else {
@@ -493,7 +482,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
   aItem = myDataTbl->item(myDataTbl->rowCount()-1, 1 );
   aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled );
   myDataTbl->blockSignals(false);
-  
+
   return true;
 }
 
@@ -501,44 +490,38 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom()
 //**********************************************************************************
 void FeaturesPlugin_WidgetFilletMultiRadiuses::onAdd()
 {
-
   QModelIndex index = myDataTbl->currentIndex();
   int i  = index.row();
-  if( i == -1 )
-    return false; 
+  if( i != -1
+    && myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2 )
+  {
+    myDataTbl->blockSignals(true);
 
-  if( !myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2 ) 
-     return false;
+    if ( i == myDataTbl->rowCount() -1)
+      i = myDataTbl->rowCount() - 2;
 
-  myDataTbl->blockSignals(true);
+    if ( i == 0)
+      i = 1;
+    else
+      i= i+1;
+    myDataTbl->model()->insertRow(i);
 
-  if ( i == myDataTbl->rowCount() -1)
-    i = myDataTbl->rowCount() - 2;
-  
-  if ( i == 0)
-    i = 1;
-  else
-    i= i+1;
-  
-
-  myDataTbl->model()->insertRow(i);
-  QTableWidgetItem* aItem =0;
-
-  aItem = myDataTbl->item( i, 0 );
-  aItem = new QTableWidgetItem( "New" );
-  myDataTbl->setItem(i, 0, aItem);
-  aItem = new QTableWidgetItem(myfirstRowValue[1]);
-  myDataTbl->setItem(i, 1, aItem);
-  aItem = new QTableWidgetItem("-1");
-  myDataTbl->setItem(i, 1, aItem);
-   aItem = new QTableWidgetItem(myfirstRowValue[2]);
-  myDataTbl->setItem(i, 2, aItem);
-  aItem = new QTableWidgetItem(myLastRowValue[2]);
-  myDataTbl->setItem(i, 2, aItem);
-  myDataTbl->blockSignals(false);
-  
-  emit valuesChanged();
-  myDataTbl->setCurrentCell( i, 0);
+    QTableWidgetItem* aItem =0;
+
+    aItem = myDataTbl->item( i, 0 );
+    aItem = new QTableWidgetItem( "" );
+    myDataTbl->setItem(i, 0, aItem);
+
+    aItem = new QTableWidgetItem("0.1");
+    myDataTbl->setItem(i, 1, aItem);
+
+    aItem = new QTableWidgetItem("0.5");
+    myDataTbl->setItem(i, 2, aItem);
+    myDataTbl->blockSignals(false);
+
+    emit valuesChanged();
+    myDataTbl->setCurrentCell( i, 0);
+  }
 }
 
 //**********************************************************************************
@@ -546,63 +529,64 @@ void FeaturesPlugin_WidgetFilletMultiRadiuses::onRemove()
 {
   QModelIndex index = myDataTbl->currentIndex();
 
-  if( !myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2 ) 
-     return false;
-
-  myDataTbl->blockSignals(true);
-  if (index.row() == -1 
-   || index.row() == 0 
-   || index.row() == myDataTbl->rowCount() -1)
-    return;
-
-  if (myTypeMethodeBypoint)
-  {
-    QTableWidgetItem* aItem = 0;
-
-    QString aName = myDataTbl->item( index.row() , 0 )->text();
-    AttributeSelectionListPtr aSelList =
-            myFeature->data()->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
+  if( myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2
+    && index.row() != -1
+    && index.row() != 0
+    && index.row() != myDataTbl->rowCount() -1){
 
-    AttributeSelectionPtr aAttr;
-    for (int i = 0; i < aSelList->size(); i++) {
-        aAttr = aSelList->value(i);
-        if( aName == QString::fromStdWString( aAttr->namingName()) )
-        {
-          aSelList->remove({i});
-        }
+    myDataTbl->blockSignals(true);
+    if (myTypeMethodeBypoint)
+    {
+      QString aName = myDataTbl->item( index.row() , 0 )->text();
+      AttributeSelectionListPtr aSelList =
+              myFeature->data()
+                      ->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
+
+      AttributeSelectionPtr aAttr;
+      for (int i = 0; i < aSelList->size(); i++) {
+          aAttr = aSelList->value(i);
+          if( aName == QString::fromStdWString( aAttr->namingName()) )
+          {
+            aSelList->remove({i});
+          }
+      }
     }
-  }
-  myDataTbl->model()->removeRow(index.row());
-  myDataTbl->blockSignals(false);
+    myDataTbl->model()->removeRow(index.row());
+    myDataTbl->blockSignals(false);
 
-  emit valuesChanged();
+    emit valuesChanged();
+  }
 }
 
 //**********************************************************************************
 void FeaturesPlugin_WidgetFilletMultiRadiuses::onTableEdited(int theRow, int theCol)
 {
   // Do not store here column of names
-  if (theCol == 0)
-    return;
+  if (theCol != 0 && myFeature.get())
+  {
 
-  if (!myFeature.get())
-    return;
+    if( theCol == 1 && myDataTbl->item(theRow, theCol)->text() == "0" ) {
+      myDataTbl->blockSignals(true);
+      myDataTbl->item(theRow, theCol)->setText("0.1");
+      myDataTbl->blockSignals(false);
+    }
 
-  ModelAPI_AttributeTables::Value aVal = getValue(myDataTbl->item(theRow, theCol)->text());
+    ModelAPI_AttributeTables::Value aVal = getValue(myDataTbl->item(theRow, theCol)->text());
 
-  AttributeTablesPtr aTablesAttr;
+    AttributeTablesPtr aTablesAttr;
 
-  if(myTypeMethodeBypoint)
-    aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_ID());
-  else  
-    aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
+    if(myTypeMethodeBypoint)
+      aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_ID());
+    else
+      aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
 
-  if (aTablesAttr->isInitialized())
-  {
-    aTablesAttr->setValue(aVal,theRow, theCol - 1);
-    emit valuesChanged();
+    if (aTablesAttr->isInitialized())
+    {
+      aTablesAttr->setValue(aVal,theRow, theCol - 1);
+      emit valuesChanged();
+    }
   }
-}   
+}
 
 //**********************************************************************************
 bool FeaturesPlugin_WidgetFilletMultiRadiuses::
@@ -614,7 +598,6 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::
 //**********************************************************************************
 bool FeaturesPlugin_WidgetFilletMultiRadiuses::processEnter()
 {
-
   return true;
 }
 
@@ -626,27 +609,25 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::
   if ( theValues.size() > 1 || !myTypeMethodeBypoint || theValues.size() == 0 )
   {
     mySetSelection = false;
-    return false; 
+    return false;
   }
   QModelIndex index = myDataTbl->currentIndex();
   if(  index.row() == -1 )
   {
     mySetSelection = false;
-    return false; 
+    return false;
   }
 
   if( !myDataTbl->currentItem()->isSelected()){
     mySetSelection = false;
-    return false; 
+    return false;
   }
 
-
   AttributeSelectionListPtr aSelList =
     myFeature->data()->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS());
 
   ResultPtr aResult;
   GeomShapePtr aShape;
-  int aNbData = 0;
   ModuleBase_ViewerPrsPtr aValue = theValues.first();
   aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aValue->object());
   aShape = aValue->shape();
@@ -655,7 +636,7 @@ bool FeaturesPlugin_WidgetFilletMultiRadiuses::
     onRemove();
    }else{
       mySetSelection = false;
-      return false; 
+      return false;
   }
 
   return true;
@@ -683,7 +664,8 @@ QList<std::shared_ptr<ModuleBase_ViewerPrs>>
 }
 
 //**********************************************************************************
-ModelAPI_AttributeTables::Value FeaturesPlugin_WidgetFilletMultiRadiuses::getValue(QString theStrVal) const
+ModelAPI_AttributeTables::Value
+          FeaturesPlugin_WidgetFilletMultiRadiuses::getValue(QString theStrVal) const
 {
   ModelAPI_AttributeTables::Value aVal;
   aVal.myDouble = theStrVal.toDouble();
@@ -697,9 +679,9 @@ QString FeaturesPlugin_WidgetFilletMultiRadiuses::findRadius(QString thename) co
 
   if(myTypeMethodeBypoint)
     aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_ID());
-  else  
+  else
     aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID());
+
   for(int i = 0; i < aTablesAttr->rows(); ++i)
   {
     ModelAPI_AttributeTables::Value aVal = aTablesAttr->value( i, 0) ;
@@ -713,7 +695,8 @@ QString FeaturesPlugin_WidgetFilletMultiRadiuses::findRadius(QString thename) co
 }
 
 //**********************************************************************************
-QString FeaturesPlugin_WidgetFilletMultiRadiuses::getValueText(ModelAPI_AttributeTables::Value& theVal) const
+QString FeaturesPlugin_WidgetFilletMultiRadiuses::
+                         getValueText(ModelAPI_AttributeTables::Value& theVal) const
 {
 
     return QString::number(theVal.myDouble);
index 10eb4ad5f074c999e2d652d213fc878a9bab5dfb..2e2af1f382de438c8f0328a28c70468527cdb2e8 100644 (file)
@@ -106,7 +106,6 @@ protected:
   /// \param theToValidate a validation of the values flag
   virtual bool setSelection(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues,
                             const bool theToValidate);
-  
     /// Return the attribute values wrapped in a list of viewer presentations
   /// \return a list of viewer presentations, which contains an attribute result and
   /// a shape. If the attribute do not uses the shape, it is empty
@@ -140,7 +139,7 @@ private:
   /// \param theStrVal a string
   QString getValueText(ModelAPI_AttributeTables::Value& theVal) const;
 
-  /// Return a radii value from the name 
+  /// Return a radii value from the name
   /// \param theStrVal a string
   QString findRadius(QString thename) const;
 
@@ -153,14 +152,14 @@ private:
   /// Editor for table header
   QLineEdit* myHeaderEditor;
 
-  bool myTypeMethodeBypoint; 
+  bool myTypeMethodeBypoint;
 
-  bool mySetSelection; 
+  bool mySetSelection;
 
   DataArrayItemDelegate* myDelegate;
 
-  std::vector<QString> myfirstRowValue; 
-  std::vector<QString> myLastRowValue; 
+  std::vector<QString> myfirstRowValue;
+  std::vector<QString> myLastRowValue;
 
 };
 
diff --git a/src/FeaturesPlugin/Test/TestFillet_MultiRadius.py b/src/FeaturesPlugin/Test/TestFillet_MultiRadius.py
new file mode 100644 (file)
index 0000000..e0e724c
--- /dev/null
@@ -0,0 +1,182 @@
+# Copyright (C) 2014-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
+#
+
+"""
+      TestFillet.py
+      Unit test of ...
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+import salome
+
+import os
+import math
+from tempfile import TemporaryDirectory
+
+import GEOM
+from ModelAPI import *
+from salome.shaper import model
+import SHAPERSTUDY
+from salome.geom import geomBuilder
+from GeomAPI import GeomAPI_Shape
+from GeomAlgoAPI import *
+
+#import SALOMEDS
+
+
+__updated__ = "2020-10-10"
+
+salome.salome_init(1)
+
+#=========================================================================
+# Help functions
+#=========================================================================
+def removeFile(theFileName):
+    try: os.remove(theFileName)
+    except OSError: pass
+    assert not os.path.exists(theFileName), \
+            "Can not remove file {0}".format(theFileName)
+
+#=========================================================================
+# test Fillet on a solid with a constant radius
+#=========================================================================
+def testFillet_constant_radius_onsolids():
+
+    model.begin()
+    partSet = model.moduleDocument()
+    ### Create Part
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+    
+    ### Create Box
+    Box_1 = model.addBox(Part_1_doc, 20, 30, 10)
+
+    ### Create Fillet
+    Fillet_1 = model.addFillet(Part_1_doc, [model.selection("SOLID", "Box_1_1")], 2, keepSubResults = True)
+
+    ### Create Export
+    Export_1 = model.exportToXAO(Part_1_doc, '/tmp/shaper_exp_cglb.xao', model.selection("SOLID", "Fillet_1_1"), 'XAO')
+
+    model.end()
+
+    # Check results
+    ###
+    ### GEOM component
+    ###
+
+    geompy = geomBuilder.New()
+
+    O = geompy.MakeVertex(0, 0, 0)
+    OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+    OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+    OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+    
+    # where we import the fillet from SHAPER and get its basic properties
+    (imported, Fillet_1_1, [], [], []) = geompy.ImportXAO("/tmp/shaper_exp_cglb.xao")
+    geompy.addToStudy( O, 'O' )
+    geompy.addToStudy( OX, 'OX' )
+    geompy.addToStudy( OY, 'OY' )
+    geompy.addToStudy( OZ, 'OZ' )
+    geompy.addToStudy( Fillet_1_1, 'Fillet_1_1' )
+
+    myDelta = 1e-6
+    Props_shaper = geompy.BasicProperties(Fillet_1_1)
+    print("\nBasic Properties:")
+    print(" Wires length: ", Props_shaper[0])
+    print(" Surface area: ", Props_shaper[1])
+    print(" Volume      : ", Props_shaper[2])      
+
+    # where we build the same fillet in GEOM for comparison
+    Box_1 = geompy.MakeBoxDXDYDZ(20, 30, 10)
+    Fillet_1 = geompy.MakeFilletAll(Box_1, 2)
+    geompy.addToStudy( Box_1, 'Box_1' )
+    geompy.addToStudy( Fillet_1, 'Fillet_1' )
+    
+    Props_geom = geompy.BasicProperties(Fillet_1)
+    print("\nBasic Properties:")
+    print(" Wires length: ", Props_geom[0])
+    print(" Surface area: ", Props_geom[1])
+    print(" Volume      : ", Props_geom[2]) 
+
+    aRefSurface = Props_geom[1]
+    aResSurface = Props_shaper[1]
+    assert (math.fabs(aResSurface - aRefSurface) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface)
+
+    aRefVolume = Props_geom[2]
+    aResVolume = Props_shaper[2]
+    assert (math.fabs(aResVolume - aRefVolume) < myDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefVolume, aResVolume)
+
+#=========================================================================
+# test Fillet on an edge with multiple radii identified by points
+#=========================================================================
+def testFillet_multiradii_bypoints():
+    model.begin()
+    partSet = model.moduleDocument()
+
+    ### Create Part
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+
+    ### Create Box
+    Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+
+    ### Create 2 Points
+    Point_2 = model.addPoint(Part_1_doc, model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), 0.4, True, False)
+    Point_3 = model.addPoint(Part_1_doc, model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), 0.8, True, False)
+
+    ### Create Fillet on an edge with 4 radii identified by points
+    Fillet_1 = model.addFilletMultiRadiusByPoints(Part_1_doc, model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), [model.selection("VERTEX", "Point_1"), model.selection("VERTEX", "Point_2")], [0.5, 2, 1, 2], keepSubResults = True)
+
+    model.end()  
+
+#=========================================================================
+# test Fillet on an edge(s) or/and face(s) with multiple radii identified
+# by curvilinear abscissa
+#=========================================================================
+def testFillet_multiradii_bycurvabs():
+    model.begin()
+    partSet = model.moduleDocument()
+
+    ### Create Part
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+
+    ### Create Box
+    Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+
+    ### Create Fillet
+    Fillet_1 = model.addFilletMultiRadiusBycurvAbs(Part_1_doc, [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]")], [0, 0.4, 0.7, 1],[1, 2, 0.5, 2], keepSubResults = True)
+
+    ### Create Fillet
+    Fillet_2 = model.addFilletMultiRadiusBycurvAbs(Part_1_doc, [model.selection("FACE", "Box_1_1/Right")], [0, 0.5, 1],[1, 0.5, 1], keepSubResults = True)
+    
+    model.end()
+    
+if __name__ == '__main__':
+    with TemporaryDirectory() as tmp_dir:
+      
+        testFillet_constant_radius_onsolids()
+        testFillet_multiradii_bypoints()
+        testFillet_multiradii_bycurvabs()
+        
+        #=========================================================================
+        # End of test
+        #=========================================================================
index f63f540b61d56916d7202194e8952889e936d7d3..766fb0cb4716111bc8d47535d20869cdfca8e2d0 100644 (file)
          tooltip="Fillet with multiple radiuses"
          icon="icons/Features/fillet_var_multiple_radiuses.png">
       <toolbox id="by_point_method">
-        <box id="by_points"
-         title="By points"
-         tooltip="Fillet with multiple radiuses by points"
-         icon="icons/Features/fillet_multiradius_by_point.png">
-          <shape_selector id="edge_selected"
-                        icon="icons/Features/edge.png"
-                        label="Start"
-                        tooltip="Select edge"
-                        shape_types="edge"
-                        use_choice="false"
-                        concealment="true">
-           <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
-           <!--validator id="FeaturesPlugin_ValidatorFilletSelection"/-->
-          </shape_selector>
-          <multiradius-panel id="array_point_radius_by_point"
-            filter_points="false">
-            <validator id="GeomValidators_ShapeType" parameters="empty,vertex"/>
-          </multiradius-panel>
-        </box>
         <box id="by_curvilinear_abscissa_methode"
          title="By curvilinear abscissa"
          tooltip="Fillet with multiple radiuses by curvilinear abscissa"
@@ -83,7 +64,7 @@
                       label="Edges or/and faces"
                       icon=""
                       tooltip="Select objects"
-                      shape_types="edges faces solids"
+                      shape_types="edges faces"
                       use_choice="false"
                       concealment="true">
           <validator id="PartSet_DifferentObjects"/>
             <validator id="GeomValidators_ShapeType" parameters="empty,vertex"/>
           </multiradiuscurv-panel>
         </box>
+        <box id="by_points"
+         title="By points"
+         tooltip="Fillet with multiple radiuses by points"
+         icon="icons/Features/fillet_multiradius_by_point.png">
+          <shape_selector id="edge_selected"
+                        icon="icons/Features/edge.png"
+                        label="Start"
+                        tooltip="Select edge"
+                        shape_types="edge"
+                        use_choice="false"
+                        concealment="true">
+           <validator id="PartSet_DifferentObjects"/>
+           <validator id="FeaturesPlugin_ValidatorFilletSelectionEdge"/>
+          </shape_selector>
+          <multiradius-panel id="array_point_radius_by_point"
+            filter_points="false">
+            <validator id="GeomValidators_ShapeType" parameters="empty,vertex"/>
+          </multiradius-panel>
+          <validator id="FeaturesPlugin_ValidatorFilletSelection" parameters = "main_objects"/>
+        </box>
       </toolbox>
     </box>
   </toolbox>
index cebf9ca791fcf5133e83da9a5f31436ab5c704e3..7632dca2d43ba5536b40fa294d576c868c7159e0 100644 (file)
@@ -188,6 +188,55 @@ const std::string& ModelAPI_ParameterEvalMessage::error() const
   return myError;
 }
 
+ModelAPI_BuildEvalMessage::ModelAPI_BuildEvalMessage(
+  const Events_ID theID, const void* theSender)
+  : Events_Message(theID, theSender), myIsProcessed(false)
+{}
+
+ModelAPI_BuildEvalMessage::~ModelAPI_BuildEvalMessage()
+{}
+
+FeaturePtr ModelAPI_BuildEvalMessage::parameter() const
+{
+  return myParam;
+}
+
+void ModelAPI_BuildEvalMessage::setParameter(FeaturePtr theParam)
+{
+  myParam = theParam;
+}
+
+void ModelAPI_BuildEvalMessage::setResults(
+    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+    const double theResult, const std::string& theError)
+{
+  myParamsList = theParamsList;
+  myResult = theResult;
+  myError = theError;
+  myIsProcessed = true;
+}
+
+bool ModelAPI_BuildEvalMessage::isProcessed()
+{
+  return myIsProcessed;
+}
+
+const std::list<std::shared_ptr<ModelAPI_ResultParameter> >&
+  ModelAPI_BuildEvalMessage::params() const
+{
+  return myParamsList;
+}
+
+const double& ModelAPI_BuildEvalMessage::result() const
+{
+  return myResult;
+}
+
+const std::string& ModelAPI_BuildEvalMessage::error() const
+{
+  return myError;
+}
+
 ModelAPI_ComputePositionsMessage::ModelAPI_ComputePositionsMessage(
   const Events_ID theID, const void* theSender)
   : Events_Message(theID, theSender)
index fccf6e24002965de8378e7c4553460eb6808d3b3..11a6aecc9724380c1513ba07571bd8c99ca340e3 100644 (file)
@@ -352,6 +352,59 @@ class ModelAPI_ParameterEvalMessage : public Events_Message
   MODELAPI_EXPORT const std::string& error() const;
 };
 
+class ModelAPI_BuildEvalMessage : public Events_Message
+{
+  FeaturePtr myParam; ///< parameters that should be evaluated
+  bool myIsProcessed; ///< true if results were set
+  /// result of processing, list of parameters in expression found
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> > myParamsList;
+  double myResult; ///< result of processing, the computed value of the expression
+  std::string myError; ///< error of processing, empty if there is no error
+
+ public:
+  /// Static. Returns EventID of the message.
+  MODELAPI_EXPORT static Events_ID& eventId()
+  {
+    static const char * MY_BUILD_EVALUATION_EVENT_ID("ParameterEvaluationRequest");
+    static Events_ID anId = Events_Loop::eventByName(MY_BUILD_EVALUATION_EVENT_ID);
+    return anId;
+  }
+
+  /// Useful method that creates and sends the event.
+  /// Returns the message, processed, with the resulting fields filled.
+  MODELAPI_EXPORT static std::shared_ptr<ModelAPI_BuildEvalMessage>
+    send(FeaturePtr theParameter, const void* theSender)
+  {
+    std::shared_ptr<ModelAPI_BuildEvalMessage> aMessage =
+      std::shared_ptr<ModelAPI_BuildEvalMessage>(
+      new ModelAPI_BuildEvalMessage(eventId(), theSender));
+    aMessage->setParameter(theParameter);
+    Events_Loop::loop()->send(aMessage);
+    return aMessage;
+  }
+
+  /// Creates an empty message
+  MODELAPI_EXPORT ModelAPI_BuildEvalMessage(const Events_ID theID, const void* theSender = 0);
+  /// The virtual destructor
+  MODELAPI_EXPORT virtual ~ModelAPI_BuildEvalMessage();
+
+  /// Returns a parameter stored in the message
+  MODELAPI_EXPORT FeaturePtr parameter() const;
+  /// Sets a parameter to the message
+  MODELAPI_EXPORT void setParameter(FeaturePtr theParam);
+  /// Sets the results of processing
+  MODELAPI_EXPORT void setResults(
+    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+    const double theResult, const std::string& theError);
+  /// Returns true if the expression is processed
+  MODELAPI_EXPORT bool isProcessed();
+  /// Returns the results of processing: list of parameters found in the expression
+  MODELAPI_EXPORT const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& params() const;
+  /// Returns the expression result
+  MODELAPI_EXPORT const double& result() const;
+  /// Returns the interpreter error (empty if no error)
+  MODELAPI_EXPORT const std::string& error() const;
+};
 
 /// Message to ask compute the positions of parameters in the expression
 class ModelAPI_ComputePositionsMessage : public Events_Message
index 772dc05c219e2fa9c563ea82796013ef67860cca..035b5d31f3a5de0f681837bc3e1379dbc62a7dff 100644 (file)
@@ -27,7 +27,7 @@ from FeaturesAPI import addPipe
 from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addSplit
 from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes
 from FeaturesAPI import addRecover
-from FeaturesAPI import addFillet, addChamfer
+from FeaturesAPI import addFillet,addFilletMultiRadiusBycurvAbs, addFilletMultiRadiusByPoints, addChamfer
 from FeaturesAPI import addFusionFaces
 from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle
 from FeaturesAPI import addRemoveResults