Salome HOME
Additional fix for the issue #1876 : now compsolid result is also splitted when selec...
authormpv <mpv@opencascade.com>
Wed, 18 Jan 2017 13:03:01 +0000 (16:03 +0300)
committermpv <mpv@opencascade.com>
Wed, 18 Jan 2017 13:03:01 +0000 (16:03 +0300)
src/GeomAPI/GeomAPI_Angle.cpp [deleted file]
src/GeomAPI/GeomAPI_Angle.h [deleted file]
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h

diff --git a/src/GeomAPI/GeomAPI_Angle.cpp b/src/GeomAPI/GeomAPI_Angle.cpp
deleted file mode 100644 (file)
index 9849b9e..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File:        GeomAPI_Angle.cpp
-// Created:     19 April 2016
-// Author:      Artem ZHIDKOV
-
-#include <GeomAPI_Angle.h>
-#include <GeomAPI_Dir.h>
-#include <GeomAPI_Lin.h>
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_XYZ.h>
-
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_XYZ.hxx>
-
-/// \struct ThreePoints
-/// \brief Used to store info about angle point and state.
-struct ThreePoints {
-  gp_Pnt myCenter;
-  gp_Pnt myFirst;
-  gp_Pnt mySecond;
-  bool myReversed[2];
-};
-
-#define MY_ANGLE implPtr<ThreePoints>()
-#define PI 3.1415926535897932
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
-                             const std::shared_ptr<GeomAPI_Pnt>& theFirst,
-                             const std::shared_ptr<GeomAPI_Pnt>& theSecond)
-{
-  ThreePoints* aResult = new ThreePoints;
-  aResult->myCenter = gp_Pnt(theCenter->x(), theCenter->y(), theCenter->z());
-  aResult->myFirst  = gp_Pnt(theFirst->x(), theFirst->y(), theFirst->z());
-  aResult->mySecond = gp_Pnt(theSecond->x(), theSecond->y(), theSecond->z());
-  aResult->myReversed[0] = aResult->myReversed[1] = false;
-  return aResult;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theStart1,
-                             const std::shared_ptr<GeomAPI_Pnt>& theEnd1,
-                             const std::shared_ptr<GeomAPI_Pnt>& theStart2,
-                             const std::shared_ptr<GeomAPI_Pnt>& theEnd2)
-{
-  std::shared_ptr<GeomAPI_Lin> aLine1(new GeomAPI_Lin(theStart1, theEnd1));
-  std::shared_ptr<GeomAPI_Lin> aLine2(new GeomAPI_Lin(theStart2, theEnd2));
-  std::shared_ptr<GeomAPI_Pnt> aCenter = aLine1->intersect(aLine2);
-  bool isParallel = !aCenter;
-  if (isParallel)
-    aCenter = theStart1;
-  std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
-  if (isParallel)
-    aPoint1 = aPoint2 = theEnd1;
-  else {
-    aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
-    aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
-  }
-  ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
-  anAngle->myReversed[0] = aPoint1 == theStart1;
-  anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
-  return anAngle;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
-                             const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
-{
-  std::shared_ptr<GeomAPI_Pnt> aCenter = theLine1->intersect(theLine2);
-  if (!aCenter)
-    aCenter = theLine1->location();
-  double aCoeff = theReversed1 ? -1.0 : 1.0;
-  std::shared_ptr<GeomAPI_Pnt> aPoint1(new GeomAPI_Pnt(
-      aCenter->xyz()->added(theLine1->direction()->xyz()->multiplied(aCoeff))));
-  aCoeff = theReversed2 ? -1.0 : 1.0;
-  std::shared_ptr<GeomAPI_Pnt> aPoint2(new GeomAPI_Pnt(
-      aCenter->xyz()->added(theLine2->direction()->xyz()->multiplied(aCoeff))));
-  ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
-  anAngle->myReversed[0] = theReversed1;
-  anAngle->myReversed[1] = theReversed2;
-  return anAngle;
-}
-
-
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
-                             const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
-                             const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
-                             const std::shared_ptr<GeomAPI_Pnt>& theEndLine2)
-    : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
-                             const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
-    : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
-                             const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
-                             const std::shared_ptr<GeomAPI_Pnt>& thePoint2)
-    : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
-{
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::center()
-{
-  gp_Pnt aPnt = MY_ANGLE->myCenter;
-  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::firstPoint()
-{
-  gp_Pnt aPnt = MY_ANGLE->myFirst;
-  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::secondPoint()
-{
-  gp_Pnt aPnt = MY_ANGLE->mySecond;
-  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-double GeomAPI_Angle::angleDegree()
-{
-  return angleRadian() * 180.0 / PI;
-}
-
-double GeomAPI_Angle::angleRadian()
-{
-  ThreePoints* anAngle = MY_ANGLE;
-  gp_Dir aDir1(anAngle->myFirst.XYZ() - anAngle->myCenter.XYZ());
-  gp_Dir aDir2(anAngle->mySecond.XYZ() - anAngle->myCenter.XYZ());
-  return aDir1.Angle(aDir2);
-}
-
-bool GeomAPI_Angle::isReversed(int theIndex)
-{
-  return MY_ANGLE->myReversed[theIndex & 0x1];
-}
diff --git a/src/GeomAPI/GeomAPI_Angle.h b/src/GeomAPI/GeomAPI_Angle.h
deleted file mode 100644 (file)
index 8d87433..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File:        GeomAPI_Angle.h
-// Created:     19 April 2016
-// Author:      Artem ZHIDKOV
-
-#ifndef GeomAPI_Angle_H_
-#define GeomAPI_Angle_H_
-
-#include <GeomAPI_Interface.h>
-
-class GeomAPI_Lin;
-class GeomAPI_Pnt;
-
-/// \class GeomAPI_Angle
-/// \ingroup DataModel
-/// \brief Build an angle in 3D
-class GeomAPI_Angle : public GeomAPI_Interface
-{
-public:
-  /// Creation of an angle defined by two lines' start, end points
-  GEOMAPI_EXPORT
-  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
-                const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
-                const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
-                const std::shared_ptr<GeomAPI_Pnt>& theEndLine2);
-  /// Creation of an angle defined by two lines taking into account their orientation
-  GEOMAPI_EXPORT
-  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
-                const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2);
-  /// Creation of an angle defined by three points
-  GEOMAPI_EXPORT
-  GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
-                const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
-                const std::shared_ptr<GeomAPI_Pnt>& thePoint2);
-
-  /// Returns central point of the angle
-  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> center();
-  /// Returns point on the first edge
-  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> firstPoint();
-  /// Returns point on the second edge
-  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> secondPoint();
-
-  /// Returns value of the angle in degrees
-  GEOMAPI_EXPORT double angleDegree();
-  /// Returns value of the angle in radians
-  GEOMAPI_EXPORT double angleRadian();
-
-  /// Returns \c true if the line is reversed during angle calculation.
-  /// If theIndex = 0, the result corresponds to the first line,
-  /// if theIndex = 1, the to the second line
-  GEOMAPI_EXPORT bool isReversed(int theIndex);
-};
-
-#endif
-
index 8fc2d5e77296ff285f37c758a5a1bafae4262cea..af701cb26bc31b7209d89a4c26f3d78f04ff1a11 100644 (file)
@@ -399,6 +399,32 @@ static bool setInvalidIfFalse(TDF_Label& theLab, const bool theFlag) {
   return theFlag;
 }
 
+void Model_AttributeSelection::split(
+  ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType)
+{
+  TopTools_ListOfShape aSubs;
+  for(TopoDS_Iterator anExplorer(theNewShape); anExplorer.More(); anExplorer.Next()) {
+    if (!anExplorer.Value().IsNull() &&
+      anExplorer.Value().ShapeType() == theType) {
+        aSubs.Append(anExplorer.Value());
+    } else { // invalid case; bad result shape, so, impossible to split easily
+      aSubs.Clear();
+      break;
+    }
+  }
+  if (aSubs.Extent() > 1) { // ok to split
+    TopTools_ListIteratorOfListOfShape aSub(aSubs);
+    GeomShapePtr aSubSh(new GeomAPI_Shape);
+    aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+    setValue(theContext, aSubSh);
+    for(aSub.Next(); aSub.More(); aSub.Next()) {
+      GeomShapePtr aSubSh(new GeomAPI_Shape);
+      aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+      myParent->append(theContext, aSubSh);
+    }
+  }
+}
+
 bool Model_AttributeSelection::update()
 {
   TDF_Label aSelLab = selectionLabel();
@@ -464,28 +490,9 @@ bool Model_AttributeSelection::update()
       // shape type shoud not not changed: if shape becomes compound of such shapes, then split
       if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
           anOldShape.ShapeType() != aNewShape.ShapeType() &&
-          aNewShape.ShapeType() == TopAbs_COMPOUND) {
-        TopTools_ListOfShape aSubs;
-        for(TopoDS_Iterator anExplorer(aNewShape); anExplorer.More(); anExplorer.Next()) {
-          if (!anExplorer.Value().IsNull() &&
-              anExplorer.Value().ShapeType() == anOldShape.ShapeType()) {
-            aSubs.Append(anExplorer.Value());
-          } else { // invalid case; bad result shape, so, impossible to split easily
-            aSubs.Clear();
-            break;
-          }
-        }
-        if (aSubs.Extent() > 1) { // ok to split
-          TopTools_ListIteratorOfListOfShape aSub(aSubs);
-          GeomShapePtr aSubSh(new GeomAPI_Shape);
-          aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
-          setValue(aContext, aSubSh);
-          for(aSub.Next(); aSub.More(); aSub.Next()) {
-            GeomShapePtr aSubSh(new GeomAPI_Shape);
-            aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
-            myParent->append(aContext, aSubSh);
-          }
-        }
+          (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID))
+      {
+        split(aContext, aNewShape, anOldShape.ShapeType());
       }
       owner()->data()->sendAttributeUpdated(this);  // send updated if shape is changed
     }
@@ -1202,6 +1209,19 @@ void Model_AttributeSelection::updateInHistory()
     // update scope to reset to a new one
     myScope.Clear();
     myRef.setValue(aModifierResFound);
+    // if context shape type is changed to more complicated and this context is selected, split
+    if (myParent &&!aSubShape.get() && aModifierResFound->shape().get() && aContext->shape().get())
+    {
+      TopoDS_Shape anOldShape = aContext->shape()->impl<TopoDS_Shape>();
+      TopoDS_Shape aNewShape = aModifierResFound->shape()->impl<TopoDS_Shape>();
+      if (!anOldShape.IsNull() && !aNewShape.IsNull() &&
+        anOldShape.ShapeType() != aNewShape.ShapeType() &&
+        (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) {
+        // prepare for split in "update"
+        TDF_Label aSelLab = selectionLabel();
+        split(aContext, aNewShape, anOldShape.ShapeType());
+      }
+    }
     update(); // it must recompute a new sub-shape automatically
   }
 }
index a24ca2d818c6d3bc639862b9ce21e0d2f8c86eae..93fb9876e0888bd5a6c85e607163a367c605f3f2 100644 (file)
@@ -11,6 +11,7 @@
 #include "Model_AttributeReference.h"
 #include <ModelAPI_AttributeSelection.h>
 #include <TDF_LabelMap.hxx>
+#include <TopoDS_Shape.hxx>
 
 class Model_AttributeSelectionList;
 
@@ -121,6 +122,9 @@ protected:
   /// Sets the parent attribute
   void setParent(Model_AttributeSelectionList* theParent);
 
+  /// Splits theNewShape into sub-shapes of theType type (for the list parent of this attribute)
+  void split(ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType);
+
   friend class Model_Data;
   friend class Model_AttributeSelectionList;
 };