Salome HOME
Update Placement feature with flags Reverse and Centering
authorazv <azv@opencascade.com>
Tue, 24 Mar 2015 09:56:46 +0000 (12:56 +0300)
committerazv <azv@opencascade.com>
Tue, 24 Mar 2015 09:57:30 +0000 (12:57 +0300)
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.h
src/FeaturesPlugin/placement_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Placement.h

index 44ad7523e4f6330e8853cec73da101699c1def22..fd59eb3867880427717fb2d801961f83cce6d43e 100644 (file)
@@ -9,6 +9,7 @@
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeBoolean.h>
 
 #include <GeomAPI_Face.h>
 #include <GeomAPI_Pln.h>
@@ -26,6 +27,8 @@ void FeaturesPlugin_Placement::initAttributes()
 {
   data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::type());
   data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::type());
+  data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
+  data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::type());
 }
 
 void FeaturesPlugin_Placement::execute()
@@ -87,11 +90,16 @@ void FeaturesPlugin_Placement::execute()
     return;
   }
 
-  std::shared_ptr<GeomAPI_Pln> aBasePlane = aBaseFace1->getPlane();
-  std::shared_ptr<GeomAPI_Pln> aSlavePlane = aSlaveFace1->getPlane();
+  // Flags of the Placement
+  AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+      data()->attribute(FeaturesPlugin_Placement::REVERSE_ID()));
+  bool isReverse = aBoolAttr->value();
+  aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+      data()->attribute(FeaturesPlugin_Placement::CENTERING_ID()));
+  bool isCentering = aBoolAttr->value();
 
   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
-  GeomAlgoAPI_Placement aFeature(aSlaveObject, aSlavePlane, aBasePlane);
+  GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseFaceContext, aSlaveFace1, aBaseFace1, isReverse, isCentering);
   if(!aFeature.isDone()) {
     static const std::string aFeatureError = "Placement algorithm failed";
     setError(aFeatureError);
index e96541de32bf43b44a7b147077f6d97ac611a45a..bf74f1364ce4c7f56d42f5485a25d6d9edad51c7 100644 (file)
@@ -43,6 +43,18 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature
     static const std::string MY_ATTRACT_FACE_ID("placement_attractable_face");
     return MY_ATTRACT_FACE_ID;
   }
+  /// attribute name of flag of reverse direction
+  inline static const std::string& REVERSE_ID()
+  {
+    static const std::string MY_REVERSE_ID("placement_reverse_direction");
+    return MY_REVERSE_ID;
+  }
+  /// attribute name of flag of centering position
+  inline static const std::string& CENTERING_ID()
+  {
+    static const std::string MY_CENTERING_ID("placement_centering");
+    return MY_CENTERING_ID;
+  }
 
   /// Returns the kind of a feature
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
index fd4924fa027d7f1625c9c85a286d534acd9e573f..4a8832004b43d339540bc395cccd6a9f966820e0 100644 (file)
@@ -8,11 +8,19 @@
     shape_types="face"
   />
   <shape_selector id="placement_attractable_face" 
-               label="Select a face" 
-               icon=":icons/cut_shape.png" 
-               tooltip="Select a face of moved object" 
-               shape_types="face" 
-               concealment="true" >
-       <validator id="PartSet_DifferentObjects"/>
+    label="Select a face" 
+    icon=":icons/cut_shape.png" 
+    tooltip="Select a face of moved object" 
+    shape_types="face" 
+    concealment="true" >
+    <validator id="PartSet_DifferentObjects"/>
   </shape_selector>
+  <boolvalue id="placement_reverse_direction"
+    label="Reverse"
+    default="false"
+    tooltip="Reverse placement direction"/>
+  <boolvalue id="placement_centering"
+    label="Centering"
+    default="false"
+    tooltip="Center faces under placement"/>
 </source>
index 3cc4f85aedc6bea31cedcd8ecf2e713996ef2a54..e5714a22e789ff59934315f5f9f0fa09b32c5bea 100644 (file)
@@ -8,52 +8,85 @@
 #include <GeomAlgoAPI_DFLoader.h>
 
 #include <GeomAPI_Pnt.h>
+#include <GeomAPI_Pln.h>
 
 #include <BRepBuilderAPI_Transform.hxx>
 #include <gp_Trsf.hxx>
 #include <gp_Quaternion.hxx>
 #include <TopExp_Explorer.hxx>
 #include <BRepCheck_Analyzer.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 #include <GProp_GProps.hxx>
 #include <BRepGProp.hxx>
 #include <Precision.hxx>
+
 #define DEB_PLACEMENT 1
 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
-    std::shared_ptr<GeomAPI_Shape> theAttractiveFace,
-    std::shared_ptr<GeomAPI_Pln> theSourcePlane,
-    std::shared_ptr<GeomAPI_Pln> theDestPlane)
+    std::shared_ptr<GeomAPI_Shape> theSourceShape,
+    std::shared_ptr<GeomAPI_Shape> theDestShape,
+    std::shared_ptr<GeomAPI_Face> theSourcePlane,
+    std::shared_ptr<GeomAPI_Face> theDestPlane,
+    bool theIsReverse,
+    bool theIsCentering)
   : myDone(false),
     myShape(new GeomAPI_Shape())
 {
-  build(theAttractiveFace, theSourcePlane, theDestPlane);
+  build(theSourceShape, theDestShape, theSourcePlane, theDestPlane, theIsReverse, theIsCentering);
 }
 
 void GeomAlgoAPI_Placement::build(
-    const std::shared_ptr<GeomAPI_Shape>& theAttractiveShape,
-    const std::shared_ptr<GeomAPI_Pln>& theSourcePlane,
-    const std::shared_ptr<GeomAPI_Pln>& theDestPlane)
+    const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
+    const std::shared_ptr<GeomAPI_Shape>& theDestShape,
+    const std::shared_ptr<GeomAPI_Face>& theSourcePlane,
+    const std::shared_ptr<GeomAPI_Face>& theDestPlane,
+    bool theIsReverse,
+    bool theIsCentering)
 {
-  std::shared_ptr<GeomAPI_Dir> aSourceDir = theSourcePlane->direction();
-  std::shared_ptr<GeomAPI_Pnt> aSourceLoc = theSourcePlane->location();
-  std::shared_ptr<GeomAPI_Dir> aDestDir = theDestPlane->direction();
-  std::shared_ptr<GeomAPI_Pnt> aDestLoc = theDestPlane->location();
+  std::shared_ptr<GeomAPI_Pln> aSourcePlane = theSourcePlane->getPlane();
+  std::shared_ptr<GeomAPI_Pln> aDestPlane = theDestPlane->getPlane();
+  std::shared_ptr<GeomAPI_Dir> aSourceDir = aSourcePlane->direction();
+  std::shared_ptr<GeomAPI_Pnt> aSourceLoc = aSourcePlane->location();
+  std::shared_ptr<GeomAPI_Dir> aDestDir = aDestPlane->direction();
+  std::shared_ptr<GeomAPI_Pnt> aDestLoc = aDestPlane->location();
+
+  // Initial shapes
+  const TopoDS_Shape& aSourceShape = theSourceShape->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aDestShape = theDestShape->impl<TopoDS_Shape>();
 
   // Calculate transformation
   gp_Trsf aTrsf;
   gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z());
   gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z());
+  // Check the material of the solids to be on the correct side
+  BRepClass3d_SolidClassifier aClassifier;
+  aClassifier.Load(aSourceShape);
+  static const double aTransStep = 10. * Precision::Confusion();
+  gp_Pnt aPoint(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
+  aPoint.Translate(aSrcDir * aTransStep);
+  aClassifier.Perform(aPoint, Precision::Confusion());
+  if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) ||
+      (aClassifier.State() == TopAbs_IN && theIsReverse))
+    aSrcDir.Reverse();
+  aClassifier.Load(aDestShape);
+  aPoint.SetCoord(aDestLoc->x(), aDestLoc->y(), aDestLoc->z());
+  aPoint.Translate(aDstDir * aTransStep);
+  aClassifier.Perform(aPoint, Precision::Confusion());
+  if (aClassifier.State() == TopAbs_IN)
+    aDstDir.Reverse();
+  // Calculate rotation
   gp_Quaternion aRot(aSrcDir, aDstDir);
   aTrsf.SetRotation(aRot);
-  gp_Vec aSrcCenter(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
-  aSrcCenter.Transform(aTrsf);
-  gp_Vec aTrans(aDestLoc->x() - aSrcCenter.X(),
-                aDestLoc->y() - aSrcCenter.Y(),
-                aDestLoc->z() - aSrcCenter.Z());
+  // Calculate translation
+  gp_Vec aSrcLoc(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
+  gp_Vec aDstLoc(aDestLoc->x(), aDestLoc->y(), aDestLoc->z());
+  if (!theIsCentering)
+    aDstLoc = aSrcLoc + gp_Vec(aDstDir) * (aDstLoc-aSrcLoc).Dot(aDstDir);
+  aSrcLoc.Transform(aTrsf);
+  gp_Vec aTrans = aDstLoc - aSrcLoc;
   aTrsf.SetTransformation(aRot, aTrans);
 
   // Transform the shape with copying it
-  const TopoDS_Shape& aShape = theAttractiveShape->impl<TopoDS_Shape>();
-  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aShape, aTrsf, true);
+  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
   if(aBuilder) {
     setImpl(aBuilder);
     myDone = aBuilder->IsDone() == Standard_True;
index 7bebf97c991277d85bf28dbdffffad328b9bc7e7..703f609c159c6f7a23dc45d209e34ac34555d797 100644 (file)
@@ -10,7 +10,7 @@
 #include <GeomAlgoAPI.h>
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_Dir.h>
-#include <GeomAPI_Pln.h>
+#include <GeomAPI_Face.h>
 #include <GeomAlgoAPI_MakeShape.h>
 #include <GeomAPI_DataMapOfShapeShape.h>
 #include <memory>
@@ -24,13 +24,19 @@ class GeomAlgoAPI_Placement : public GeomAPI_Interface
 public:
   /** \brief Creates an object which is obtained from current object by transformation calculated
    *         as a movement of the source plane to be coincident with the destination plane
-   *  \param[in] theAttractiveShape shape to be moved
-   *  \param[in] theSourcePlane     plane on the shape to be made coincident with destination plane
-   *  \param[in] theDestPlane       destination plane
+   *  \param[in] theSourceShape  shape to be moved
+   *  \param[in] theDestShape    invariabt shape
+   *  \param[in] theSourcePlane  plane on the shape to be made coincident with destination plane
+   *  \param[in] theDestPlane    destination plane
+   *  \param[in] theIsReverse    indicates that the solid materials should be on the same side against the destination plane
+   *  \param[in] theIsCentering  indicates the planes should be centered
    */
-  GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr<GeomAPI_Shape> theAttractiveShape,
-                                           std::shared_ptr<GeomAPI_Pln> theSourcePlane,
-                                           std::shared_ptr<GeomAPI_Pln> theDestPlane);
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Shape> theDestShape,
+                                           std::shared_ptr<GeomAPI_Face> theSourcePlane,
+                                           std::shared_ptr<GeomAPI_Face> theDestPlane,
+                                           bool theIsReverse = false,
+                                           bool theIsCentering = false);
 
   /// Returns True if algorithm succeed
   GEOMALGOAPI_EXPORT const bool isDone() const
@@ -56,9 +62,12 @@ public:
 
 private:
   /// builds resulting shape
-  void build(const std::shared_ptr<GeomAPI_Shape>& theAttractiveShape,
-             const std::shared_ptr<GeomAPI_Pln>& theSourcePlane,
-             const std::shared_ptr<GeomAPI_Pln>& theDestPlane);
+  void build(const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
+             const std::shared_ptr<GeomAPI_Shape>& theDestShape,
+             const std::shared_ptr<GeomAPI_Face>& theSourcePlane,
+             const std::shared_ptr<GeomAPI_Face>& theDestPlane,
+             bool theIsReverse,
+             bool theIsCentering);
 
   /// fields
   bool myDone;