]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Feature #524: 4.01. Revolution feature (not complete!)
authordbv <dbv@opencascade.com>
Wed, 13 May 2015 12:53:56 +0000 (15:53 +0300)
committerdbv <dbv@opencascade.com>
Tue, 26 May 2015 11:14:48 +0000 (14:14 +0300)
Added new feature Revolution;
Added algorithm for Rotation;
Added new class GeomAPI_Ax1;
Added new method to GeomAlgoAPI_ShapeProps::centreOfMass;
Added new validator GeomValidators_ZeroOffset (actually it is useful only for Extrusion and Revolution features);
Some fixes to GeomAlgoAPI_Prism;

27 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Revolution.h [new file with mode: 0644]
src/FeaturesPlugin/extrusion_widget.xml
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/revolution_widget.xml [new file with mode: 0644]
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI_Ax1.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Ax1.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Face.cpp
src/GeomAPI/GeomAPI_Pln.cpp
src/GeomAPI/GeomAPI_Pln.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Prism.h
src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Revolution.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h
src/GeomValidators/CMakeLists.txt
src/GeomValidators/GeomValidators_ZeroOffset.cpp [new file with mode: 0644]
src/GeomValidators/GeomValidators_ZeroOffset.h [new file with mode: 0644]
src/Model/Model_AttributeSelection.cpp
src/PartSet/PartSet_Module.cpp

index dfce818692f42196c7178c22cd9bb557108a545f..6bd7dcd403cf35baf3c01587efe2831f1a07ddc0 100644 (file)
@@ -7,6 +7,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin.h
     FeaturesPlugin_Plugin.h
     FeaturesPlugin_Extrusion.h
+    FeaturesPlugin_Revolution.h
     FeaturesPlugin_Boolean.h
     FeaturesPlugin_Group.h
     FeaturesPlugin_Placement.h
@@ -15,6 +16,7 @@ SET(PROJECT_HEADERS
 SET(PROJECT_SOURCES
     FeaturesPlugin_Plugin.cpp
     FeaturesPlugin_Extrusion.cpp
+    FeaturesPlugin_Revolution.cpp
     FeaturesPlugin_Boolean.cpp
     FeaturesPlugin_Group.cpp
     FeaturesPlugin_Placement.cpp
@@ -23,6 +25,7 @@ SET(PROJECT_SOURCES
 SET(XML_RESOURCES
   plugin-Features.xml
   extrusion_widget.xml
+  revolution_widget.xml
   boolean_widget.xml
   group_widget.xml
   placement_widget.xml
index 7dd5081f47508f8292823cdbe610a001b27d7694..c35243e8d9d2c25a68808428ac32d808b28764d4 100644 (file)
@@ -6,6 +6,7 @@
 #include <FeaturesPlugin_Extrusion.h>
 #include <FeaturesPlugin_Group.h>
 #include <FeaturesPlugin_Placement.h>
+#include <FeaturesPlugin_Revolution.h>
 
 #include <ModelAPI_Session.h>
 
@@ -28,6 +29,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
 {
   if (theFeatureID == FeaturesPlugin_Extrusion::ID()) {
     return FeaturePtr(new FeaturesPlugin_Extrusion);
+  } else if (theFeatureID == FeaturesPlugin_Revolution::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Revolution);
   } else if (theFeatureID == FeaturesPlugin_Boolean::ID()) {
     return FeaturePtr(new FeaturesPlugin_Boolean);
   } else if (theFeatureID == FeaturesPlugin_Group::ID()) {
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp b/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp
new file mode 100644 (file)
index 0000000..304d374
--- /dev/null
@@ -0,0 +1,197 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Revolution.cpp
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#include <FeaturesPlugin_Revolution.h>
+
+#include <GeomAlgoAPI_FaceBuilder.h>
+#include <GeomAlgoAPI_Rotation.h>
+#include <GeomAPI_Ax3.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAPI_XYZ.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+
+#define _LATERAL_TAG 1
+#define _FIRST_TAG 2
+#define _LAST_TAG 3
+#define EDGE 6
+
+//=================================================================================================
+FeaturesPlugin_Revolution::FeaturesPlugin_Revolution()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Revolution::initAttributes()
+{
+  AttributeSelectionListPtr aSelection = 
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+    FeaturesPlugin_Revolution::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+  // revolution works with faces always
+  aSelection->setSelectionType("FACE");
+
+  data()->addAttribute(FeaturesPlugin_Revolution::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Revolution::FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FeaturesPlugin_Revolution::FROM_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
+
+  data()->addAttribute(FeaturesPlugin_Revolution::TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(FeaturesPlugin_Revolution::TO_ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
+
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FeaturesPlugin_Revolution::FROM_OBJECT_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FeaturesPlugin_Revolution::TO_OBJECT_ID());
+}
+
+//=================================================================================================
+void FeaturesPlugin_Revolution::execute()
+{
+  AttributeSelectionListPtr aFaceRefs = selectionList(FeaturesPlugin_Revolution::LIST_ID());
+
+  //Getting axe.
+  std::shared_ptr<GeomAPI_Ax1> anAxis;
+  std::shared_ptr<GeomAPI_Edge> anEdge;
+  std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(FeaturesPlugin_Revolution::AXIS_OBJECT_ID());
+  if(anObjRef && anObjRef->value()->isEdge()) {
+    anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
+  }
+  if(anEdge) {
+    anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(), anEdge->line()->direction()));
+  }
+
+  // Getting bounding planes.
+  std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape());
+  std::shared_ptr<GeomAPI_Shape> aToShape(new GeomAPI_Shape());
+
+  anObjRef = selection(FeaturesPlugin_Revolution::FROM_OBJECT_ID());
+  if(anObjRef) {
+    aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
+  }
+  anObjRef = selection(FeaturesPlugin_Revolution::TO_OBJECT_ID());
+  if(anObjRef) {
+    aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
+  }
+
+  // Getting angles.
+  double aFromAngle = real(FeaturesPlugin_Revolution::FROM_ANGLE_ID())->value();
+  double aToAngle = real(FeaturesPlugin_Revolution::TO_ANGLE_ID())->value();
+
+  // for each selected face generate a result
+  int anIndex = 0, aResultIndex = 0;
+  for(; anIndex < aFaceRefs->size(); anIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = aFaceRefs->value(anIndex);
+    ResultPtr aContextRes = aFaceRef->context();
+    std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
+    if (!aContext.get()) {
+      static const std::string aContextError = "The selection context is bad";
+      setError(aContextError);
+      break;
+    }
+
+    std::shared_ptr<GeomAPI_Shape> aValueFace = aFaceRef->value();
+    int aFacesNum = -1; // this mean that "aFace" is used
+    ResultConstructionPtr aConstruction =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes);
+    if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces
+      if (aConstruction.get()) {
+        aFacesNum = aConstruction->facesNum();
+      } else {
+        static const std::string aFaceError = "Can not find basis for extrusion";
+        setError(aFaceError);
+        break;
+      }
+    }
+
+    for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      std::shared_ptr<GeomAPI_Shape> aBaseShape;
+      if (aFacesNum == -1) {
+        aBaseShape = aValueFace;
+      } else {
+        aBaseShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+      }
+
+      GeomAlgoAPI_Revolution aFeature(aBaseShape, anAxis, aFromShape, aFromAngle, aToShape, aToAngle);
+      if(!aFeature.isDone()) {
+        static const std::string aFeatureError = "Revolution algorithm failed";
+        setError(aFeatureError);
+        break;
+      }
+
+      // Check if shape is valid
+      if(aFeature.shape()->isNull()) {
+        static const std::string aShapeError = "Resulting shape is Null";
+        setError(aShapeError);
+        break;
+      }
+      if(!aFeature.isValid()) {
+        std::string aFeatureError = "Warning: resulting shape is not valid";
+        setError(aFeatureError);
+        break;
+      }
+      //LoadNamingDS
+      LoadNamingDS(aFeature, aResultBody, aBaseShape, aContext);
+
+      setResult(aResultBody, aResultIndex);
+      aResultIndex++;
+
+      if (aFacesNum == -1)
+        break;
+    }
+  }
+  // remove the rest results if there were produced in the previous pass
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Revolution::LoadNamingDS(GeomAlgoAPI_Revolution& theFeature,
+                                             std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                             std::shared_ptr<GeomAPI_Shape> theBasis,
+                                             std::shared_ptr<GeomAPI_Shape> theContext)
+{
+  //TODO: Fix naming
+  theResultBody->store(theFeature.shape());
+  return;
+
+  //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
+  std::string aLatName = "LateralFace";
+  theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape(), theBasis, EDGE,_LATERAL_TAG, aLatName, *aSubShapes);
+
+  ////Insert first face
+  //std::string aBotName = "FirstFace";
+  //std::shared_ptr<GeomAPI_Shape> aBottomFace = theFeature.firstShape();
+  //if(!aBottomFace->isNull()) {
+  //  if(aSubShapes->isBound(aBottomFace)) {
+  //    aBottomFace = aSubShapes->find(aBottomFace);
+  //  }
+  //  theResultBody->generated(aBottomFace, aBotName, _FIRST_TAG);
+  //}
+
+  ////Insert last face
+  //std::string aTopName = "LastFace";
+  //std::shared_ptr<GeomAPI_Shape> aTopFace = theFeature.lastShape();
+  //if (!aTopFace->isNull()) {
+  //  if (aSubShapes->isBound(aTopFace)) {
+  //    aTopFace = aSubShapes->find(aTopFace);
+  //  }
+  //  theResultBody->generated(aTopFace, aTopName, _LAST_TAG);
+  //}
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Revolution.h b/src/FeaturesPlugin/FeaturesPlugin_Revolution.h
new file mode 100644 (file)
index 0000000..ffb7ae2
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        FeaturesPlugin_Revolution.h
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef FeaturesPlugin_Revolution_H_
+#define FeaturesPlugin_Revolution_H_
+
+#include <FeaturesPlugin.h>
+
+#include <GeomAlgoAPI_Revolution.h>
+#include <ModelAPI_Feature.h>
+
+class GeomAPI_Shape;
+class ModelAPI_ResultBody;
+
+/** \class FeaturesPlugin_Revolution
+ *  \ingroup Plugins
+ *  \brief Feature for creation of revolution from the planar face.
+ *  Revolution creates the lateral faces based on edges of the base face and
+ *  the start and end faces and/or start and end angles.
+ */
+class FeaturesPlugin_Revolution : public ModelAPI_Feature
+{
+ public:
+  /// Revolution kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_REVOLUTION_ID("Revolution");
+    return MY_REVOLUTION_ID;
+  }
+
+  /// Attribute name of references sketch entities list, it should contain a sketch result or
+  /// a pair a sketch result to sketch face.
+  inline static const std::string& LIST_ID()
+  {
+    static const std::string MY_GROUP_LIST_ID("base");
+    return MY_GROUP_LIST_ID;
+  }
+
+  /// Attribute name of an object to which the extrusion grows.
+  inline static const std::string& AXIS_OBJECT_ID()
+  {
+    static const std::string MY_TO_OBJECT_ID("axis_object");
+    return MY_TO_OBJECT_ID;
+  }
+
+  /// Attribute name of revolution angle.
+  inline static const std::string& TO_ANGLE_ID()
+  {
+    static const std::string MY_TO_ANGLE_ID("to_angle");
+    return MY_TO_ANGLE_ID;
+  }
+
+  /// Attribute name of revolution angle.
+  inline static const std::string& FROM_ANGLE_ID()
+  {
+    static const std::string MY_FROM_ANGLE_ID("from_angle");
+    return MY_FROM_ANGLE_ID;
+  }
+
+  /// Attribute name of an object to which the revolution grows.
+  inline static const std::string& TO_OBJECT_ID()
+  {
+    static const std::string MY_TO_OBJECT_ID("to_object");
+    return MY_TO_OBJECT_ID;
+  }
+
+  /// Attribute name of tool object.
+  inline static const std::string& FROM_OBJECT_ID()
+  {
+    static const std::string MY_FROM_OBJECT_ID("from_object");
+    return MY_FROM_OBJECT_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Revolution::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_Revolution();
+
+private:
+  /// Load Naming data structure of the feature to the document.
+  void LoadNamingDS(GeomAlgoAPI_Revolution& theFeature, std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBasis,
+                    std::shared_ptr<GeomAPI_Shape> theContext);
+};
+
+#endif
index 5783d542c91d650034452da3bccba393a648ea67..0160e96d596647c96868d33e2b86bc048c2e5ccf 100644 (file)
       <validator id="GeomValidators_Positive"/>
     </doublevalue>
   </groupbox>
-<!--XML definition of the revolution:-->
-<!--  <multi_selector id="base"
-    label="Select a sketch face"
-    icon=":icons/sketch.png"
-    tooltip="Select a sketch face"
-    type_choice="Faces">
-    <validator id="PartSet_SketchEntityValidator" parameters="Sketch"/>
-  </multi_selector>
-  <shape_selector id="axis_object"
-                  icon=":icons/axis.png"
-                  label="Plane face"
-                  tooltip="Select a planar face"
-                  shape_types="edge">
-  </shape_selector>
-  <groupbox title="From">
-    <shape_selector id="from_object"
-                    icon=":icons/plane.png"
-                    label="Plane face"
-                    tooltip="Select a planar face"
-                    shape_types="face">
-      <validator id="GeomValidators_Face" parameters="plane"/>
-    </shape_selector>
-    <doublevalue
-      id="from_size"
-      label="Size"
-      min="0"
-      step="1.0"
-      default="0"
-      icon=":icons/angle_down.png"
-      tooltip="Height">
-      <validator id="GeomValidators_Positive"/>
-    </doublevalue>
-  </groupbox>
-  <groupbox title="To">
-    <shape_selector id="to_object"
-                    icon=":icons/plane_inverted.png"
-                    label="Plane face"
-                    tooltip="Select a planar face"
-                    shape_types="face">
-      <validator id="GeomValidators_Face" parameters="plane"/>
-    </shape_selector>
-    <doublevalue
-      id="to_size"
-      label="Size"
-      min="0"
-      step="1.0"
-      default="10"
-      icon=":icons/angle_up.png"
-      tooltip="Height">
-      <validator id="GeomValidators_Positive"/>
-    </doublevalue>
-  </groupbox>-->
+  <validator id="GeomValidators_ZeroOffset" parameters="from_object,to_object,from_size,to_size"/>
 </source>
index 7790b2839c59f761a4b5a03a80aaf4d32444eaa4..288ae115b13ca606470c8ad0254a43099eeaa167 100644 (file)
@@ -6,6 +6,9 @@
       <feature id="Extrusion" title="Extrusion" tooltip="Create a solid by extrusion of a face" icon=":icons/extrusion.png">
           <source path="extrusion_widget.xml"/>
       </feature>
+      <feature id="Revolution" title="Revolution" tooltip="Create a solid by revolution of a face" icon=":icons/revol.png">
+          <source path="revolution_widget.xml"/>
+      </feature>
       <feature id="Boolean" title="Boolean" tooltip="Perform boolean operations with solids" icon=":icons/cut.png">
           <source path="boolean_widget.xml"/>
       </feature>
diff --git a/src/FeaturesPlugin/revolution_widget.xml b/src/FeaturesPlugin/revolution_widget.xml
new file mode 100644 (file)
index 0000000..55514d3
--- /dev/null
@@ -0,0 +1,60 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="base"
+    label="Select a sketch face"
+    icon=":icons/sketch.png"
+    tooltip="Select a sketch face"
+    type_choice="Faces">
+    <validator id="PartSet_SketchEntityValidator" parameters="Sketch"/>
+  </multi_selector>
+  <shape_selector id="axis_object"
+                  icon=":icons/axis.png"
+                  label="Axis"
+                  tooltip="Select an edge for axis"
+                  shape_types="edge"
+                  default="">
+    <validator id="GeomValidators_ShapeType" parameters="line"/>
+  </shape_selector>
+  <groupbox title="From">
+    <shape_selector id="from_object"
+                    icon=":icons/plane.png"
+                    label="Plane face"
+                    tooltip="Select a planar face"
+                    shape_types="face"
+                    default="&lt;sketch&gt;">
+      <validator id="GeomValidators_Face" parameters="plane"/>
+    </shape_selector>
+    <doublevalue
+      id="from_angle"
+      label="Angle"
+      min="0"
+      step="1.0"
+      default="0"
+      icon=":icons/angle_down.png"
+      tooltip="Angle">
+      <validator id="GeomValidators_Positive"/>
+    </doublevalue>
+  </groupbox>
+  <groupbox title="To">
+    <shape_selector id="to_object"
+                    icon=":icons/plane_inverted.png"
+                    label="Plane face"
+                    tooltip="Select a planar face"
+                    shape_types="face"
+                    default="&lt;sketch&gt;">
+      <validator id="GeomValidators_Face" parameters="plane"/>
+    </shape_selector>
+    <doublevalue
+      id="to_angle"
+      label="Angle"
+      min="0"
+      step="1.0"
+      default="10"
+      icon=":icons/angle_up.png"
+      tooltip="Angle">
+      <validator id="GeomValidators_Positive"/>
+    </doublevalue>
+  </groupbox>
+  <validator id="GeomValidators_ZeroOffset" parameters="from_object,to_object,from_angle,to_angle"/>
+</source>
\ No newline at end of file
index e1726ca506616a4d427fcf096c58dc212fc1c1db..2be8c4af2878681beba9791bc57114831a19e2d8 100644 (file)
@@ -29,7 +29,8 @@ SET(PROJECT_HEADERS
     GeomAPI_DataMapOfShapeShape.h
     GeomAPI_ICustomPrs.h
     GeomAPI_Vertex.h
-       GeomAPI_Ax3.h
+    GeomAPI_Ax1.h
+    GeomAPI_Ax3.h
 )
 
 SET(PROJECT_SOURCES
@@ -54,7 +55,8 @@ SET(PROJECT_SOURCES
     GeomAPI_DataMapOfShapeShape.cpp
     GeomAPI_Vertex.cpp
     GeomAPI_ICustomPrs.cpp
-       GeomAPI_Ax3.cpp
+    GeomAPI_Ax1.cpp
+    GeomAPI_Ax3.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomAPI/GeomAPI_Ax1.cpp b/src/GeomAPI/GeomAPI_Ax1.cpp
new file mode 100644 (file)
index 0000000..dcf5a98
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Ax1.cpp
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAPI_Ax1.h>
+
+#include <gp_Ax1.hxx>
+
+#define MY_AX1 static_cast<gp_Ax1*>(myImpl)
+
+//=================================================================================================
+GeomAPI_Ax1::GeomAPI_Ax1()
+: GeomAPI_Interface(new gp_Ax1())
+{
+}
+
+//=================================================================================================
+GeomAPI_Ax1::GeomAPI_Ax1(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+                         std::shared_ptr<GeomAPI_Dir> theDir)
+: GeomAPI_Interface(new gp_Ax1(theOrigin->impl<gp_Pnt>(),
+                               theDir->impl<gp_Dir>()))
+{
+}
+
+//=================================================================================================
+void GeomAPI_Ax1::setOrigin(const std::shared_ptr<GeomAPI_Pnt>& theOrigin)
+{
+  MY_AX1->SetLocation(theOrigin->impl<gp_Pnt>());
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Pnt> GeomAPI_Ax1::origin() const
+{
+  gp_Pnt aPnt = MY_AX1->Location();
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(),aPnt.Y(),aPnt.Z()));
+}
+
+//=================================================================================================
+void GeomAPI_Ax1::setDir(const std::shared_ptr<GeomAPI_Dir>& theDir)
+{
+  MY_AX1->SetDirection(theDir->impl<gp_Dir>());
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Dir> GeomAPI_Ax1::dir() const
+{
+  gp_Dir aDir = MY_AX1->Direction();
+  return std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
+}
+
+//=================================================================================================
+void GeomAPI_Ax1::reverse()
+{
+  MY_AX1->Reverse();
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Ax1> GeomAPI_Ax1::reversed()
+{
+  gp_Ax1 anAxis = MY_AX1->Reversed();
+  std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(anAxis.Location().X(), anAxis.Location().Y(), anAxis.Location().Z()));
+  std::shared_ptr<GeomAPI_Dir> aDir(new GeomAPI_Dir(anAxis.Direction().X(), anAxis.Direction().Y(), anAxis.Direction().Z()));
+  return std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(aPnt, aDir));
+}
\ No newline at end of file
diff --git a/src/GeomAPI/GeomAPI_Ax1.h b/src/GeomAPI/GeomAPI_Ax1.h
new file mode 100644 (file)
index 0000000..d65d8e8
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Ax1.h
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GEOMAPI_AX1_H_
+#define GEOMAPI_AX1_H_
+
+#include <GeomAPI.h>
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+
+/** \ingroup DataModel
+ *  \brief The class represents an axis in 3D space.
+ */
+class GEOMAPI_EXPORT GeomAPI_Ax1 : public GeomAPI_Interface
+{
+public:
+  /// Default constructor.
+  GeomAPI_Ax1();
+
+  /** \brief Ñonstructor.
+  *   \param[in] theOrigin point of origin.
+  *   \param[in] theDir direction of axis.
+  */
+  GeomAPI_Ax1(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+              std::shared_ptr<GeomAPI_Dir> theDir);
+
+  /// Sets origin point.
+  void setOrigin(const std::shared_ptr<GeomAPI_Pnt>& theOrigin);
+
+  /// \return the plane origin point.
+  std::shared_ptr<GeomAPI_Pnt> origin() const;
+
+  /// Sets direction vector.
+  void setDir(const std::shared_ptr<GeomAPI_Dir>& theDir);
+
+  /// \return direction vector.
+  std::shared_ptr<GeomAPI_Dir> dir() const;
+
+  /// Reverses the unit vector of this axis and assigns the result to this axis.
+  void reverse();
+
+  /// \return reversed unit vector of this axis.
+  std::shared_ptr<GeomAPI_Ax1> reversed();
+};
+
+#endif
index b9dbd45df2f45bf8127e0b0d8f18a20ff43d9dfa..b569598357b982526ca0221c1332289ac200bbfb 100644 (file)
@@ -66,7 +66,7 @@ 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));
   GeomLib_IsPlanarSurface isPlanar(aSurf);
-  return isPlanar.IsPlanar();
+  return isPlanar.IsPlanar() == Standard_True;
 }
 
 std::shared_ptr<GeomAPI_Pln> GeomAPI_Face::getPlane() const
index 81c5bbc2e18726f8f4fdb501ba669c556fb59eeb..4947170e9358aaef1dbb5996fbe5439318b60ea0 100644 (file)
@@ -5,6 +5,7 @@
 // Author:      Mikhail PONIKAROV
 
 #include<GeomAPI_Pln.h>
+#include <GeomAPI_Ax3.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Dir.h>
 
 
 using namespace std;
 
+GeomAPI_Pln::GeomAPI_Pln(const std::shared_ptr<GeomAPI_Ax3>& theAxis)
+: GeomAPI_Interface(new gp_Ax3(theAxis->impl<gp_Ax3>()))
+{
+}
+
 GeomAPI_Pln::GeomAPI_Pln(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
                          const std::shared_ptr<GeomAPI_Dir>& theNormal)
     : GeomAPI_Interface(new gp_Pln(thePoint->impl<gp_Pnt>(), theNormal->impl<gp_Dir>()))
index 8bd9668e7dc407e0020f27bfa8943f4bc106f187..8d9b6e5c156c96fcd30ec41dc9efb0e151943dbf 100644 (file)
@@ -10,6 +10,7 @@
 #include <memory>
 #include <GeomAPI_Interface.h>
 
+class GeomAPI_Ax3;
 class GeomAPI_Pnt;
 class GeomAPI_Dir;
 
@@ -21,6 +22,9 @@ class GeomAPI_Dir;
 class GEOMAPI_EXPORT GeomAPI_Pln : public GeomAPI_Interface
 {
  public:
+  /// Creation of plane by the axis placement
+  GeomAPI_Pln(const std::shared_ptr<GeomAPI_Ax3>& theAxis);
+
   /// Creation of plane by the point and normal
   GeomAPI_Pln(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
               const std::shared_ptr<GeomAPI_Dir>& theNormal);
index 83a668987dc3824de0e2c3674b65aa1ae50a2814..3a5b04d2f061409fbe38289985dc8c2b89f6117c 100644 (file)
@@ -15,7 +15,9 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_SketchBuilder.h
     GeomAlgoAPI_Extrusion.h
     GeomAlgoAPI_Prism.h
+    GeomAlgoAPI_Revolution.h
     GeomAlgoAPI_Boolean.h
+    GeomAlgoAPI_Rotation.h
     GeomAlgoAPI_MakeShape.h
     GeomAlgoAPI_ShapeProps.h
     GeomAlgoAPI_DFLoader.h
@@ -37,7 +39,9 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_SketchBuilder.cpp
     GeomAlgoAPI_Extrusion.cpp
     GeomAlgoAPI_Prism.cpp
+    GeomAlgoAPI_Revolution.cpp
     GeomAlgoAPI_Boolean.cpp
+    GeomAlgoAPI_Rotation.cpp
     GeomAlgoAPI_MakeShape.cpp
     GeomAlgoAPI_ShapeProps.cpp
     GeomAlgoAPI_DFLoader.cpp
index f800657de8cf7db66ecdfcfa4dea331e30918c17..7d2cf323385f9b7a013cb337bb35815e330b874d 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 
-// File:        GeomAlgoAPI_Prism.h
+// File:        GeomAlgoAPI_Prism.cpp
 // Created:     5 May 2015
 // Author:      Dmitry Bobylev
 
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepFeat_MakePrism.hxx>
 #include <BRepGProp.hxx>
-#include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <gp_Cylinder.hxx>
 #include <gp_Pln.hxx>
 #include <GProp_GProps.hxx>
-#include <LocOpe_FindEdgesInFace.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 
+//=================================================================================================
 GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(std::shared_ptr<GeomAPI_Shape> theBasis,
                                      std::shared_ptr<GeomAPI_Shape> theFromShape,
                                      std::shared_ptr<GeomAPI_Shape> theToShape)
 : myFromShape(theFromShape),
   myToShape(theToShape),
+  myDone(false),
   myShape(new GeomAPI_Shape()),
   myFirst(new GeomAPI_Shape()),myLast(new GeomAPI_Shape())
 {
   build(theBasis);
 }
 
-//============================================================================
+//=================================================================================================
 void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis)
 {
+  if(!theBasis || !myFromShape || !myToShape ||
+    (myFromShape && myToShape && myFromShape->isEqual(myToShape))) {
+    return;
+  }
+
   TopoDS_Face aBasis = TopoDS::Face(theBasis->impl<TopoDS_Shape>());
-  Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(
-    BRep_Tool::Surface(aBasis));
+  Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aBasis));
   if(aPlane.IsNull()) { // non-planar shapes is not supported for extrusion yet
     return;
   }
@@ -50,20 +52,17 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis)
     setImpl(aBuilder);
     TopoDS_Shape aFromShape = myFromShape->impl<TopoDS_Shape>();
     TopoDS_Shape aToShape   = myToShape->impl<TopoDS_Shape>();
-    aBuilder->Perform(myFromShape->impl<TopoDS_Shape>(), myToShape->impl<TopoDS_Shape>());
-    myDone = aBuilder->IsDone();
-    if (myDone) {
-      TopoDS_Shape aResult;
-      if(aBuilder->Shape().ShapeType() == TopAbs_COMPOUND) {
-        aResult = GeomAlgoAPI_DFLoader::refineResult(aBuilder->Shape());
-      }
-      else {
-        aResult = aBuilder->Shape();
-      }
+    aBuilder->Perform(aFromShape, aToShape);
+    myDone = aBuilder->IsDone() == Standard_True;
+    if(myDone){
+      TopoDS_Shape aResult = aBuilder->Shape();
       TopExp_Explorer anExp(aResult, TopAbs_SOLID);
       if(!anExp.More()) {
         return;
       }
+      if(aResult.ShapeType() == TopAbs_COMPOUND) {
+        aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
+      }
       // 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());
@@ -78,20 +77,20 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis)
   }
 }
 
-//============================================================================
+//=================================================================================================
 const bool GeomAlgoAPI_Prism::isDone() const
 {
   return myDone;
 }
 
-//============================================================================
+//=================================================================================================
 const bool GeomAlgoAPI_Prism::isValid() const
 {
   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
   return (aChecker.IsValid() == Standard_True);
 }
 
-//============================================================================
+//=================================================================================================
 const bool GeomAlgoAPI_Prism::hasVolume() const
 {
   bool hasVolume(false);
@@ -105,37 +104,37 @@ const bool GeomAlgoAPI_Prism::hasVolume() const
   return hasVolume;
 }
 
-//============================================================================
+//=================================================================================================
 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Prism::shape () const
 {
   return myShape;
 }
 
-//============================================================================
+//=================================================================================================
 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Prism::firstShape()
 {
   return myFirst;
 }
 
-//============================================================================
+//=================================================================================================
 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Prism::lastShape()
 {
   return myLast;
 }
 
-//============================================================================
+//=================================================================================================
 void GeomAlgoAPI_Prism::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
 {
   theMap = myMap;
 }
 
-//============================================================================
+//=================================================================================================
 GeomAlgoAPI_MakeShape* GeomAlgoAPI_Prism::makeShape() const
 {
   return myMkShape;
 }
 
-//============================================================================
+//=================================================================================================
 GeomAlgoAPI_Prism::~GeomAlgoAPI_Prism()
 {
   if (myImpl) {
index a795e90e7b7f51553a67dcc32029d8e172be72ed..fde00d55d965ad3c0a5cbfacb611d7becb08cfba 100644 (file)
 #include <GeomAPI_DataMapOfShapeShape.h>
 #include <memory>
 
-/**\class GeomAlgoAPI_Prism
- * \ingroup DataAlgo
- * \brief Allows to create the prism based on a given face and bounding planes
+/** \class GeomAlgoAPI_Prism
+ *  \ingroup DataAlgo
+ *  \brief Allows to create the prism based on a given face and bounding planes.
+ *  \n Note that only planar faces are allowed as bounding faces and resulting
+ *  extrusion will be bounded by the infinite planes taken from the faces.
  */
-
 class GeomAlgoAPI_Prism : public GeomAPI_Interface
 {
 public:
-  /* \brief Creates extrusion for the given shape along the normal for this shape
-   * \param[in] theBasis face or wire to be extruded
-   * \param[in] theFromShape bottom bounding shape
-   * \param[in] theToShape top bounding shape
-   * \return a solid or a face/shell which is obtained from specified one
+  /** \brief Creates extrusion for the given shape along the normal for this shape.
+   *  \param[in] theBasis face or wire to be extruded;
+   *  \param[in] theFromShape bottom bounding shape;
+   *  \param[in] theToShape top bounding shape;
    */
-  /// Constructor
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Prism(std::shared_ptr<GeomAPI_Shape> theBasis,
                                        std::shared_ptr<GeomAPI_Shape> theFromShape,
                                        std::shared_ptr<GeomAPI_Shape> theToShape);
 
-  /// Returns True if algorithm succeed
+  /// \return true if algorithm succeed.
   GEOMALGOAPI_EXPORT const bool isDone() const;
 
-  ///  Returns True if resulting shape is valid
+  /// \return true if resulting shape is valid.
   GEOMALGOAPI_EXPORT const bool isValid() const;
 
-  /// Returns True if resulting shape has volume
+  /// \return true if resulting shape has volume.
   GEOMALGOAPI_EXPORT const bool hasVolume() const;
 
-  /// Returns result of the Prism algorithm which may be a Solid or a Face
+  /// \return result of the Prism algorithm.
   GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape() const;
 
-  /// Returns the first shape 
+  /// \returns the first shape.
   GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& firstShape();
 
-  /// returns last shape
+  /// \return the last shape.
   GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& lastShape();
-  /// Returns map of sub-shapes of the result. To be used for History keeping
+
+  /// \return 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
+  /// \return interface for History processing.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape() const;
 
-  /// Destructor
+  /// Destructor.
   GEOMALGOAPI_EXPORT  ~GeomAlgoAPI_Prism();
+
 private:
-  /// builds resulting shape
+  /// Builds resulting shape.
   void build(const std::shared_ptr<GeomAPI_Shape>& theBasis);
-  /// fields
+
+private:
+  /// Fields.
   std::shared_ptr<GeomAPI_Shape> myFromShape;
   std::shared_ptr<GeomAPI_Shape> myToShape;
   bool myDone;
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp
new file mode 100644 (file)
index 0000000..a608373
--- /dev/null
@@ -0,0 +1,365 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Revolution.cpp
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAlgoAPI_Revolution.h>
+
+#include <GeomAlgoAPI_DFLoader.h>
+#include <GeomAlgoAPI_Rotation.h>
+#include <GeomAlgoAPI_ShapeProps.h>
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAlgoAPI_Cut.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepPrimAPI_MakeRevol.hxx>
+#include <BRepGProp.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <gp_Pln.hxx>
+#include <GProp_GProps.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBasis,
+                                               std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                               std::shared_ptr<GeomAPI_Shape> theFromShape,
+                                               double                         theFromAngle,
+                                               std::shared_ptr<GeomAPI_Shape> theToShape,
+                                               double                         theToAngle)
+: myAxis(theAxis),
+  myFromShape(theFromShape),
+  myFromAngle(theFromAngle),
+  myToShape(theToShape),
+  myToAngle(theToAngle),
+  myDone(false),
+  myShape(new GeomAPI_Shape()),
+  myFirst(new GeomAPI_Shape()),myLast(new GeomAPI_Shape())
+{
+  build(theBasis);
+}
+
+//=================================================================================================
+TopoDS_Face GeomAlgoAPI_Revolution::makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
+{
+  gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
+  double aSign = aVec * thePlane.Axis().Direction().XYZ();
+  if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
+
+  BRepBuilderAPI_MakeFace aMakeFace(thePlane);
+  TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
+
+  return aResultFace;
+}
+
+//=================================================================================================
+TopoDS_Solid GeomAlgoAPI_Revolution::makeSolidFromFace(const TopoDS_Face& theFace)
+{
+  TopoDS_Shell aShell;
+  TopoDS_Solid aSolid;
+
+  BRep_Builder aBoundingBuilder;
+  aBoundingBuilder.MakeShell(aShell);
+  aBoundingBuilder.Add(aShell, theFace);
+  aBoundingBuilder.MakeSolid(aSolid);
+  aBoundingBuilder.Add(aSolid, aShell);
+
+  return aSolid;
+}
+
+//=================================================================================================
+TopoDS_Shape GeomAlgoAPI_Revolution::findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
+{
+  TopoDS_Shape aResult = theShape;
+
+  if(theShape.ShapeType() == TopAbs_COMPOUND) {
+    double aMinDistance = Precision::Infinite();
+    double aCurDistance;
+    GProp_GProps aGProps;
+    gp_Pnt aCentr;
+
+    for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
+      TopoDS_Shape aValue = anItr.Value();
+      BRepGProp::VolumeProperties(aValue, aGProps);
+      aCentr = aGProps.CentreOfMass();
+      aCurDistance = aCentr.Distance(thePoint);
+
+      if(aCurDistance < aMinDistance) {
+        aMinDistance = aCurDistance;
+        aResult = aValue;
+      }
+    }
+  }
+
+  return aResult;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBasis)
+{
+  if(!theBasis || !myAxis ||
+    (((!myFromShape && !myToShape) || (myFromShape && myToShape && myFromShape->isEqual(myToShape)))
+    && (myFromAngle == 0.0 && myToAngle == 0.0))) {
+    return;
+  }
+
+  TopoDS_Face aBasisFace = TopoDS::Face(theBasis->impl<TopoDS_Shape>());
+  GeomLib_IsPlanarSurface isBasisPlanar(BRep_Tool::Surface(aBasisFace));
+  if(!isBasisPlanar.IsPlanar()) {// non-planar shapes is not supported for revolution
+    return;
+  }
+  gp_Pln aBasisPln = isBasisPlanar.Plan();
+  gp_Ax1 anAxis = myAxis->impl<gp_Ax1>();
+
+  TopoDS_Shape aResult;
+  if(!myFromShape && !myToShape) { // Case 1: When only angles was set.
+    // Rotating base face with the negative value of "from angle".
+    GeomAlgoAPI_Rotation aRotation(theBasis, myAxis, -myFromAngle);
+    TopoDS_Shape aRotatedBaseShape = aRotation.shape()->impl<TopoDS_Shape>();
+
+    // Making revolution to the angle equal to the sum of "from angle" and "to angle".
+    double anAngle = myFromAngle + myToAngle;
+    BRepPrimAPI_MakeRevol aRevolBuilder(aRotatedBaseShape,
+                                        anAxis,
+                                        anAngle / 180 * M_PI,
+                                        Standard_True);
+    aRevolBuilder.Build();
+    if(!aRevolBuilder.IsDone()) {
+      return;
+    }
+
+    aResult = aRevolBuilder.Shape();
+  } else if(myFromShape && myToShape) { // Case 2: When both bounding planes were set.
+    // Getting bounding faces.
+    TopoDS_Face aFromFace = TopoDS::Face(myFromShape->impl<TopoDS_Shape>());
+    TopoDS_Face aToFace   = TopoDS::Face(myToShape->impl<TopoDS_Shape>());
+
+    // Getting planes from bounding face.
+    GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
+    GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
+    if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {// non-planar shapes is not supported for revolution bounding
+      return;
+    }
+    gp_Pln aFromPln = isFromPlanar.Plan();
+    gp_Pln aToPln   = isToPlanar.Plan();
+
+    // Orienting bounding planes properly so that the center of mass of the base face stays
+    // on the result shape after cut.
+    gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeProps::centreOfMass(theBasis)->impl<gp_Pnt>();
+    aFromFace = makeFaceFromPlane(aFromPln, aBasisCentr);
+    aToFace   = makeFaceFromPlane(aToPln, aBasisCentr);
+
+    // Making solids from bounding planes and putting them in compound.
+    TopoDS_Shape aFromSolid = makeSolidFromFace(aFromFace);
+    TopoDS_Shape aToSolid   = makeSolidFromFace(aToFace);
+
+    // Rotating bounding planes to the specified angle.
+    gp_Trsf aFromTrsf;
+    gp_Trsf aToTrsf;
+    double aFromRotAngle = ((aFromPln.Axis().Direction() * aBasisPln.Axis().Direction()) > 0) ? -myFromAngle : myFromAngle;
+    double aToRotAngle = ((aToPln.Axis().Direction() * aBasisPln.Axis().Direction()) > 0) ? -myToAngle : myToAngle;
+    aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
+    aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
+    BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
+    BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
+    aFromSolid = aFromTransform.Shape();
+    aToSolid   = aToTransform.Shape();
+
+    // Making revolution to the 360 angle.
+    BRepPrimAPI_MakeRevol aRevolBuilder(aBasisFace, anAxis, 2 * M_PI, Standard_True);
+    aRevolBuilder.Build();
+    TopoDS_Shape aRevolShape = aRevolBuilder.Shape();
+
+    // Cutting revolution with from plane.
+    BRepAlgoAPI_Cut aFromCutBuilder(aRevolShape, aFromSolid);
+    aFromCutBuilder.Build();
+    if(!aFromCutBuilder.IsDone()) {
+      return;
+    }
+    aResult = aFromCutBuilder.Shape();
+
+    // Cutting revolution with to plane.
+    BRepAlgoAPI_Cut aToCutBuilder(aResult, aToSolid);
+    aToCutBuilder.Build();
+    if(!aToCutBuilder.IsDone()) {
+      return;
+    }
+    aResult = aToCutBuilder.Shape();
+
+    // If after cut we got more than one solids then take closest to the center of mass of the base face.
+    aResult = findClosest(aResult, aBasisCentr);
+
+  } else { //Case 3: When only one bounding plane was set.
+    // Getting bounding face.
+    TopoDS_Face aBoundingFace;
+    bool isFromFaceSet = false;
+    if(myFromShape) {
+      aBoundingFace = TopoDS::Face(myFromShape->impl<TopoDS_Shape>());
+      isFromFaceSet = true;
+    } else if(myToShape) {
+      aBoundingFace = TopoDS::Face(myToShape->impl<TopoDS_Shape>());
+    }
+
+    // Getting plane from bounding face.
+    GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
+    if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
+      return;
+    }
+    gp_Pln aBoundingPln = isBoundingPlanar.Plan();
+
+    // Orienting bounding plane properly so that the center of mass of the base face stays
+    // on the result shape after cut.
+    gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeProps::centreOfMass(theBasis)->impl<gp_Pnt>();
+    aBoundingFace = makeFaceFromPlane(aBoundingPln, aBasisCentr);
+
+    // Making solid from bounding plane.
+    TopoDS_Shape aBoundingSolid = makeSolidFromFace(aBoundingFace);
+
+    // Rotating bounding plane to the specified angle.
+    double aBoundingRotAngle = isFromFaceSet ? myFromAngle : myToAngle;
+    if(aBoundingPln.Axis().IsParallel(aBasisPln.Axis(), Precision::Confusion())) {
+      if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
+    } else {
+      double aSign = (aBoundingPln.Axis().Direction() ^ aBasisPln.Axis().Direction()) *
+                     anAxis.Direction();
+      if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
+        aBoundingRotAngle = -aBoundingRotAngle;
+      }
+    }
+    gp_Trsf aBoundingTrsf;
+    aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
+    BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
+    aBoundingSolid = aBoundingTransform.Shape();
+
+    // Making revolution to the 360 angle.
+    BRepPrimAPI_MakeRevol aRevolBuilder(aBasisFace, anAxis, 2 * M_PI, Standard_True);
+    aRevolBuilder.Build();
+    TopoDS_Shape aRevolShape = aRevolBuilder.Shape();
+
+    // Cutting revolution with bounding plane.
+    BRepAlgoAPI_Cut aFromCutBuilder(aRevolShape, aBoundingSolid);
+    aFromCutBuilder.Build();
+    if(!aFromCutBuilder.IsDone()) {
+      return;
+    }
+
+    // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
+    aResult = aFromCutBuilder.Shape();
+    if(isFromFaceSet) {
+      aBasisFace.Orientation(TopAbs_REVERSED);
+    }
+
+    // Making solid from basis face.
+    TopoDS_Shape aBasisSolid = makeSolidFromFace(aBasisFace);
+
+    // Rotating basis face to the specified angle.
+    gp_Trsf aBasisTrsf;
+    double aBasisRotAngle = isFromFaceSet ? myToAngle : -myFromAngle;
+    aBasisTrsf.SetRotation(anAxis, aBasisRotAngle / 180.0 * M_PI);
+    BRepBuilderAPI_Transform aBasisTransform(aBasisSolid, aBasisTrsf, true);
+    aBasisSolid = aBasisTransform.Shape();
+
+    // Cutting revolution with basis face.
+    BRepAlgoAPI_Cut aBasisCutBuilder(aResult, aBasisSolid);
+    aBasisCutBuilder.Build();
+    if(aBasisCutBuilder.IsDone()) {
+      TopoDS_Shape aCutResult = aBasisCutBuilder.Shape();
+      TopExp_Explorer anExp(aCutResult, TopAbs_SOLID);
+      if(anExp.More()) {
+        aResult = aCutResult;
+      }
+    }
+
+    // If after cut we got more than one solids then take closest to the center of mass of the base face.
+    aResult = findClosest(aResult, aBasisCentr);
+  }
+
+  TopExp_Explorer anExp(aResult, TopAbs_SOLID);
+  if(!anExp.More()) {
+    return;
+  }
+
+  // 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));
+  //myFirst->setImpl(new TopoDS_Shape(aBuilder->Modified(aFromShape).First()));
+  //myLast->setImpl(new TopoDS_Shape(aBuilder->Modified(aToShape).First()));
+  //myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
+  myDone = true;
+  return;
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Revolution::isDone() const
+{
+  return myDone;
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Revolution::isValid() const
+{
+  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+  return (aChecker.IsValid() == Standard_True);
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Revolution::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_Revolution::shape () const
+{
+  return myShape;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Revolution::firstShape()
+{
+  return myFirst;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Revolution::lastShape()
+{
+  return myLast;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Revolution::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
+{
+  theMap = myMap;
+}
+
+//=================================================================================================
+GeomAlgoAPI_MakeShape* GeomAlgoAPI_Revolution::makeShape() const
+{
+  return myMkShape;
+}
+
+//=================================================================================================
+GeomAlgoAPI_Revolution::~GeomAlgoAPI_Revolution()
+{
+  if (myImpl) {
+    myMap.clear();
+  }
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.h b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.h
new file mode 100644 (file)
index 0000000..a6df8b5
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Revolution.h
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Revolution_H_
+#define GeomAlgoAPI_Revolution_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_Ax1.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+
+class gp_Pln;
+class gp_Pnt;
+class TopoDS_Face;
+class TopoDS_Shape;
+class TopoDS_Solid;
+
+/** \class GeomAlgoAPI_Revolution
+ *  \ingroup DataAlgo
+ *  \brief Allows to create the revolution based on a given face, angles and bounding planes.
+ *  \n Note that only the planar faces are allowed as bounding faces and resulting
+ *  revolution will be bounded by the infinite planes taken from the faces.
+ *  \n If the bounding plane was specified with the angle then this plane will be rotated around
+ *  the axis to the value of the angle.
+ *  \n Note that algorithm return only one solid object. So in case when after cutting with bounding
+ *  planes algorithm got more than one solid it will return the closest to the center of mass of
+ *  the base face.
+ */
+class GeomAlgoAPI_Revolution : public GeomAPI_Interface
+{
+public:
+  /** \brief Creates revolution for the given shape
+   *  \param[in] theBasis face for revolution
+   *  \param[in] theFromShape from bounding shape
+   *  \param[in] theFromAngle from angle
+   *  \param[in] theToShape to bounding shape
+   *  \param[in] theToAngle to angle
+   *  \return a solid which is obtained from specified one
+   */
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBasis,
+                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                            std::shared_ptr<GeomAPI_Shape> theFromShape,
+                                            double                         theFromAngle,
+                                            std::shared_ptr<GeomAPI_Shape> theToShape,
+                                            double                         theToAngle);
+
+  /// \return true if algorithm succeed.
+  GEOMALGOAPI_EXPORT const bool isDone() const;
+
+  /// \return true if resulting shape is valid.
+  GEOMALGOAPI_EXPORT const bool isValid() const;
+
+  /// \return true if resulting shape has volume.
+  GEOMALGOAPI_EXPORT const bool hasVolume() const;
+
+  /// \return result of the Revolution algorithm.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape() const;
+
+  /// \return the first shape.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& firstShape();
+
+  /// \return the last shape.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& lastShape();
+  /// \return map of sub-shapes of the result. To be used for History keeping.
+  GEOMALGOAPI_EXPORT void mapOfShapes(GeomAPI_DataMapOfShapeShape& theMap) const;
+
+  /// \return interface for History processing.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape() const;
+
+  /// Destructor.
+  GEOMALGOAPI_EXPORT ~GeomAlgoAPI_Revolution();
+
+private:
+  /** \brief Constructs infinite face from thePlane, and with axis located on the same side
+   *  of the plane as thePoint. Modifies thePlane axis direction.
+   *  \param[in,out] thePlane plane to construct face.
+   *  \param[in] thePoint point to locate plane axis.
+   *  \return constructed face.
+   */
+  TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
+
+  /// \return solid created from face.
+  TopoDS_Solid makeSolidFromFace(const TopoDS_Face& theFace);
+
+  /** \brief Selects solid from theShape with closest center of mass to thePoint
+   *  \param[in] theShape compound with solids.
+   *  \param[in] thePoint point.
+   *  \return solid.
+   */
+  TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
+
+  /// Builds resulting shape.
+  void build(const std::shared_ptr<GeomAPI_Shape>& theBasis);
+
+private:
+  /// Fields.
+  std::shared_ptr<GeomAPI_Ax1>   myAxis;
+  std::shared_ptr<GeomAPI_Shape> myFromShape;
+  double myFromAngle;
+  std::shared_ptr<GeomAPI_Shape> myToShape;
+  double myToAngle;
+  bool myDone;
+  std::shared_ptr<GeomAPI_Shape> myShape;
+  std::shared_ptr<GeomAPI_Shape> myFirst;
+  std::shared_ptr<GeomAPI_Shape> myLast;
+  GeomAPI_DataMapOfShapeShape myMap;
+  GeomAlgoAPI_MakeShape* myMkShape;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp
new file mode 100644 (file)
index 0000000..f165e5a
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Rotation.cpp
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAlgoAPI_Rotation.h>
+
+#include <GeomAlgoAPI_ShapeProps.h>
+
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <Precision.hxx>
+#include <TopExp_Explorer.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                           std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                           double                         theAngle)
+: myDone(false),
+  myShape(new GeomAPI_Shape())
+{
+  build(theSourceShape, theAxis, theAngle);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Rotation::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                 std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                 double                         theAngle)
+{
+  if(!theSourceShape || !theAxis) {
+    return;
+  }
+
+  const TopoDS_Shape& aSourceShape = theSourceShape->impl<TopoDS_Shape>();
+  const gp_Ax1& anAxis = theAxis->impl<gp_Ax1>();
+
+  if(aSourceShape.IsNull()) {
+    return;
+  }
+
+  gp_Trsf aTrsf;
+  aTrsf.SetRotation(anAxis, theAngle / 180.0 * M_PI);
+
+  // Transform the shape with copying it.
+  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+  if(!aBuilder) {
+    return;
+  }
+
+  setImpl(aBuilder);
+  myDone = aBuilder->IsDone() == Standard_True;
+
+  if(!myDone) {
+    return;
+  }
+
+  TopoDS_Shape aResult = aBuilder->Shape();
+  // Fill data map to keep correct orientation of sub-shapes.
+  for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
+    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    myMap.bind(aCurrentShape, aCurrentShape);
+  }
+
+  myShape->setImpl(new TopoDS_Shape(aResult));
+  myMkShape = new GeomAlgoAPI_MakeShape(aBuilder);
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Rotation::isValid() const
+{
+  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+  return (aChecker.IsValid() == Standard_True);
+}
+
+//=================================================================================================
+const bool GeomAlgoAPI_Rotation::hasVolume() const
+{
+  bool hasVolume(false);
+  if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) {
+    hasVolume = true;
+  }
+  return hasVolume;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Rotation::shape() const
+{
+  return myShape;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Rotation::mapOfShapes(GeomAPI_DataMapOfShapeShape& theMap) const
+{
+  theMap = myMap;
+}
+
+//=================================================================================================
+GeomAlgoAPI_MakeShape* GeomAlgoAPI_Rotation::makeShape() const
+{
+  return myMkShape;
+}
+
+//=================================================================================================
+GeomAlgoAPI_Rotation::~GeomAlgoAPI_Rotation()
+{
+  if (myImpl) {
+    myMap.clear();
+  }
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h
new file mode 100644 (file)
index 0000000..3f77f21
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Rotation.h
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Rotation_H_
+#define GeomAlgoAPI_Rotation_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAPI_Ax1.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_Shape.h>
+
+/** \class GeomAlgoAPI_Rotation
+ *  \ingroup DataAlgo
+ *  \brief Creates a copy of the object by rotating it around the axis.
+ */
+class GeomAlgoAPI_Rotation : public GeomAPI_Interface
+{
+public:
+  /** \brief Creates an object which is obtained from current object by rotating it around the axis.
+   *  \param[in] theSourceShape  a shape to be rotated.
+   *  \param[in] theAxis         rotation axis.
+   *  \param[in] theAngle        rotation angle(in degree).
+   */
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+                                          std::shared_ptr<GeomAPI_Ax1>   theAxis,
+                                          double                         theAngle);
+
+  /// \return true if algorithm succeed.
+  GEOMALGOAPI_EXPORT const bool isDone() const
+  { return myDone; }
+
+  /// \return true if resulting shape is valid.
+  GEOMALGOAPI_EXPORT const bool isValid() const;
+
+  /// \return true if resulting shape has volume.
+  GEOMALGOAPI_EXPORT const bool hasVolume() const;
+
+  /// \return result of the Placement algorithm which may be a Solid or a Face.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape() const;
+
+  /// \return 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_Rotation();
+
+private:
+  /// Builds resulting shape.
+  void build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
+             std::shared_ptr<GeomAPI_Ax1>   theAxis,
+             double                         theAngle);
+
+private:
+  /// Fields.
+  bool myDone;
+  std::shared_ptr<GeomAPI_Shape> myShape;
+  GeomAPI_DataMapOfShapeShape    myMap;
+  GeomAlgoAPI_MakeShape*         myMkShape;
+};
+
+#endif
index 00ef55c0ea3710b858304f33ab83ad7d1447420e..f11155bede13d709e4c0e4925fe079f14acf8c09 100644 (file)
 #include <GProp_GProps.hxx>
 #include <TopoDS_Shape.hxx>
 
-
+//=================================================================================================
 double GeomAlgoAPI_ShapeProps::volume(std::shared_ptr<GeomAPI_Shape> theShape)
 {
   GProp_GProps aGProps;
-  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+  if(!theShape) {
+    return 0.0;
+  }
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  if(aShape.IsNull()) {
+    return 0.0;
+  }
   BRepGProp::VolumeProperties(aShape, aGProps);
   return aGProps.Mass();
-}
\ No newline at end of file
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeProps::centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  GProp_GProps aGProps;
+  if(!theShape) {
+    return NULL;
+  }
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  if(aShape.IsNull()) {
+    return NULL;
+  }
+  BRepGProp::SurfaceProperties(aShape, aGProps);
+  gp_Pnt aCentre = aGProps.CentreOfMass();
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
+}
index 636b43d85037ad87c5b73cbdaa603b99e3d84960..abc7faa724bc77bfc401d2d98304db49b539c97c 100644 (file)
@@ -7,19 +7,24 @@
 #ifndef GeomAlgoAPI_ShapeProps_H_
 #define GeomAlgoAPI_ShapeProps_H_
 
-/**\class GeomAlgoAPI_ShapeProps
- * \ingroup DataAlgo
- * \brief Allows to compute different shape props
- */
-
 #include <GeomAlgoAPI.h>
+
+#include <GeomAPI_Pnt.h>
 #include <GeomAPI_Shape.h>
 
+/** \class GeomAlgoAPI_ShapeProps
+ *  \ingroup DataAlgo
+ *  \brief Allows to compute different shape props.
+ */
 class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeProps
 {
 public:
-  /// Returns the total volume of the solids of the current shape
+  /// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
   static double volume(std::shared_ptr<GeomAPI_Shape> theShape);
+
+  /// \return the centre of mass of the current shape. The coordinates returned for the center of mass
+  /// are expressed in the absolute Cartesian coordinate system.
+  static std::shared_ptr<GeomAPI_Pnt> centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape);
 };
 
 #endif
index fda2411f42b9727627719ea32702dd588a28a6bd..2c40e8cb8a7ba13d0925581c1312ca54724717c2 100644 (file)
@@ -9,6 +9,7 @@ SET(PROJECT_HEADERS
     GeomValidators_Positive.h
     GeomValidators_ShapeType.h
     GeomValidators_Tools.h
+    GeomValidators_ZeroOffset.h
 )
 
 SET(PROJECT_SOURCES
@@ -17,6 +18,7 @@ SET(PROJECT_SOURCES
     GeomValidators_Positive.cpp
     GeomValidators_ShapeType.cpp
     GeomValidators_Tools.cpp
+    GeomValidators_ZeroOffset.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomValidators/GeomValidators_ZeroOffset.cpp b/src/GeomValidators/GeomValidators_ZeroOffset.cpp
new file mode 100644 (file)
index 0000000..2aa3cf4
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomValidators_ZeroOffset.h
+// Created:     13 May 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomValidators_ZeroOffset.h>
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelection.h>
+
+//=================================================================================================
+bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                        const std::list<std::string>& theArguments) const
+{
+  if(theArguments.size() < 4) {
+    return false;
+  }
+
+  std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+
+  std::shared_ptr<GeomAPI_Shape> aFromShape;
+  std::shared_ptr<GeomAPI_Shape> aToShape;
+
+  std::shared_ptr<ModelAPI_AttributeSelection> anAttrSel = theFeature->selection(*anIt);
+  if(anAttrSel) {
+    aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
+  }
+  anIt++;
+  anAttrSel = theFeature->selection(*anIt);
+  if(anAttrSel) {
+    aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
+  }
+  anIt++;
+
+  double aFromOffset = 0.0;
+  double aToOffset = 0.0;
+
+  std::shared_ptr<ModelAPI_AttributeDouble> anAttrDouble = theFeature->real(*anIt);
+  if(anAttrDouble) {
+    aFromOffset = anAttrDouble->value();
+  }
+  anIt++;
+  anAttrDouble = theFeature->real(*anIt);
+  if(anAttrDouble) {
+    aToOffset = anAttrDouble->value();
+  }
+
+  if(((!aFromShape && !aToShape) || ((aFromShape && aToShape) && aFromShape->isEqual(aToShape)))
+    && (aFromOffset == 0.0 && aToOffset == 0.0)) {
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool GeomValidators_ZeroOffset::isNotObligatory(std::string theFeature, std::string theAttribute)
+{
+  if(theAttribute == "from_object" || theAttribute == "to_object") {
+    return true;
+  }
+
+  return false;
+}
diff --git a/src/GeomValidators/GeomValidators_ZeroOffset.h b/src/GeomValidators/GeomValidators_ZeroOffset.h
new file mode 100644 (file)
index 0000000..b0ce4eb
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomValidators_ZeroOffset.h
+// Created:     13 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomValidators_ZeroOffset_H
+#define GeomValidators_ZeroOffset_H
+
+#include <GeomValidators.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_FeatureValidator.h>
+
+/** \class GeomValidators_ZeroOffset
+ *  \ingroup Validators
+ *  \brief Validates that bounding planes not the same or both offsets are not 0
+ */
+class GeomValidators_ZeroOffset : public ModelAPI_FeatureValidator
+{
+public:
+  /** \brief Returns true if feature and/or attributes are valid.
+   *  \param[in] theFeature the validated feature.
+   *  \param[in] theArguments the arguments in the configuration file for this validator.
+   *  \n First pair of arguments should be bounding planes id.
+   *  \n Second pair of arguments should be offsets id.
+   *  \returns true if feature is valid.
+   */
+  GEOMVALIDATORS_EXPORT virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                             const std::list<std::string>& theArguments) const;
+
+  /// \return true if the attribute in feature is not obligatory for the feature execution.
+  GEOMVALIDATORS_EXPORT virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
+#endif
index af2ca84621c2ea506c2d2358e5b67fc01ac2c24d..4818b3a5794277107285a80bdf3c3664d3845125 100644 (file)
@@ -174,8 +174,7 @@ bool Model_AttributeSelection::isInitialized()
       TDF_Label aSelLab = selectionLabel();
       if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape
         ResultPtr aContext = context();
-        if (!aContext.get()) 
-          return false;
+        return aContext.get();
       }
       if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value
           return true;
index 0927b50ee2d560bf28cfc81164ad307c744cc9ce..e0a753a4b2a806136ece3642a15cafde2c76653d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <GeomValidators_Face.h>
 #include <GeomValidators_ConstructionComposite.h>
+#include <GeomValidators_ZeroOffset.h>
 
 
 #include <ModelAPI_Object.h>
@@ -158,6 +159,9 @@ void PartSet_Module::registerValidators()
   aFactory->registerValidator("GeomValidators_ConstructionComposite",
                               new GeomValidators_ConstructionComposite);
 
+  aFactory->registerValidator("GeomValidators_ZeroOffset",
+                              new GeomValidators_ZeroOffset);
+
   aFactory->registerValidator("PartSet_SketchEntityValidator",
                               new PartSet_SketchEntityValidator);