]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
New feature "Placement" was implemented
authorazv <azv@opencascade.com>
Tue, 2 Dec 2014 12:02:48 +0000 (15:02 +0300)
committerazv <azv@opencascade.com>
Tue, 2 Dec 2014 12:03:39 +0000 (15:03 +0300)
13 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Placement.h [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI_Edge.cpp
src/GeomAPI/GeomAPI_Face.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Face.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Placement.h [new file with mode: 0644]

index 5b8f1c075187a52ff21bde41de6ed6ea1547479c..406032e871b71dbd79d491641b7760b616de84de 100644 (file)
@@ -4,8 +4,9 @@ SET(PROJECT_HEADERS
     FeaturesPlugin.h
     FeaturesPlugin_Plugin.h
     FeaturesPlugin_Extrusion.h
-       FeaturesPlugin_Boolean.h
-       FeaturesPlugin_Group.h
+    FeaturesPlugin_Boolean.h
+    FeaturesPlugin_Group.h
+    FeaturesPlugin_Placement.h
 )
 
 SET(PROJECT_SOURCES
@@ -13,6 +14,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Extrusion.cpp
     FeaturesPlugin_Boolean.cpp
     FeaturesPlugin_Group.cpp
+    FeaturesPlugin_Placement.cpp
 )
 
 SET(XML_RESOURCES
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
new file mode 100644 (file)
index 0000000..b9b567f
--- /dev/null
@@ -0,0 +1,155 @@
+// File:        FeaturesPlugin_Placement.cpp
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#include "FeaturesPlugin_Placement.h"
+
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeSelection.h>
+
+#include <GeomAPI_Face.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAlgoAPI_Placement.h>
+
+FeaturesPlugin_Placement::FeaturesPlugin_Placement()
+{
+}
+
+void FeaturesPlugin_Placement::initAttributes()
+{
+  data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::type());
+  data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::type());
+}
+
+void FeaturesPlugin_Placement::execute()
+{
+  // Verify the base face
+  std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = std::dynamic_pointer_cast<
+    ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_FACE_ID()));
+  if (!aFaceRef)
+    return;
+
+  std::shared_ptr<GeomAPI_Shape> aBaseFace = 
+    std::dynamic_pointer_cast<GeomAPI_Shape>(aFaceRef->value());
+  if (!aBaseFace)
+    return;
+
+  std::shared_ptr<GeomAPI_Shape> aBaseFaceContext;
+  ResultPtr aContextRes = aFaceRef->context();
+  if (aContextRes) {
+    if (aContextRes->groupName() == ModelAPI_ResultBody::group())
+      aBaseFaceContext = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
+    else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
+      aBaseFaceContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
+  }
+  if (!aBaseFaceContext) {
+    static const std::string aContextError = "The selection context is bad";
+    setError(aContextError);
+    return;
+  }
+
+  // Verify the attractive face
+  aFaceRef = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
+      data()->attribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID()));
+
+  std::shared_ptr<GeomAPI_Shape> anAttractiveFace = 
+    std::dynamic_pointer_cast<GeomAPI_Shape>(aFaceRef->value());
+  if (!anAttractiveFace)
+    return;
+
+  std::shared_ptr<GeomAPI_Shape> anAttractiveFaceContext;
+  aContextRes = aFaceRef->context();
+  if (aContextRes) {
+    if (aContextRes->groupName() == ModelAPI_ResultBody::group())
+      anAttractiveFaceContext = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
+    else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
+      anAttractiveFaceContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
+  }
+  if (!anAttractiveFaceContext) {
+    static const std::string aContextError = "The selection context is bad";
+    setError(aContextError);
+    return;
+  }
+
+  // Verify faces planarity
+  std::shared_ptr<GeomAPI_Face> aBaseFace1(new GeomAPI_Face(aBaseFace));
+  std::shared_ptr<GeomAPI_Face> anAttractFace1(new GeomAPI_Face(anAttractiveFace));
+  if (!aBaseFace1->isPlanar() || !anAttractFace1->isPlanar()) {
+    static const std::string aPlanarityError = "One of selected face is not planar";
+    setError(aPlanarityError);
+    return;
+  }
+
+  std::shared_ptr<GeomAPI_Pln> aBasePlane = aBaseFace1->getPlane();
+  std::shared_ptr<GeomAPI_Pln> anAttractivePlane = anAttractFace1->getPlane();
+
+  std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
+  GeomAlgoAPI_Placement aFeature(anAttractiveFaceContext, anAttractivePlane, aBasePlane);
+  if(!aFeature.isDone()) {
+    static const std::string aFeatureError = "Placement algorithm failed";
+    setError(aFeatureError);
+    return;
+  }
+
+  // Check if shape is valid
+  if (aFeature.shape()->isNull()) {
+    static const std::string aShapeError = "Resulting shape is Null";
+    setError(aShapeError);
+    return;
+  }
+  if(!aFeature.isValid()) {
+    std::string aFeatureError = "Warning: resulting shape is not valid";
+    setError(aFeatureError);
+    return;
+  }  
+  //LoadNamingDS
+  LoadNamingDS(aFeature, aResultBody, anAttractiveFace, anAttractiveFaceContext);
+
+  setResult(aResultBody);
+}
+
+//============================================================================
+void FeaturesPlugin_Placement::LoadNamingDS(
+    GeomAlgoAPI_Placement& theFeature,
+    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+    std::shared_ptr<GeomAPI_Shape> theBasis,
+    std::shared_ptr<GeomAPI_Shape> theContext)
+{
+  /// TODO: SZY
+/*
+
+  //load result
+  if(theBasis->isEqual(theContext))
+    theResultBody->store(theFeature.shape());
+  else
+    theResultBody->storeGenerated(theContext, theFeature.shape()); 
+
+  GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
+  theFeature.mapOfShapes(*aSubShapes);
+
+    //Insert lateral face : Face from Edge
+  theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape(), theBasis, EDGE,_LATERAL_TAG, *aSubShapes);
+
+  //Insert bottom face
+  std::shared_ptr<GeomAPI_Shape> aBottomFace = theFeature.firstShape();  
+  if (!aBottomFace->isNull()) {
+       if (aSubShapes->isBound(aBottomFace)) {  
+               aBottomFace = aSubShapes->find(aBottomFace);            
+    }    
+    theResultBody->generated(aBottomFace, _FIRST_TAG);
+  }
+
+
+
+  //Insert top face
+  std::shared_ptr<GeomAPI_Shape> aTopFace = theFeature.lastShape();
+  if (!aTopFace->isNull()) {
+    if (aSubShapes->isBound(aTopFace)) {        
+      aTopFace = aSubShapes->find(aTopFace);   
+    }
+    theResultBody->generated(aTopFace, _LAST_TAG);
+  }
+
+*/
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.h b/src/FeaturesPlugin/FeaturesPlugin_Placement.h
new file mode 100644 (file)
index 0000000..a98793e
--- /dev/null
@@ -0,0 +1,60 @@
+// File:        FeaturesPlugin_Placement.h
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef FeaturesPlugin_Placement_H_
+#define FeaturesPlugin_Placement_H_
+
+#include "FeaturesPlugin.h"
+#include <ModelAPI_Feature.h>
+#include <GeomAlgoAPI_Placement.h>
+
+class ModelAPI_ResultBody;
+class GeomAPI_Shape;
+
+class FeaturesPlugin_Placement : public ModelAPI_Feature
+{
+ public:
+  /// Placement kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_PLACEMENT_ID("Placement");
+    return MY_PLACEMENT_ID;
+  }
+  /// attribute name of referenced face
+  inline static const std::string& BASE_FACE_ID()
+  {
+    static const std::string MY_BASE_FACE_ID("placement_base_face");
+    return MY_BASE_FACE_ID;
+  }
+  /// attribute name of attractable face
+  inline static const std::string& ATTRACT_FACE_ID()
+  {
+    static const std::string MY_ATTRACT_FACE_ID("placement_attractable_face");
+    return MY_ATTRACT_FACE_ID;
+  }
+
+  /// Returns the kind of a feature
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Placement::ID();
+    return MY_KIND;
+  }
+
+  /// Creates a new part document if needed
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation
+  FeaturesPlugin_Placement();
+private:
+  /// Load Naming data structure of the feature to the document
+  void LoadNamingDS(GeomAlgoAPI_Placement& theFeature,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBasis,
+                    std::shared_ptr<GeomAPI_Shape> theContext);
+};
+
+#endif
index 749941fcab783ebcd4276b2d6a8bbaf92716d729..3c2dcc0d3a02fcc49301775112602de7f35168de 100644 (file)
@@ -7,6 +7,9 @@
       <feature id="Boolean" title="Boolean" tooltip="Perform boolean operations with shapes" icon=":icons/cut.png">
           <source path="boolean_widget.xml"/>
       </feature>
+      <feature id="Placement" title="Placement" tooltip="Perform moving an object to specified position" icon="">
+<!--          <source path="extrusion_widget.xml"/>-->
+      </feature>
     </group>
     <group id="Collections">
       <feature id="Group"
index 2718fa98007c81bd5db0b61caf66488bbcedebf1..51261f34377f6a8c1941742312794140dcb5722b 100644 (file)
@@ -19,6 +19,7 @@ SET(PROJECT_HEADERS
     GeomAPI_Pln.h
     GeomAPI_Shape.h
     GeomAPI_Edge.h
+    GeomAPI_Face.h
     GeomAPI_PlanarEdges.h
     GeomAPI_AISObject.h
     GeomAPI_IPresentable.h
@@ -41,6 +42,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Pln.cpp
     GeomAPI_Shape.cpp
     GeomAPI_Edge.cpp
+    GeomAPI_Face.cpp
     GeomAPI_PlanarEdges.cpp
     GeomAPI_AISObject.cpp
     GeomAPI_Curve.cpp
index 5e455f9f3dd3f3bd426fa0f85999859c4bac463f..cdd471f4009b6d8ce46e2bb99c58cd1beb7a1151 100644 (file)
@@ -129,4 +129,4 @@ bool GeomAPI_Edge::isEqual(std::shared_ptr<GeomAPI_Shape> theEdge)
     return false;
 
   return true;
-}
\ No newline at end of file
+}
diff --git a/src/GeomAPI/GeomAPI_Face.cpp b/src/GeomAPI/GeomAPI_Face.cpp
new file mode 100644 (file)
index 0000000..a455a0a
--- /dev/null
@@ -0,0 +1,95 @@
+// File:        GeomAPI_Face.cpp
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Face.h>
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAPI_Pnt.h>
+
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Plane.hxx>
+
+GeomAPI_Face::GeomAPI_Face()
+  : GeomAPI_Shape()
+{
+}
+
+GeomAPI_Face::GeomAPI_Face(const std::shared_ptr<GeomAPI_Shape>& theShape)
+{
+  if (!theShape->isNull() && theShape->isFace()) {
+    setImpl(new TopoDS_Shape(theShape->impl<TopoDS_Shape>()));
+  }
+}
+
+bool GeomAPI_Face::isEqual(std::shared_ptr<GeomAPI_Shape> theFace) const
+{
+  if (!theFace->isFace())
+    return false;
+
+  const TopoDS_Shape& aMyShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aInShape = theFace->impl<TopoDS_Shape>();
+
+  Handle(Geom_Surface) aMySurf = BRep_Tool::Surface(TopoDS::Face(aMyShape));
+  Handle(Geom_Surface) aInSurf = BRep_Tool::Surface(TopoDS::Face(aInShape));
+
+  // Check that surfaces a the same type
+  if (aMySurf->DynamicType() != aInSurf->DynamicType())
+    return false;
+
+  // Get parameters of surfaces
+  double aMyUMin, aMyUMax, aMyVMin, aMyVMax;
+  aMySurf->Bounds(aMyUMin, aMyUMax, aMyVMin, aMyVMax);
+  double aInUMin, aInUMax, aInVMin, aInVMax;
+  aInSurf->Bounds(aInUMin, aInUMax, aInVMin, aInVMax);
+
+  // Check that parameters are the same
+  if (fabs(aMyUMin - aInUMin) > Precision::PConfusion() ||
+      fabs(aMyUMax - aInUMax) > Precision::PConfusion() ||
+      fabs(aMyVMin - aInVMin) > Precision::PConfusion() ||
+      fabs(aMyVMax - aInVMax) > Precision::PConfusion())
+    return false;
+
+  return true;
+}
+
+bool GeomAPI_Face::isPlanar() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+  if (aSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+    return true;
+  return false;
+}
+
+std::shared_ptr<GeomAPI_Pln> GeomAPI_Face::getPlane() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+
+  if (!aSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+    return std::shared_ptr<GeomAPI_Pln>();
+
+  // Obtain central point
+  double aUMin, aUMax, aVMin, aVMax;
+  aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
+  gp_Pnt aCentralPnt;
+  gp_Vec aDU, aDV;
+  aSurf->D1((aUMin+aUMax)*0.5, (aVMin+aVMax)*0.5, aCentralPnt, aDU, aDV);
+  std::shared_ptr<GeomAPI_Pnt> aCenter(
+      new GeomAPI_Pnt(aCentralPnt.X(), aCentralPnt.Y(), aCentralPnt.Z()));
+
+  // Obtain plane direction
+  gp_XYZ aNormalVec = aDU.XYZ().Crossed(aDV.XYZ());
+  if (aNormalVec.SquareModulus() < Precision::Confusion() * Precision::Confusion())
+    return std::shared_ptr<GeomAPI_Pln>();
+  std::shared_ptr<GeomAPI_Dir> aNormal(
+      new GeomAPI_Dir(aNormalVec.X(), aNormalVec.Y(), aNormalVec.Z()));
+
+  std::shared_ptr<GeomAPI_Pln> aResult(new GeomAPI_Pln(aCenter, aNormal));
+  return aResult;
+}
diff --git a/src/GeomAPI/GeomAPI_Face.h b/src/GeomAPI/GeomAPI_Face.h
new file mode 100644 (file)
index 0000000..c070bf2
--- /dev/null
@@ -0,0 +1,36 @@
+// File:        GeomAPI_Face.h
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Face_H_
+#define GeomAPI_Face_H_
+
+#include <GeomAPI_Shape.h>
+
+class GeomAPI_Pln;
+
+/**\class GeomAPI_Face
+* \ingroup DataModel
+ * \brief Interface to the face object
+ */
+class GEOMAPI_EXPORT GeomAPI_Face : public GeomAPI_Shape
+{
+public:
+  /// Creation of empty (null) shape
+  GeomAPI_Face();
+
+  /// Creation of face by the face-shape
+  GeomAPI_Face(const std::shared_ptr<GeomAPI_Shape>& theShape);
+
+  /// Returns true if the current face is geometrically equal to the given face
+  virtual bool isEqual(const std::shared_ptr<GeomAPI_Shape> theFace) const;
+
+  /// Returns true if the face is a planar face
+  bool isPlanar() const;
+
+  /// Returns the base plane of the face (if it is planar) with location in the center of the face
+  std::shared_ptr<GeomAPI_Pln> getPlane() const;
+};
+
+#endif
+
index 5b9694ccce509b77e915aa2724636c138045c8c0..f656eb2bea907a9237cd740a6c995f73510c04ce 100644 (file)
@@ -39,3 +39,9 @@ bool GeomAPI_Shape::isEdge() const
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
   return aShape.ShapeType() == TopAbs_EDGE;
 }
+
+bool GeomAPI_Shape::isFace() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  return aShape.ShapeType() == TopAbs_FACE;
+}
index c55d9ab314d3b5cff5e5ce8a9228de60c652eb7b..e72c4bc90eda020f2fbbdb335eb86db8b97969e7 100644 (file)
@@ -30,6 +30,9 @@ class GEOMAPI_EXPORT GeomAPI_Shape : public GeomAPI_Interface
   /// Returns whether the shape is an edge
   virtual bool isEdge() const;
 
+  /// Returns whether the shape is a face
+  virtual bool isFace() const;
+
 };
 
 //! Pointer on list of shapes
index 5656a0ad8a5e0227eaa10d12050708099e3a7f12..8f5a4007c3be6049e10606ef2484aff95cf9745e 100644 (file)
@@ -14,6 +14,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Boolean.h
     GeomAlgoAPI_MakeShape.h
     GeomAlgoAPI_DFLoader.h
+    GeomAlgoAPI_Placement.h
 )
 
 SET(PROJECT_SOURCES
@@ -26,6 +27,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Boolean.cpp
     GeomAlgoAPI_MakeShape.cpp
     GeomAlgoAPI_DFLoader.cpp
+    GeomAlgoAPI_Placement.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp
new file mode 100644 (file)
index 0000000..b8718f9
--- /dev/null
@@ -0,0 +1,118 @@
+// File:        GeomAlgoAPI_Placement.cpp
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#include <GeomAlgoAPI_Placement.h>
+#include <GeomAlgoAPI_DFLoader.h>
+
+#include <GeomAPI_Pnt.h>
+
+#include <BRepBuilderAPI_Transform.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Quaternion.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+#include <Precision.hxx>
+
+
+GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
+    std::shared_ptr<GeomAPI_Shape> theAttractiveFace,
+    std::shared_ptr<GeomAPI_Pln> theSourcePlane,
+    std::shared_ptr<GeomAPI_Pln> theDestPlane)
+  : myDone(false),
+    myShape(new GeomAPI_Shape())
+{
+  build(theAttractiveFace, theSourcePlane, theDestPlane);
+}
+
+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)
+{
+  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();
+
+  // Calculate transformation
+  gp_Trsf aTrsf;
+  gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z());
+  gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z());
+  gp_Quaternion aRot(aSrcDir, aDstDir);
+  gp_Vec aTrans(aDestLoc->x() - aSourceLoc->x(),
+                aDestLoc->y() - aSourceLoc->y(),
+                aDestLoc->z() - aSourceLoc->z());
+  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);
+  if(aBuilder) {
+    setImpl(aBuilder);
+    myDone = aBuilder->IsDone() == Standard_True;
+    if (myDone) {
+      TopoDS_Shape aResult;
+      if(aBuilder->Shape().ShapeType() == TopAbs_COMPOUND) 
+        aResult = GeomAlgoAPI_DFLoader::refineResult(aBuilder->Shape());
+      else
+        aResult = aBuilder->Shape();
+      // fill data map to keep correct orientation of sub-shapes 
+      for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
+        std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+        aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
+        myMap.bind(aCurrentShape, aCurrentShape);
+      }   
+      myShape->setImpl(new TopoDS_Shape(aResult));
+      myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
+    }
+  }
+}
+
+//============================================================================
+const bool GeomAlgoAPI_Placement::isValid() const
+{
+  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+  return (aChecker.IsValid() == Standard_True);
+}
+
+//============================================================================
+const bool GeomAlgoAPI_Placement::hasVolume() const
+{
+  bool hasVolume(false);
+  if(isValid()) {
+    const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
+    GProp_GProps aGProp;
+    BRepGProp::VolumeProperties(aRShape, aGProp);
+    if(aGProp.Mass() > Precision::Confusion()) 
+      hasVolume = true;        
+  }
+  return hasVolume;
+}
+
+//============================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Placement::shape () const 
+{
+  return myShape;
+}
+
+//============================================================================
+void GeomAlgoAPI_Placement::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
+{
+  theMap = myMap;
+}
+
+//============================================================================
+GeomAlgoAPI_MakeShape * GeomAlgoAPI_Placement::makeShape() const
+{
+  return myMkShape;
+}
+
+//============================================================================
+GeomAlgoAPI_Placement::~GeomAlgoAPI_Placement()
+{
+  if (myImpl)
+    myMap.clear();
+}
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h
new file mode 100644 (file)
index 0000000..09c9e34
--- /dev/null
@@ -0,0 +1,68 @@
+// File:        GeomAlgoAPI_Placement.h
+// Created:     2 Dec 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAlgoAPI_Placement_H_
+#define GeomAlgoAPI_Placement_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <memory>
+
+/**\class GeomAlgoAPI_Placement
+ * \ingroup DataAlgo
+ * \brief Creates the copied object which face is placed on the given plane
+ */
+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
+   */
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr<GeomAPI_Shape> theAttractiveShape,
+                                           std::shared_ptr<GeomAPI_Pln> theSourcePlane,
+                                           std::shared_ptr<GeomAPI_Pln> theDestPlane);
+
+  /// Returns True if algorithm succeed
+  GEOMALGOAPI_EXPORT const bool isDone() const
+  { return myDone; }
+
+  ///  Returns True if resulting shape is valid
+  GEOMALGOAPI_EXPORT const bool isValid() const;
+
+  /// Returns True if resulting shape has volume
+  GEOMALGOAPI_EXPORT const bool hasVolume() const;
+
+  /// Returns result of the Placement algorithm which may be a Solid or a Face
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape () const;
+
+  /// Returns map of sub-shapes of the result. To be used for History keeping
+  GEOMALGOAPI_EXPORT void  mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const;
+
+  /// Return interface for for History processing
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape () const;
+
+  /// Destructor
+  GEOMALGOAPI_EXPORT virtual ~GeomAlgoAPI_Placement();
+
+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);
+
+  /// fields
+  bool myDone;
+  std::shared_ptr<GeomAPI_Shape> myShape;
+  GeomAPI_DataMapOfShapeShape myMap;
+  GeomAlgoAPI_MakeShape * myMkShape;
+};
+
+#endif