]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implemented extrusion for sketch
authorazv <azv@opencascade.com>
Fri, 6 Jun 2014 14:01:53 +0000 (18:01 +0400)
committerazv <azv@opencascade.com>
Fri, 6 Jun 2014 14:01:53 +0000 (18:01 +0400)
src/ConstructionPlugin/ConstructionPlugin_Extrusion.cpp
src/ConstructionPlugin/ConstructionPlugin_Extrusion.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp

index 8b5dc2d60a5767158280db1ad1d162bdd778cfdb..0af9cad3b2647396a91bb620d2439f442989f1ec 100644 (file)
@@ -10,6 +10,8 @@
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeBoolean.h>
 
+#include <GeomAlgoAPI_Extrusion.h>
+
 using namespace std;
 
 ConstructionPlugin_Extrusion::ConstructionPlugin_Extrusion()
@@ -20,14 +22,24 @@ void ConstructionPlugin_Extrusion::initAttributes()
 {
   data()->addAttribute(EXTRUSION_FACE, ModelAPI_AttributeReference::type());
   data()->addAttribute(EXTRUSION_SIZE, ModelAPI_AttributeDouble::type());
-  data()->addAttribute(EXTRUSION_REVERCE, ModelAPI_AttributeBoolean::type());
+  data()->addAttribute(EXTRUSION_REVERSE, ModelAPI_AttributeBoolean::type());
 }
 
-// this is for debug only
-#include <iostream>
-void ConstructionPlugin_Extrusion::execute() 
+void ConstructionPlugin_Extrusion::execute()
 {
-  // TODO: create a real shape for the point using OCC layer
-  //cout<<"X="<<data()->real(POINT_ATTR_X)->value()<<" Y="<<data()->real(POINT_ATTR_Y)->value()
-  //    <<" Z="<<data()->real(POINT_ATTR_Z)->value()<<endl;
+  boost::shared_ptr<ModelAPI_AttributeReference> aFaceRef = 
+    boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(data()->attribute(EXTRUSION_FACE));
+  if (!aFaceRef)
+    return;
+  FeaturePtr aFaceFeature = aFaceRef->value();
+  if (!aFaceFeature)
+    return;
+  boost::shared_ptr<GeomAPI_Shape> aFace = aFaceFeature->data()->shape();
+  if (!aFace)
+    return;
+
+  double aSize = data()->real(EXTRUSION_SIZE)->value();
+  if (data()->boolean(EXTRUSION_REVERSE)->value())
+    aSize = -aSize;
+  data()->store(GeomAlgoAPI_Extrusion::makeExtrusion(aFace, aSize));
 }
index 5270d2d892c6a756d489202e8e1fd5c8e718b83b..5933929b83d27808c2c1ad42c6d80e06eecabd1e 100644 (file)
@@ -18,7 +18,7 @@ const std::string EXTRUSION_FACE = "extrusion_face";
 const std::string EXTRUSION_SIZE = "extrusion_size";
 
 /// attribute name of reverce direction
-const std::string EXTRUSION_REVERCE = "extrusion_reverse";
+const std::string EXTRUSION_REVERSE = "extrusion_reverse";
 
 
 class ConstructionPlugin_Extrusion: public ModelAPI_Feature
index 5822d61fb15faafa03f551fd693e723608ea1b04..135d2747055307f087dd94627e59b5ff62c82b5a 100644 (file)
@@ -10,6 +10,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_EdgeBuilder.h
     GeomAlgoAPI_PointBuilder.h
     GeomAlgoAPI_SketchBuilder.h
+    GeomAlgoAPI_Extrusion.h
 )
 
 SET(PROJECT_SOURCES
@@ -18,6 +19,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_EdgeBuilder.cpp
     GeomAlgoAPI_PointBuilder.cpp
     GeomAlgoAPI_SketchBuilder.cpp
+    GeomAlgoAPI_Extrusion.cpp
 )
 
 ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS})
@@ -33,7 +35,7 @@ INCLUDE_DIRECTORIES(
   ${CAS_INCLUDE_DIRS}
 )
 
-TARGET_LINK_LIBRARIES(GeomAlgoAPI ${PROJECT_LIBRARIES} GeomAPI ${CAS_TKBool} ${CAS_TKBO})
+TARGET_LINK_LIBRARIES(GeomAlgoAPI ${PROJECT_LIBRARIES} GeomAPI ${CAS_TKBool} ${CAS_TKBO} ${CAS_TKPrim})
 
 SET(SWIG_SCRIPTS
   ${CMAKE_CURRENT_BINARY_DIR}/GeomAlgoAPI.py
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp
new file mode 100644 (file)
index 0000000..d5affc0
--- /dev/null
@@ -0,0 +1,68 @@
+// File:        GeomAlgoAPI_Extrusion.cpp
+// Created:     06 Jun 2014
+// Author:      Artem ZHIDKOV
+
+#include <GeomAlgoAPI_Extrusion.h>
+
+#include <gp_Pln.hxx>
+
+#include <BRepPrimAPI_MakePrism.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <Precision.hxx>
+const double tolerance = Precision::Angular();
+
+boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
+                        boost::shared_ptr<GeomAPI_Shape> theShape,
+                        boost::shared_ptr<GeomAPI_Dir>   theDir,
+                        double                           theSize)
+{
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  gp_Vec aDir(theDir->impl<gp_Dir>().XYZ() * theSize);
+
+  TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(aShape, aDir);
+  if (aPrism.IsNull())
+    return boost::shared_ptr<GeomAPI_Shape>();
+
+  boost::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape());
+  aResult->setImpl(new TopoDS_Shape(aPrism));
+  return aResult;
+}
+
+boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
+                        boost::shared_ptr<GeomAPI_Shape> theShape,
+                        double                           theSize)
+{
+  bool isFirstNorm = true;
+  gp_Dir aShapeNormal;
+
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  TopExp_Explorer aFaceExp(aShape, TopAbs_FACE);
+  for ( ; aFaceExp.More(); aFaceExp.Next())
+  {
+    const TopoDS_Face& aFace = (const TopoDS_Face&)aFaceExp.Current();
+    Handle(BRep_TFace) aBFace = Handle(BRep_TFace)::DownCast(aFace.TShape());
+    if (aBFace.IsNull())
+      return boost::shared_ptr<GeomAPI_Shape>();
+
+    Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aBFace->Surface());
+    if (aPlane.IsNull()) // non-planar shapes is not supported for extrusion yet
+      continue;
+
+    const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();
+    if (isFirstNorm)
+    {
+      aShapeNormal = aNormal;
+      isFirstNorm = false;
+    }
+    else if (!aShapeNormal.IsEqual(aNormal, tolerance)) // non-planar shapes is not supported for extrusion yet
+      return boost::shared_ptr<GeomAPI_Shape>();
+  }
+
+  boost::shared_ptr<GeomAPI_Dir> aDir(
+    new GeomAPI_Dir(aShapeNormal.X(), aShapeNormal.Y(), aShapeNormal.Z()));
+
+  return GeomAlgoAPI_Extrusion::makeExtrusion(theShape, aDir, theSize);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h
new file mode 100644 (file)
index 0000000..f2a098c
--- /dev/null
@@ -0,0 +1,42 @@
+// File:        GeomAlgoAPI_Extrusion.h
+// Created:     06 Jun 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAlgoAPI_Extrusion_HeaderFile
+#define GeomAlgoAPI_Extrusion_HeaderFile
+
+#include <GeomAlgoAPI.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Dir.h>
+#include <boost/shared_ptr.hpp>
+
+/**\class GeomAlgoAPI_Extrusion
+ * \ingroup DataAlgo
+ * \brief Allows to create the prism based on a given face and a direction
+ */
+
+class GEOMALGOAPI_EXPORT GeomAlgoAPI_Extrusion
+{
+public:
+  /* \brief Creates extrusion for the given shape
+   * \param[in] theShape face or wire to be extruded
+   * \param[in] theDir   direction of extrusion
+   * \param[in] theSize  the length of extrusion (if the value is less than 0, the extrusion in opposite direction)
+   * \return a solid or a face which is obtained from specified one
+   */
+  static boost::shared_ptr<GeomAPI_Shape> makeExtrusion(
+                        boost::shared_ptr<GeomAPI_Shape> theShape,
+                        boost::shared_ptr<GeomAPI_Dir>   theDir,
+                        double                           theSize);
+
+  /* \brief Creates extrusion for the given shape along the normal for this shape
+   * \param[in] theShape face or wire to be extruded
+   * \param[in] theSize  the length of extrusion (if the value is less than 0, the extrusion in opposite normal)
+   * \return a solid or a face which is obtained from specified one
+   */
+  static boost::shared_ptr<GeomAPI_Shape> makeExtrusion(
+                        boost::shared_ptr<GeomAPI_Shape> theShape,
+                        double                           theSize);
+};
+
+#endif
index 01cc99bffe20970175a946e6344394a269b0b898..1828a7193368b9cba8950f1a18bd005fa0954228 100644 (file)
 #include <BRep_TVertex.hxx>
 #include <BRepAlgoAPI_Cut.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 #include <Geom_Curve.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
-#include <TopOpeBRepTool_ShapeClassifier.hxx>
 
 #include <Precision.hxx>
 const double tolerance = Precision::Confusion();
@@ -298,37 +298,50 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
 void GeomAlgoAPI_SketchBuilder::fixIntersections(
           std::list< boost::shared_ptr<GeomAPI_Shape> >& theFaces)
 {
-////  TopOpeBRepTool_ShapeClassifier aClassifier;
-////  const int aSameDomain = 1;
-////
-////  std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
-////  std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
-////  for ( ; anIter1 != theFaces.end(); anIter1++)
-////  {
-////    anIter2 = anIter1;
-////    for (++anIter2; anIter2 != theFaces.end(); anIter2++)
-////    {
-////      TopAbs_State aState = aClassifier.StateShapeShape(
-////        (*anIter1)->impl<TopoDS_Shape>(), (*anIter2)->impl<TopoDS_Shape>(), aSameDomain);
-////      if (aState == TopAbs_IN)
-////      { // second shape should be cut from the first
-////        BRepAlgoAPI_Cut aCut((*anIter1)->impl<TopoDS_Shape>(),
-////                             (*anIter2)->impl<TopoDS_Shape>());
-////        (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape()));
-////      }
-////      else if (aState != TopAbs_OUT)
-////      { // change the shapes order and repeat
-////        aState = aClassifier.StateShapeShape(
-////          (*anIter2)->impl<TopoDS_Shape>(), (*anIter1)->impl<TopoDS_Shape>(), aSameDomain);
-////        if (aState == TopAbs_IN)
-////        { // first shape should be cut from the second
-////          BRepAlgoAPI_Cut aCut((*anIter2)->impl<TopoDS_Shape>(),
-////                               (*anIter1)->impl<TopoDS_Shape>());
-////          (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape()));
-////        }
-////      }
-////    }
-////  }
+  BRepClass_FaceClassifier aClassifier;
+
+  std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
+  std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
+  for ( ; anIter1 != theFaces.end(); anIter1++)
+  {
+    anIter2 = anIter1;
+    for (++anIter2; anIter2 != theFaces.end(); anIter2++)
+    {
+      const TopoDS_Face& aF1 = (*anIter1)->impl<TopoDS_Face>();
+      TopExp_Explorer aVert2((*anIter2)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+      for ( ; aVert2.More(); aVert2.Next())
+      {
+        Handle(BRep_TVertex) aV = Handle(BRep_TVertex)::DownCast(aVert2.Current().TShape());
+        aClassifier.Perform(aF1, aV->Pnt(), tolerance);
+        if (aClassifier.State() != TopAbs_IN)
+          break;
+      }
+      if (aVert2.More())
+      { // second shape is not inside first, change the shapes order and repeat comparision
+        const TopoDS_Face& aF2 = (*anIter2)->impl<TopoDS_Face>();
+        TopExp_Explorer aVert1((*anIter1)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+        for ( ; aVert1.More(); aVert1.Next())
+        {
+          Handle(BRep_TVertex) aV = Handle(BRep_TVertex)::DownCast(aVert1.Current().TShape());
+          aClassifier.Perform(aF2, aV->Pnt(), tolerance);
+          if (aClassifier.State() != TopAbs_IN)
+            break;
+        }
+        if (!aVert1.More())
+        { // first shape should be cut from the second
+          BRepAlgoAPI_Cut aCut((*anIter2)->impl<TopoDS_Shape>(),
+                               (*anIter1)->impl<TopoDS_Shape>());
+          (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape()));
+        }
+      }
+      else
+      { // second shape should be cut from the first
+        BRepAlgoAPI_Cut aCut((*anIter1)->impl<TopoDS_Shape>(),
+                             (*anIter2)->impl<TopoDS_Shape>());
+        (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape()));
+      }
+    }
+  }
 }
 
 
index bc9d72735210f7e0e9647aa93afa68a1cb16f5a7..850058e8c1d438da7edb4a59c41fcac9d05ded49 100644 (file)
@@ -64,6 +64,10 @@ void SketchPlugin_Sketch::execute()
   std::list< boost::shared_ptr<GeomAPI_Shape> > aWires;
   GeomAlgoAPI_SketchBuilder::createFaces(aDirX->dir(), aDirY->dir(), aNorm->dir(),
                                          aFeaturesPreview, aLoops, aWires);
+
+  aLoops.insert(aLoops.end(), aWires.begin(), aWires.end());
+  boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aLoops);
+  data()->store(aCompound);
 }
 
 const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Sketch::preview()