]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implementation of experimental approximated pipe creation feature done by Edouard... PipeApprox
authormpv <mpv@opencascade.com>
Mon, 29 Aug 2016 10:09:27 +0000 (13:09 +0300)
committermpv <mpv@opencascade.com>
Mon, 29 Aug 2016 10:09:27 +0000 (13:09 +0300)
20 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_PipeApprox.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_PipeApprox.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/parameterlaw_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/pipeapprox_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/pipeapproxlaw_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.h [new file with mode: 0644]
src/Model/Model_Update.cpp

index 451b9c0022d65ea1513c1971f1c4c8f7033ea651..03df9caa699cfff73fdaa653708dd1cb79f4812e 100644 (file)
@@ -28,6 +28,10 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_ValidatorTransform.h
     FeaturesPlugin_Validators.h
     FeaturesPlugin_RemoveSubShapes.h
+    FeaturesPlugin_PipeApprox.h
+    FeaturesPlugin_PipeApproxLaw.h
+    FeaturesPlugin_ParameterLaw.h
+    FeaturesPlugin_Validators.h
 )
 
 SET(PROJECT_SOURCES
@@ -54,6 +58,10 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_ValidatorTransform.cpp
     FeaturesPlugin_Validators.cpp
     FeaturesPlugin_RemoveSubShapes.cpp
+    FeaturesPlugin_PipeApprox.cpp
+    FeaturesPlugin_PipeApproxLaw.cpp
+    FeaturesPlugin_ParameterLaw.cpp
+    FeaturesPlugin_Validators.cpp
 )
 
 SET(XML_RESOURCES
@@ -74,6 +82,9 @@ SET(XML_RESOURCES
   pipe_widget.xml
   remove_subshapes_widget.xml
   union_widget.xml
+  pipeapprox_widget.xml
+  pipeapproxlaw_widget.xml
+  parameterlaw_widget.xml
 )
 
 SET(TEXT_RESOURCES
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.cpp b/src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.cpp
new file mode 100644 (file)
index 0000000..4f38329
--- /dev/null
@@ -0,0 +1,131 @@
+// Copyright
+
+// File:        FeaturesPlugin_ParameterLaw.cpp
+
+
+#include "FeaturesPlugin_ParameterLaw.h"
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Object.h>
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+//??#include "ParametersPlugin_Parameter.h"
+//??#include <SketchPlugin_SketchEntity.h>
+#include <ModelAPI_AttributeDouble.h>
+//#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+
+#include <sstream>
+#include <string> 
+
+//=================================================================================================
+FeaturesPlugin_ParameterLaw::FeaturesPlugin_ParameterLaw()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_ParameterLaw::initAttributes()
+{
+       data()->addAttribute(LAW_REFERENCE_ID(), ModelAPI_AttributeSelection::typeId());
+       data()->addAttribute(LAW_DEFINITION_ID(), ModelAPI_AttributeSelection::typeId());
+       data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
+
+       data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
+
+       data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+}
+
+//=================================================================================================
+void FeaturesPlugin_ParameterLaw::execute()
+{
+       // Getting Ref and Def
+       std::shared_ptr<GeomAPI_Shape> aRef;
+       std::shared_ptr<GeomAPI_Shape> aDef;
+       //REFERENCE
+       AttributeSelectionPtr aRefSelection = selection(LAW_REFERENCE_ID());
+       if(!aRefSelection.get()) {
+               setError("Error: Ref selection is empty.");
+               return;
+       }
+       aRef = std::dynamic_pointer_cast<GeomAPI_Shape>(aRefSelection->value());
+       if(!aRef.get()) {
+               // Probably it is a construction.
+               aRef = aRefSelection->context()->shape();
+       }
+       if(!aRef.get() || aRef->isNull()) {
+               setError("Error: Ref shape is null.");
+               return;
+       }
+       //DEFINITION
+       AttributeSelectionPtr aDefSelection = selection(LAW_DEFINITION_ID());
+       if(!aDefSelection.get()) {
+               setError("Error: Def selection is empty.");
+               return;
+       }
+       aDef = std::dynamic_pointer_cast<GeomAPI_Shape>(aDefSelection->value());
+       if(!aDef.get()) {
+               // Probably it is a construction.
+               aDef = aDefSelection->context()->shape();
+       }
+       if(!aDef.get() || aDef->isNull()) {
+               setError("Error: Def shape is null.");
+               return;
+       }
+
+       // Flags for reverse path
+    bool isReverse = boolean(REVERSE_ID())->value();
+
+       GeomAlgoAPI_ParameterLaw aParameterLawAlgo = GeomAlgoAPI_ParameterLaw(aDef, aRef, isReverse);
+       int aResultIndex = 0;
+
+       if(!aParameterLawAlgo.isDone()) {
+               static const std::string aPrismAlgoError = "Error: Param algo failed.";
+               setError(aPrismAlgoError);
+               aResultIndex = 0;
+               //break;
+       }
+       // Check if shape is valid
+       if(!aParameterLawAlgo.shape().get() || aParameterLawAlgo.shape()->isNull()) {
+               static const std::string aShapeError = "Error: Resulting shape is Null.";
+               setError(aShapeError);
+               aResultIndex = 0;
+               return;
+       }
+       if(!aParameterLawAlgo.isValid()) {
+               std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
+               setError(aPrismAlgoError);
+               aResultIndex = 0;
+               //break;
+       }
+
+       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+       
+       loadNamingDS(aParameterLawAlgo, aResultBody);
+       setResult(aResultBody, aResultIndex);
+       aResultIndex++;
+       removeResults(aResultIndex);
+}
+
+void FeaturesPlugin_ParameterLaw::loadNamingDS(GeomAlgoAPI_ParameterLaw& theParameterLawAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody)
+{
+       theResultBody->store(theParameterLawAlgo.shape());
+       
+       int aIndex = 0, aTag = 0;
+       const std::string aName = "Law";
+       std::ostringstream aStr;
+       aStr << aName << "_" << aIndex++;
+       theResultBody->generated(theParameterLawAlgo.shape(), aStr.str(), aTag++);
+}
\ No newline at end of file
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.h b/src/FeaturesPlugin/FeaturesPlugin_ParameterLaw.h
new file mode 100644 (file)
index 0000000..c6b4895
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright
+
+// File:        FeaturesPlugin_ParameterLaw.h
+
+
+#ifndef FeaturesPlugin_ParameterLaw_H_
+#define FeaturesPlugin_ParameterLaw_H_
+
+#include <FeaturesPlugin.h>
+
+#include <GeomAlgoAPI_ParameterLaw.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <memory>
+#include <list>
+
+class GeomAPI_Shape;
+class ModelAPI_ResultBody;
+
+/** \class FeaturesPlugin_Pipe
+ *  \ingroup Plugins
+ *  \brief Feature for creation of Pipe from the planar face.
+ *  Pipe 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_ParameterLaw : public ModelAPI_Feature
+{
+ public:
+  /// Pipe kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ParameterLaw_ID("ParameterLaw");
+    return MY_ParameterLaw_ID;
+  }
+
+      /// attribute name of law reference curve
+  inline static const std::string& LAW_REFERENCE_ID()
+  {
+    static const std::string MY_LAW_REFERENCE_ID("law_reference");
+    return MY_LAW_REFERENCE_ID;
+  }
+
+      /// attribute name of law definition curve
+  inline static const std::string& LAW_DEFINITION_ID()
+  {
+    static const std::string MY_LAW_DEFINITION_ID("law_definition");
+    return MY_LAW_DEFINITION_ID;
+  }
+
+      /// attribute name of parameter name
+  inline static const std::string& VARIABLE_ID()
+  {
+    static const std::string MY_VARIABLE_ID("variable");
+    return MY_VARIABLE_ID;
+  }
+
+    /// attribute name of flag of reverse direction
+  inline static const std::string& REVERSE_ID()
+  {
+    static const std::string MY_REVERSE_ID("reverse_direction");
+    return MY_REVERSE_ID;
+  }
+
+  /// attribute name for creation method
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string METHOD_ATTR("CreationMethod");
+    return METHOD_ATTR;
+  }
+
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_ParameterLaw::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_ParameterLaw();
+
+private:
+  /// Load Naming data structure of the feature to the document.
+  void loadNamingDS(GeomAlgoAPI_ParameterLaw& theParameterLawAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody);
+};
+#endif
diff --git a/src/FeaturesPlugin/FeaturesPlugin_PipeApprox.cpp b/src/FeaturesPlugin/FeaturesPlugin_PipeApprox.cpp
new file mode 100644 (file)
index 0000000..b0804d5
--- /dev/null
@@ -0,0 +1,314 @@
+// Copyright
+
+// File:        FeaturesPlugin_PipeApprox.cpp
+
+
+#include "FeaturesPlugin_PipeApprox.h"
+
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Object.h>
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+//??#include "ParametersPlugin_Parameter.h"
+//??#include <SketchPlugin_SketchEntity.h>
+#include <ModelAPI_AttributeDouble.h>
+//#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+
+#include <sstream>
+#include <string> 
+
+namespace patch
+{
+       template < typename T > std::string to_string( const T& n )
+       {
+               std::ostringstream stm ;
+               stm << n ;
+               return stm.str() ;
+       }
+}
+
+//static ListOfShape makeProfileList(ObjectPtr theProfileObjRef);
+static ListOfShape makeProfileList(AttributeSelectionListPtr aFacesSelectionList);
+//=================================================================================================
+FeaturesPlugin_PipeApprox::FeaturesPlugin_PipeApprox()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApprox::initAttributes()
+{
+       AttributeSelectionListPtr aSelection = 
+               std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+               PROFILE_ID(), ModelAPI_AttributeSelectionList::typeId()));
+       aSelection->setSelectionType("FACE");
+
+
+       data()->addAttribute(PATH_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+       //data()->addAttribute(PATH_OBJECT_ID(), ModelAPI_AttributeSelectionList::typeId());
+       data()->addAttribute(BINORMAL_ID(), ModelAPI_AttributeSelection::typeId());
+
+       data()->addAttribute(LAW_REFERENCE_ID(), ModelAPI_AttributeSelection::typeId());
+       data()->addAttribute(LAW_DEFINITION_ID(), ModelAPI_AttributeSelection::typeId());
+
+       data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApprox::execute()
+{
+       // Getting creation method.
+       std::string aCreationMethod = string(CREATION_METHOD())->value();
+
+       //Getting path 
+       //limit to edge
+
+       std::shared_ptr<GeomAPI_Edge> aPath;
+       std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(PATH_OBJECT_ID());
+
+       if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
+               aPath = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
+       } else if(anObjRef->context() && anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
+               aPath = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
+       }
+       /*
+       //list of edge
+       ListOfShape aEdgesList;
+       AttributeSelectionListPtr aEdgesSelectionList = selectionList(PATH_OBJECT_ID());
+       for(int anIndex = 0; anIndex < aEdgesSelectionList->size(); anIndex++) {
+       AttributeSelectionPtr aEdgeSel = aEdgesSelectionList->value(anIndex);
+       std::shared_ptr<GeomAPI_Shape> aEdgeShape = aEdgeSel->value();
+       if(aEdgeShape.get() && !aEdgeShape->isNull()) { 
+       aEdgesList.push_back(aEdgeShape);
+       }
+       }
+       */
+
+       //Getting profile
+       ListOfShape aFacesList;
+       AttributeSelectionListPtr aFacesSelectionList = selectionList(PROFILE_ID());
+       for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
+               AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
+               std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
+               if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
+                       aFacesList.push_back(aFaceShape);
+               } else { // This may be the whole sketch result selected, check and get faces.
+                       ResultPtr aContext = aFaceSel->context();
+                       std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
+                       if(!aContextShape.get()) {
+                               static const std::string aContextError = "Error: The selection context is bad.";
+                               setError(aContextError);
+                               return;
+                       }
+                       ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+                       if(!aConstruction.get()) {
+                               static const std::string aFaceError = "Error: Can not find basis for extrusion.";
+                               setError(aFaceError);
+                               return;
+                       }
+                       int aFacesNum = aConstruction->facesNum();
+                       for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+                               aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+                               aFacesList.push_back(aFaceShape);
+                       }
+               }
+       }
+
+       // Getting Bi-Normal
+       std::shared_ptr<GeomAPI_Shape> aBiNormal;
+       if(aCreationMethod == "binormal") {
+               AttributeSelectionPtr aBiNormalSelection = selection(BINORMAL_ID());
+               if(!aBiNormalSelection.get()) {
+                       setError("Error: Bi-Normal selection is empty.");
+                       return;
+               }
+               aBiNormal = std::dynamic_pointer_cast<GeomAPI_Shape>(aBiNormalSelection->value());
+               if(!aBiNormal.get()) {
+                       // Probably it is a construction.
+                       aBiNormal = aBiNormalSelection->context()->shape();
+               }
+               if(!aBiNormal.get() || aBiNormal->isNull()) {
+                       setError("Error: Bi-Normal shape is null.");
+                       return;
+               }
+       }
+
+       // Getting Ref and Def
+       std::shared_ptr<GeomAPI_Shape> aRef;
+       std::shared_ptr<GeomAPI_Shape> aDef;
+       if(aCreationMethod == "with law") {
+               //REFERENCE
+               AttributeSelectionPtr aRefSelection = selection(LAW_REFERENCE_ID());
+               if(!aRefSelection.get()) {
+                       setError("Error: Ref selection is empty.");
+                       return;
+               }
+               aRef = std::dynamic_pointer_cast<GeomAPI_Shape>(aRefSelection->value());
+               if(!aRef.get()) {
+                       // Probably it is a construction.
+                       aRef = aRefSelection->context()->shape();
+               }
+               if(!aRef.get() || aRef->isNull()) {
+                       setError("Error: Ref shape is null.");
+                       return;
+               }
+               //DEFINITION
+               AttributeSelectionPtr aDefSelection = selection(LAW_DEFINITION_ID());
+               if(!aDefSelection.get()) {
+                       setError("Error: Def selection is empty.");
+                       return;
+               }
+               aDef = std::dynamic_pointer_cast<GeomAPI_Shape>(aDefSelection->value());
+               if(!aDef.get()) {
+                       // Probably it is a construction.
+                       aDef = aDefSelection->context()->shape();
+               }
+               if(!aDef.get() || aDef->isNull()) {
+                       setError("Error: Def shape is null.");
+                       return;
+               }
+       }
+
+       // Generating result for each shell and face.
+       int aResultIndex = 0;
+       if(aCreationMethod == "simple" || aCreationMethod == "binormal" 
+               || aCreationMethod == "with law") {
+                       for(ListOfShape::const_iterator anIter = aFacesList.cbegin(); anIter != aFacesList.cend(); anIter++) {
+                               std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
+                               //std::shared_ptr<GeomAPI_Shape> aBaseShape = aFaceShape;
+                               GeomAlgoAPI_PipeApprox aPipeApproxAlgo = GeomAlgoAPI_PipeApprox();
+                               if(aCreationMethod == "simple"){
+                                       aPipeApproxAlgo = GeomAlgoAPI_PipeApprox(aBaseShape, aPath);
+                               }else if(aCreationMethod == "binormal"){
+                                       aPipeApproxAlgo = GeomAlgoAPI_PipeApprox(aBaseShape, aPath, aBiNormal);
+                               }else if(aCreationMethod == "with law"){
+                                       aPipeApproxAlgo = GeomAlgoAPI_PipeApprox(aBaseShape, aPath, aDef, aRef);
+                               }
+
+
+                               /*
+                               GeomAlgoAPI_PipeApprox aPipeApproxAlgo = aCreationMethod == "simple" ? GeomAlgoAPI_PipeApprox(aBaseShape, aEdgesList) :
+                               GeomAlgoAPI_PipeApprox(aBaseShape, aEdgesList, aBiNormal);
+                               */
+                               if(!aPipeApproxAlgo.isDone()) {
+                                       static const std::string aPrismAlgoError = "Error: Pipe algorithm failed.";
+                                       setError(aPrismAlgoError);
+                                       aResultIndex = 0;
+                                       //break;
+                               }
+                               // Check if shape is valid
+                               if(!aPipeApproxAlgo.shape().get() || aPipeApproxAlgo.shape()->isNull()) {
+                                       static const std::string aShapeError = "Error: Resulting shape is Null.";
+                                       setError(aShapeError);
+                                       aResultIndex = 0;
+                                       //break;
+                               }
+                               if(!aPipeApproxAlgo.isValid()) {
+                                       std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
+                                       setError(aPrismAlgoError);
+                                       aResultIndex = 0;
+                                       //break;
+                               }
+
+                               ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+                               loadNamingDS(aPipeApproxAlgo, aResultBody, aBaseShape);
+                               setResult(aResultBody, aResultIndex);
+                               aResultIndex++;
+                       }
+       }
+       removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApprox::loadNamingDS(GeomAlgoAPI_PipeApprox& thePipeApproxAlgo,
+       std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+       std::shared_ptr<GeomAPI_Shape> theBasis)
+{
+       //load result
+       theResultBody->storeGenerated(theBasis, thePipeApproxAlgo.shape());
+
+       std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = thePipeApproxAlgo.mapOfSubShapes();
+
+       //Insert lateral face : Face from Edge
+       const std::string aLatName = "LateralFace";
+       const int aLatTag = 1;
+       theResultBody->loadAndOrientGeneratedShapes(&thePipeApproxAlgo, theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
+
+       //Insert to faces
+       int aToFaceIndex = 1;
+       const std::string aToName = "ToFace";
+       int aToTag = 2;
+       const ListOfShape& aToFaces = thePipeApproxAlgo.toShapes();
+       for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
+               std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
+               if(aSubShapes->isBound(aToFace)) {
+                       aToFace = aSubShapes->find(aToFace);
+               }
+               std::ostringstream aStr;
+               aStr << aToName << "_" << aToFaceIndex++;
+               theResultBody->generated(aToFace, aStr.str(), aToTag++);
+       }
+
+       //Insert from faces
+       int aFromFaceIndex = 1;
+       const std::string aFromName = "FromFace";
+       int aFromTag = aToTag > 10000 ? aToTag : 10000;
+       const ListOfShape& aFromFaces = thePipeApproxAlgo.fromShapes();
+       for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
+               std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
+               if(aSubShapes->isBound(aFromFace)) {
+                       aFromFace = aSubShapes->find(aFromFace);
+               }
+               std::ostringstream aStr;
+               aStr << aFromName << "_" << aFromFaceIndex++;
+               theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
+       }
+}
+
+
+
+//ListOfShape makeProfileList(ObjectPtr theProfileObjRef){
+ListOfShape makeProfileList(AttributeSelectionListPtr aFacesSelectionList){
+       ListOfShape aFacesList;
+       //AttributeSelectionListPtr aFacesSelectionList = theProfileObjRef->data()->selectionList("profile");
+       for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
+               AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
+               std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
+               if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
+                       aFacesList.push_back(aFaceShape);
+               } else { // This may be the whole sketch result selected, check and get faces.
+                       ResultPtr aContext = aFaceSel->context();
+                       std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
+                       if(!aContextShape.get()) {
+                               static const std::string aContextError = "Error: The selection context is bad.";
+                               return aFacesList;
+                       }
+                       ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+                       if(!aConstruction.get()) {
+                               static const std::string aFaceError = "Error: Can not find basis for extrusion.";
+                               return aFacesList;
+                       }
+                       int aFacesNum = aConstruction->facesNum();
+                       for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+                               aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+                               aFacesList.push_back(aFaceShape);
+                       }
+               }
+       }
+
+       return aFacesList;
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_PipeApprox.h b/src/FeaturesPlugin/FeaturesPlugin_PipeApprox.h
new file mode 100644 (file)
index 0000000..b742ae3
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright
+
+// File:        FeaturesPlugin_PipeApprox.h
+
+
+#ifndef FeaturesPlugin_PipeApprox_H_
+#define FeaturesPlugin_PipeApprox_H_
+
+#include <FeaturesPlugin.h>
+
+#include <GeomAlgoAPI_PipeApprox.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <memory>
+#include <list>
+
+class GeomAPI_Shape;
+class ModelAPI_ResultBody;
+
+/** \class FeaturesPlugin_Pipe
+ *  \ingroup Plugins
+ *  \brief Feature for creation of Pipe from the planar face.
+ *  Pipe 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_PipeApprox : public ModelAPI_Feature
+{
+ public:
+  /// Pipe kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_PipeApprox_ID("PipeApprox");
+    return MY_PipeApprox_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& PROFILE_ID()
+  {
+    static const std::string MY_PROFILE_LIST_ID("profile");
+    return MY_PROFILE_LIST_ID;
+  }
+
+  /// Attribute name of an Pipe path.
+  inline static const std::string& PATH_OBJECT_ID()
+  {
+    static const std::string MY_PATH_ID("path_object");
+    return MY_PATH_ID;
+  }
+
+  /// Attribute name of Bi-Normal.
+  inline static const std::string& BINORMAL_ID()
+  {
+    static const std::string MY_BINORMAL_ID("binormal");
+    return MY_BINORMAL_ID;
+  }
+
+  inline static const std::string& LAW_REFERENCE_ID()
+  {
+    static const std::string MY_LAW_REFERENCE_ID("law_reference");
+    return MY_LAW_REFERENCE_ID;
+  }
+
+  inline static const std::string& LAW_DEFINITION_ID()
+  {
+    static const std::string MY_LAW_DEFINITION_ID("law_definition");
+    return MY_LAW_DEFINITION_ID;
+  }
+
+  /// attribute name for creation method
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string METHOD_ATTR("CreationMethod");
+    return METHOD_ATTR;
+  }
+
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_PipeApprox::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_PipeApprox();
+
+private:
+  /// Load Naming data structure of the feature to the document.
+  void loadNamingDS(GeomAlgoAPI_PipeApprox& thePipeApproxAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBasis);
+
+};
+#endif
diff --git a/src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.cpp b/src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.cpp
new file mode 100644 (file)
index 0000000..a23b9ee
--- /dev/null
@@ -0,0 +1,460 @@
+// Copyright
+
+// File:        FeaturesPlugin_PipeApproxLaw.cpp
+
+//TODO: SORT ALL THE INCLUDES
+#include "FeaturesPlugin_PipeApproxLaw.h"
+
+#include <FeaturesPlugin_ParameterLaw.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Object.h>
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+//??#include "ParametersPlugin_Parameter.h"
+//??#include <SketchPlugin_SketchEntity.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+
+#include <sstream>
+
+namespace patch
+{
+       template < typename T > std::string to_string( const T& n )
+       {
+               std::ostringstream stm ;
+               stm << n ;
+               return stm.str() ;
+       }
+}
+
+
+static ListOfShape makeProfileList(AttributeSelectionListPtr aFacesSelectionList);
+
+
+//for splitting string
+std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+       std::stringstream ss(s);
+       std::string item;
+       while (std::getline(ss, item, delim)) {
+               elems.push_back(item);
+       }
+       return elems;
+}
+
+std::vector<std::string> split(const std::string &s, char delim) {
+       std::vector<std::string> elems;
+       split(s, delim, elems);
+       return elems;
+}
+
+
+//=================================================================================================
+FeaturesPlugin_PipeApproxLaw::FeaturesPlugin_PipeApproxLaw()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApproxLaw::initAttributes()
+{
+       mySelection = 
+               std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
+               PROFILE_ID(), ModelAPI_AttributeSelectionList::typeId()));
+       mySelection->setSelectionType("FACE");
+       mySelection->setImmutable(false);
+
+       data()->addAttribute(PATH_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+       data()->addAttribute(BINORMAL_ID(), ModelAPI_AttributeSelection::typeId());
+
+
+       myParameter = data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeSelectionList::typeId());
+       data()->addAttribute(NBSECT_ID(), ModelAPI_AttributeInteger::typeId());
+       data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
+       data()->addAttribute(FRENET_ID(), ModelAPI_AttributeBoolean::typeId());
+       data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApproxLaw::performSketchIteration()
+{
+       for(int i = 0; i < myNbLaws; i++){              
+               const std::string & theValue = patch::to_string(myIterationMOI[i][myCPT]); //it -> devient compteur sur le vect
+               FeaturePtr aIterationParamFeature = ModelAPI_Feature::feature(myVectResultParameterPtr[i]);
+               aIterationParamFeature->data()->string("expression")->setValue(theValue);
+       }
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApproxLaw::getParamLaws(GeomAlgoAPI_ParameterLaw& aParameterLawAlgo)
+{
+       ObjectPtr aFeatureObj = mySelection->owner();
+       DocumentPtr aDocument = aFeatureObj->document();
+
+       bool haveParam;
+
+       AttributeSelectionListPtr aLawsSelectionList = selectionList(VARIABLE_ID());
+       myNbLaws = aLawsSelectionList->size();
+
+       for(int i = 0; i < myNbLaws; i++){
+               AttributeSelectionPtr aFaceSel = aLawsSelectionList->value(i);
+               ObjectPtr aLawObj = aFaceSel->context();
+               FeaturePtr aLawFeature = ModelAPI_Feature::feature(aLawObj);
+
+               //check existence of the laws
+               haveParam = false;
+
+               //get the param, and the def and ref curves
+               std::string aParameterName = aLawFeature->data()->string(FeaturesPlugin_ParameterLaw::VARIABLE_ID())->value();
+
+               int anIndex2 = 0, aSize2 = aDocument->size(ModelAPI_ResultParameter::group());
+               ObjectPtr aParamObj = aDocument->object(ModelAPI_ResultParameter::group(), anIndex2);
+
+               while(anIndex2 < aSize2 && aParamObj->data()->name() != aParameterName){
+                       anIndex2++;
+                       aParamObj = aDocument->object(ModelAPI_ResultParameter::group(), anIndex2);
+               }
+               if(aParamObj->data()->name() == aParameterName)
+               {
+                       ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+                       if (aParam.get()){
+                               FeaturePtr aFeature = ModelAPI_Feature::feature(aParam);
+                               haveParam = (aFeature != myParameter->owner());
+                       }
+               }
+               ResultParameterPtr aParam;
+               if (haveParam) {
+                       aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+                       haveParam = aParam.get() != NULL;
+               }
+               if(!haveParam)
+               {
+                       break;
+               }else{
+                       myVectResultParameterPtr.push_back(aParam);
+
+                       bool isReverse = 
+                               aLawFeature->data()->boolean(FeaturesPlugin_ParameterLaw::REVERSE_ID())->value();
+                       std::shared_ptr<GeomAPI_Shape> aDef = 
+                               aLawFeature->data()->selection(FeaturesPlugin_ParameterLaw::LAW_DEFINITION_ID())->value();
+
+                       std::shared_ptr<GeomAPI_Shape> aRef = 
+                               aLawFeature->data()->selection(FeaturesPlugin_ParameterLaw::LAW_REFERENCE_ID())->value();
+
+                       std::vector<double> tempVec = aParameterLawAlgo.getVectorOfScalar(aDef, aRef, isReverse, myNbSections);
+                       myIterationMOI.insert(std::pair<int, std::vector<double>>(i, tempVec));
+               }
+       }
+}
+
+//=================================================================================================
+bool FeaturesPlugin_PipeApproxLaw::checkParamLaws()
+{
+       ObjectPtr aFeatureObj = mySelection->owner();
+       DocumentPtr aDocument = aFeatureObj->document();
+
+       bool res;
+
+       AttributeSelectionListPtr aLawsSelectionList = selectionList(VARIABLE_ID());
+       myNbLaws = aLawsSelectionList->size();
+
+       for(int i = 0; i < myNbLaws; i++){
+               AttributeSelectionPtr aFaceSel = aLawsSelectionList->value(i);
+
+               ObjectPtr aLawObj = aFaceSel->context();
+               FeaturePtr aLawFeature = ModelAPI_Feature::feature(aLawObj);
+               //check existence of the laws
+
+               res = false;
+
+               std::string aParameterName = aLawFeature->data()->string(FeaturesPlugin_ParameterLaw::VARIABLE_ID())->value();
+
+               int anIndex2 = 0, aSize2 = aDocument->size(ModelAPI_ResultParameter::group());
+               ObjectPtr aParamObj = aDocument->object(ModelAPI_ResultParameter::group(), anIndex2);
+
+               while(anIndex2 < aSize2 && aParamObj->data()->name() != aParameterName){
+                       anIndex2++;
+                       aParamObj = aDocument->object(ModelAPI_ResultParameter::group(), anIndex2);
+               }
+               if(aParamObj->data()->name() == aParameterName)
+               {
+                       ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+                       if (aParam.get()){
+                               FeaturePtr aFeature = ModelAPI_Feature::feature(aParam);
+
+                               res = (aFeature != myParameter->owner());
+                       }
+               }
+               ResultParameterPtr aParam;
+
+               if (res) {
+                       aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+
+                       res = aParam.get() != NULL;
+               }
+       }
+       return res;
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApproxLaw::execute()
+{
+       int cpt = 0;
+       if (!myIterationMOI.empty()) { // iteration is performed
+               // do the iteration
+               // get the updated sketch
+
+               AttributeSelectionPtr aUpdatedShapeSel = myIterationUpdatedFacesSelectionList->value(cpt);
+               std::shared_ptr<GeomAPI_Shape> aUpdatedShape = aUpdatedShapeSel->value();
+               myIterationLOS.push_back(aUpdatedShape);
+
+               myCPT--;
+
+
+               if (myCPT >= 0) {
+                       // set new param to update sketch
+                       performSketchIteration();
+                       return; // the execution will be called again with an updated sketch
+               } else {
+                       myIterationMOI.clear(); // finish the iteration
+               }
+       }
+
+       // Getting creation method.
+       std::string aCreationMethod = string(CREATION_METHOD())->value();
+
+       // Flags for reverse path
+       bool isReverse = boolean(REVERSE_ID())->value();
+
+       // Flags for min torsion
+       bool withFrenet = boolean(FRENET_ID())->value();
+
+       // Getting nb sections.
+       myNbSections = integer(NBSECT_ID())->value();
+
+
+       // Getting path.
+       AttributeSelectionPtr aPathSelection = selection(PATH_OBJECT_ID());
+       if(!aPathSelection.get()) {
+               setError("Error: Path selection is empty.");
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aPathShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aPathSelection->value());
+       if(!aPathShape.get()) {
+               // Probaply it is a construction.
+               aPathShape = aPathSelection->context()->shape();
+       }
+       if(!aPathShape.get() || aPathShape->isNull()) {
+               setError("Error: Path shape is null.");
+               return;
+       }
+
+       //Getting profile
+       ListOfShape aFacesList;
+       AttributeSelectionListPtr aFacesSelectionList = selectionList(PROFILE_ID());
+       for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
+               AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
+               std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
+               if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
+                       aFacesList.push_back(aFaceShape);
+               } else { // This may be the whole sketch result selected, check and get faces.
+                       ResultPtr aContext = aFaceSel->context();
+                       std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
+                       if(!aContextShape.get()) {
+                               static const std::string aContextError = "Error: The selection context is bad.";
+                               setError(aContextError);
+                               return;
+                       }
+                       ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+                       if(!aConstruction.get()) {
+                               static const std::string aFaceError = "Error: Can not find basis for extrusion.";
+                               setError(aFaceError);
+                               return;
+                       }
+                       int aFacesNum = aConstruction->facesNum();
+                       for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+                               aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+                               aFacesList.push_back(aFaceShape);
+                       }
+               }
+       }
+
+
+       // Getting Bi-Normal
+
+       std::shared_ptr<GeomAPI_Shape> aBiNormal;
+       if(aCreationMethod == "with binormal") {
+               AttributeSelectionPtr aBiNormalSelection = selection(BINORMAL_ID());
+               if(!aBiNormalSelection.get()) {
+                       setError("Error: Bi-Normal selection is empty.");
+                       return;
+               }
+               aBiNormal = std::dynamic_pointer_cast<GeomAPI_Shape>(aBiNormalSelection->value());
+               if(!aBiNormal.get()) {
+                       // Probably it is a construction.
+                       aBiNormal = aBiNormalSelection->context()->shape();
+               }
+               if(!aBiNormal.get() || aBiNormal->isNull()) {
+                       setError("Error: Bi-Normal shape is null.");
+                       return;
+               }
+       }
+
+       // Generating result for each shell and face.
+       int aResultIndex = 0;
+       //this is "fake" for loop
+       //we expect to only treat one face
+       //think I need the selectionlist to have access to sketch, not sure
+       for(ListOfShape::const_iterator anIter = aFacesList.cbegin(); anIter != aFacesList.cend(); anIter++) {
+               std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
+               GeomAlgoAPI_PipeApprox aPipeApproxLawAlgo = GeomAlgoAPI_PipeApprox();
+               GeomAlgoAPI_ParameterLaw aParameterLawAlgo = GeomAlgoAPI_ParameterLaw();
+
+               ObjectPtr aFeatureObj = mySelection->owner();
+               DocumentPtr aDocument = aFeatureObj->document();
+               if(checkParamLaws())
+               {
+                       if (myIterationLOS.empty()) { // starts the iteration
+                               myCPT = myNbSections - 1;
+                               getParamLaws(aParameterLawAlgo);
+                               myIterationUpdatedFacesSelectionList = aFeatureObj->data()->selectionList(PROFILE_ID());
+                               // init the iteration by first modification of the sketch
+                               performSketchIteration();
+                               return;
+                       } else {  // perform the algo on already computed contours in the previous iteration
+                               if(aCreationMethod == "simple"){
+                                       aPipeApproxLawAlgo = GeomAlgoAPI_PipeApprox(myIterationLOS, aPathShape, isReverse, myNbSections, withFrenet);
+                               }
+                               if(aCreationMethod == "with binormal"){
+                                       aPipeApproxLawAlgo = GeomAlgoAPI_PipeApprox(myIterationLOS, aPathShape, aBiNormal, isReverse, myNbSections/*, crossSections*/);
+                               }
+                               myIterationLOS.clear();
+                               myCPT = myNbSections - 1;
+                       }
+               }
+
+
+               if(!aPipeApproxLawAlgo.isDone()) {
+                       static const std::string aPrismAlgoError = "Error: Pipe algorithm failed.";
+                       setError(aPrismAlgoError);
+                       aResultIndex = 0;
+                       //break;
+               }
+               // Check if shape is valid
+               if(!aPipeApproxLawAlgo.shape().get() || aPipeApproxLawAlgo.shape()->isNull()) {
+                       static const std::string aShapeError = "Error: Resulting shape is Null.";
+                       setError(aShapeError);
+                       aResultIndex = 0;
+                       //break;
+               }
+               if(!aPipeApproxLawAlgo.isValid()) {
+                       std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
+                       setError(aPrismAlgoError);
+                       aResultIndex = 0;
+                       //break;
+               }
+
+               ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+               loadNamingDS(aPipeApproxLawAlgo, aResultBody, aBaseShape);
+               setResult(aResultBody, aResultIndex);
+               aResultIndex++;
+
+               cpt++;
+       }
+
+       removeResults(aResultIndex);
+
+}
+
+//=================================================================================================
+void FeaturesPlugin_PipeApproxLaw::loadNamingDS(GeomAlgoAPI_PipeApprox& thePipeApproxLawAlgo,
+       std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+       std::shared_ptr<GeomAPI_Shape> theBasis)
+{
+       //load result
+       theResultBody->storeGenerated(theBasis, thePipeApproxLawAlgo.shape());
+
+       std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = thePipeApproxLawAlgo.mapOfSubShapes();
+
+       //Insert lateral face : Face from Edge
+       const std::string aLatName = "LateralFace";
+       const int aLatTag = 1;
+       theResultBody->loadAndOrientGeneratedShapes(&thePipeApproxLawAlgo, theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
+
+       //Insert to faces
+       int aToFaceIndex = 1;
+       const std::string aToName = "ToFace";
+       int aToTag = 2;
+       const ListOfShape& aToFaces = thePipeApproxLawAlgo.toShapes();
+       for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
+               std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
+               if(aSubShapes->isBound(aToFace)) {
+                       aToFace = aSubShapes->find(aToFace);
+               }
+               std::ostringstream aStr;
+               aStr << aToName << "_" << aToFaceIndex++;
+               theResultBody->generated(aToFace, aStr.str(), aToTag++);
+       }
+
+       //Insert from faces
+       int aFromFaceIndex = 1;
+       const std::string aFromName = "FromFace";
+       int aFromTag = aToTag > 10000 ? aToTag : 10000;
+       const ListOfShape& aFromFaces = thePipeApproxLawAlgo.fromShapes();
+       for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
+               std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
+               if(aSubShapes->isBound(aFromFace)) {
+                       aFromFace = aSubShapes->find(aFromFace);
+               }
+               std::ostringstream aStr;
+               aStr << aFromName << "_" << aFromFaceIndex++;
+               theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
+       }
+}
+
+
+
+ListOfShape makeProfileList(AttributeSelectionListPtr aFacesSelectionList){
+       ListOfShape aFacesList;
+       for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
+               AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
+               std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
+               if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
+                       aFacesList.push_back(aFaceShape);
+               } else { // This may be the whole sketch result selected, check and get faces.
+                       ResultPtr aContext = aFaceSel->context();
+                       std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
+                       if(!aContextShape.get()) {
+                               static const std::string aContextError = "Error: The selection context is bad.";
+                               return aFacesList;
+                       }
+                       ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+                       if(!aConstruction.get()) {
+                               static const std::string aFaceError = "Error: Can not find basis for extrusion.";
+                               return aFacesList;
+                       }
+                       int aFacesNum = aConstruction->facesNum();
+                       for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+                               aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+                               aFacesList.push_back(aFaceShape);
+                       }
+               }
+       }
+
+       return aFacesList;
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.h b/src/FeaturesPlugin/FeaturesPlugin_PipeApproxLaw.h
new file mode 100644 (file)
index 0000000..7c57517
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright
+
+// File:        FeaturesPlugin_PipeApproxLaw.h
+
+
+#ifndef FeaturesPlugin_PipeApproxLaw_H_
+#define FeaturesPlugin_PipeApproxLaw_H_
+
+#include <FeaturesPlugin.h>
+
+#include <GeomAlgoAPI_PipeApprox.h>
+#include <GeomAlgoAPI_ParameterLaw.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <memory>
+#include <list>
+#include <vector>
+#include <map>
+#include <string> 
+
+class GeomAPI_Shape;
+class ModelAPI_ResultBody;
+
+/** \class FeaturesPlugin_Pipe
+ *  \ingroup Plugins
+ *  \brief Feature for creation of Pipe from the planar face.
+ *  Pipe 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_PipeApproxLaw : public ModelAPI_Feature
+{
+ public:
+  /// Pipe kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_PipeApproxLaw_ID("PipeApproxLaw");
+    return MY_PipeApproxLaw_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& PROFILE_ID()
+  {
+    static const std::string MY_PROFILE_LIST_ID("profile");
+    return MY_PROFILE_LIST_ID;
+  }
+
+  /// Attribute name of an Pipe path.
+  inline static const std::string& PATH_OBJECT_ID()
+  {
+    static const std::string MY_PATH_ID("path_object");
+    return MY_PATH_ID;
+  }
+
+  /// Attribute name of Bi-Normal.
+  inline static const std::string& BINORMAL_ID()
+  {
+    static const std::string MY_BINORMAL_ID("binormal");
+    return MY_BINORMAL_ID;
+  }
+
+  /// Attribute name of ParmLaws
+  inline static const std::string& VARIABLE_ID()
+  {
+    static const std::string MY_VARIABLE_ID("Parameter_laws");
+    return MY_VARIABLE_ID;
+  }
+
+  /// Attribute name of nb cross-sections
+  inline static const std::string& NBSECT_ID()
+  {
+    static const std::string MY_NBSECT_ID("nb_sect");
+    return MY_NBSECT_ID;
+  }
+
+  /// attribute name of flag of minimizetorsion
+  inline static const std::string& FRENET_ID()
+  {
+    static const std::string MY_FRENET_ID("use_Frenet");
+    return MY_FRENET_ID;
+  }
+  
+  /// attribute name of flag of reverse direction
+  inline static const std::string& REVERSE_ID()
+  {
+    static const std::string MY_REVERSE_ID("reverse_direction");
+    return MY_REVERSE_ID;
+  }
+
+  /// attribute name for creation method
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string METHOD_ATTR("CreationMethod");
+    return METHOD_ATTR;
+  }
+
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_PipeApproxLaw::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_PipeApproxLaw();
+
+private:
+  /// Load Naming data structure of the feature to the document.
+  void loadNamingDS(GeomAlgoAPI_PipeApprox& thePipeApproxLawAlgo,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theBasis);
+
+  /// does the update of sketch that will call "execution" of this feature
+  void performSketchIteration();
+
+  bool checkParamLaws();
+  void FeaturesPlugin_PipeApproxLaw::getParamLaws(GeomAlgoAPI_ParameterLaw& aParameterLawAlgo);
+
+  AttributeSelectionListPtr mySelection;
+  AttributePtr myParameter;
+
+  /// fields needed for iteration of updated sketch
+  std::map<int, std::vector<double>> myIterationMOI; ///< empty means iteration is not started
+
+  std::vector<ResultParameterPtr> myVectResultParameterPtr;
+  
+  AttributeSelectionListPtr myIterationUpdatedFacesSelectionList;
+  ListOfShape myIterationLOS;
+  
+  int myCPT;
+  int myNbLaws;
+  int myNbSections;
+};
+#endif
index 54b0021f0a8bdaf51151f27e9aec857875a20381..0f210e69b34fdaba505a394108dc62c52ef5b8fc 100644 (file)
 #include <FeaturesPlugin_ValidatorTransform.h>
 #include <FeaturesPlugin_Validators.h>
 
+#include <FeaturesPlugin_PipeApprox.h>
+#include <FeaturesPlugin_PipeApproxLaw.h>
+#include <FeaturesPlugin_ParameterLaw.h>
+
 #include <ModelAPI_Session.h>
 
 #include <string>
@@ -60,6 +64,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorUnionSelection);
   aFactory->registerValidator("FeaturesPlugin_ValidatorUnionArguments",
                               new FeaturesPlugin_ValidatorUnionArguments);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorParameterLaw",
+                                 new FeaturesPlugin_ValidatorParameterLaw);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
@@ -99,6 +105,12 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_RemoveSubShapes);
   } else if (theFeatureID == FeaturesPlugin_Union::ID()) {
     return FeaturePtr(new FeaturesPlugin_Union);
+  } else if (theFeatureID == FeaturesPlugin_ParameterLaw::ID()) {
+    return FeaturePtr(new FeaturesPlugin_ParameterLaw);
+  }else if (theFeatureID == FeaturesPlugin_PipeApproxLaw::ID()) {
+    return FeaturePtr(new FeaturesPlugin_PipeApproxLaw);
+  }else if (theFeatureID == FeaturesPlugin_PipeApprox::ID()) {
+    return FeaturePtr(new FeaturesPlugin_PipeApprox);
   }
 
   // feature of such kind is not found
index c77f516b64c14c8b09fe732d2efa850e360139ec..b0b4cba2d1a867df2005a57ea41338c066555361 100644 (file)
@@ -782,3 +782,49 @@ bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeat
 {
   return false;
 }
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorParameterLaw::isValid(const AttributePtr& theAttribute,
+                                                        const std::list<std::string>& theArguments,
+                                                        Events_InfoMessage& theError) const
+{
+       //SEEMS THIS DOES NOTHING SPECIAL!!
+  bool isLawValid = true;
+  //if(theArguments.empty()) {
+  //  theError = "Error: Validator parameters is empty.";
+  //  return false;
+  //}
+  std::string anAttributeType = theAttribute->attributeType();
+  std::string anAttirbuteID = theAttribute->id();
+  if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+    AttributeSelectionListPtr aSelectionListAttr = 
+                      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+    // all context objects should be sketch entities
+    for (int i = 0, aSize = aSelectionListAttr->size(); i < aSize ; i++) {
+      AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
+      ObjectPtr anObject = aSelectAttr->context();
+      if (!anObject.get())
+        isLawValid = false;
+      else {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+        isLawValid = true;
+      }
+    }
+  }
+  if (anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+    AttributeSelectionPtr aSelectAttr = 
+                      std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+    ObjectPtr anObject = aSelectAttr->context();
+    // a context of the selection attribute is a feature result. It can be a case when the result
+    // of the feature is null, e.g. the feature is modified and has not been executed yet.
+    // The validator returns an invalid result here. The case is an extrusion built on a sketch
+    // feature. A new sketch element creation leads to an empty result.
+    if (!anObject.get())
+      isLawValid = false;
+    else {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+         isLawValid = true;
+       }
+  }
+  return isLawValid;
+}
\ No newline at end of file
index ce3fe042e3ad7186f09a797555a2c250aa6275da..4f853042d8bc6eedaed3b9860d5f90ffd7ba85f4 100644 (file)
@@ -202,4 +202,15 @@ class FeaturesPlugin_ValidatorUnionArguments: public ModelAPI_FeatureValidator
   virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
 };
 
+class FeaturesPlugin_ValidatorParameterLaw: public ModelAPI_AttributeValidator
+{
+public:
+  //! \return true if attribute has selection type listed in the parameter arguments.
+  //! \param[in] theAttribute the checked attribute.
+  //! \param[in] theArguments arguments of the attribute.
+  //! \param[out] theError error message.
+   virtual bool isValid(const AttributePtr& theAttribute,
+                        const std::list<std::string>& theArguments,
+                        Events_InfoMessage& theError) const;
+};
 #endif
diff --git a/src/FeaturesPlugin/parameterlaw_widget.xml b/src/FeaturesPlugin/parameterlaw_widget.xml
new file mode 100644 (file)
index 0000000..d92e464
--- /dev/null
@@ -0,0 +1,28 @@
+<source>
+  <toolbox id="CreationMethod">
+    <box id="parameter law" title="" icon="">
+      <stringvalue id="variable" label="Name" icon=":pictures/expression.png" placeholder="Please input the parameter name">
+        <!--validator id="Parameters_VariableValidator"/-->
+      </stringvalue>
+      <shape_selector id="law_reference"
+          label="Select a reference line"
+          icon=""
+          tooltip="By convention, create a line from Left to Right"
+          shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+      <shape_selector id="law_definition"
+                label="Select a definition curve"
+                icon=""
+                tooltip=""
+                shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="edge"/>
+      </shape_selector>
+      <boolvalue id="reverse_direction"
+          label="Reverse"
+          default="false"
+          tooltip="Reverse path direction"/>
+    
+  </box>
+  </toolbox>
+</source>
\ No newline at end of file
diff --git a/src/FeaturesPlugin/pipeapprox_widget.xml b/src/FeaturesPlugin/pipeapprox_widget.xml
new file mode 100644 (file)
index 0000000..58b401f
--- /dev/null
@@ -0,0 +1,74 @@
+<!-- Copyright -->
+
+<source>
+  <toolbox id="CreationMethod">
+    <box id="simple" title="Simple pipeApprox by objects and path" icon="">
+      <multi_selector id="profile"
+                      label="Select the profile"
+                      icon=":icons/sketch.png"
+                      tooltip="Select the profile"
+                      type_choice="faces">
+        <validator id="FeaturesPlugin_ValidatorBaseForGeneration" parameters="face"/>
+      </multi_selector>
+      <shape_selector id="path_object"
+                      label="Select a path"
+                      icon=""
+                      tooltip="Select edges for a path"
+                      shape_types="edge wire">
+        <validator id="FeaturesPlugin_ValidatorPipePath"/>
+      </shape_selector>
+  </box>
+    <box id="with law" title="" icon="">
+      <shape_selector id="law_reference"
+          label="Select a reference line"
+          icon=""
+          tooltip=""
+          shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+      <shape_selector id="law_definition"
+                label="Select a definition curve"
+                icon=""
+                tooltip=""
+                shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="edge"/>
+      </shape_selector>
+      <multi_selector id="profile"
+                      label="Select the profile"
+                      icon=":icons/sketch.png"
+                      tooltip="Select the profile"
+                      type_choice="faces">
+        <validator id="FeaturesPlugin_ValidatorBaseForGeneration" parameters="face"/>
+      </multi_selector>
+      <shape_selector id="path_object"
+                label="Select a path"
+                icon=""
+                tooltip="Select edges for a path"
+                shape_types="edge">
+        <validator id="FeaturesPlugin_ValidatorPipePath"/>
+      </shape_selector>
+  </box>
+    <box id="binormal" title="Pipe by objects, path and Bi-Normal" icon="">
+      <shape_selector id="binormal"
+                      label="Bi-Normal:"
+                      tooltip="Select an edge for Bi-Normal"
+                      shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+      <multi_selector id="profile"
+                      label="Select the profile"
+                      icon=":icons/sketch.png"
+                      tooltip="Select the profile"
+                      type_choice="faces">
+        <validator id="FeaturesPlugin_ValidatorBaseForGeneration" parameters="face"/>
+      </multi_selector>
+      <shape_selector id="path_object"
+                      label="Select a path"
+                      icon=""
+                      tooltip="Select edges for a path"
+                      shape_types="edge wire">
+        <validator id="FeaturesPlugin_ValidatorPipePath"/>
+      </shape_selector>
+    </box>
+  </toolbox>
+</source>
diff --git a/src/FeaturesPlugin/pipeapproxlaw_widget.xml b/src/FeaturesPlugin/pipeapproxlaw_widget.xml
new file mode 100644 (file)
index 0000000..feb2bd4
--- /dev/null
@@ -0,0 +1,90 @@
+<source>
+  <toolbox id="CreationMethod">
+    <box id="simple" title="" icon="icons/Features/pipe_locations_32x32.png">
+      <multi_selector id="profile"
+                      label="Select the profile"
+                      icon=":icons/sketch.png"
+                      tooltip="Select the profile"
+                      type_choice="faces">
+        <validator id="FeaturesPlugin_ValidatorBaseForGeneration" parameters="face"/>
+      </multi_selector>
+      <!-- shape_selector id="path_object"
+                      label="Path object:"
+                      tooltip="Select an edge or wire for path"
+                      shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="edge"/>
+      </shape_selector> -->
+      <shape_selector id="path_object"
+                label="Select a path"
+                icon=""
+                tooltip="Select edges for a path"
+                shape_types="edge wire">
+        <validator id="FeaturesPlugin_ValidatorPipePath"/>
+      </shape_selector>
+      <multi_selector id="Parameter_laws"
+                label="Select the laws"
+                icon=":icons/sketch.png"
+                tooltip="Select the laws"
+                type_choice="Objects">
+        <validator id="FeaturesPlugin_ValidatorParameterLaw"/>
+      </multi_selector>
+      <integervalue
+          id="nb_sect"
+          label="Number of sections for approx"
+          default="50"
+          min ="2"
+          icon=""
+          tooltip="Please input the number of sections for approx, by default 50">
+      </integervalue>
+      <boolvalue id="use_Frenet"
+          label="use frenet trihedron"
+          default="false"
+          tooltip="Use Frenet (by default try to minimize torsion)"/>
+      <boolvalue id="reverse_direction"
+                label="Reverse"
+                default="false"
+                tooltip="Reverse path direction"/>
+    </box>
+    <box id="with binormal" title="" icon="icons/Features/pipe_binormal_32x32.png">
+      <multi_selector id="profile"
+                      label="Select the profile"
+                      icon=":icons/sketch.png"
+                      tooltip="Select the profile"
+                      type_choice="faces">
+        <validator id="FeaturesPlugin_ValidatorBaseForGeneration" parameters="face"/>
+      </multi_selector>
+      <shape_selector id="path_object"
+                      label="Path object:"
+                      tooltip="Select an edge or wire for path"
+                      shape_types="edge wire">
+        <validator id="FeaturesPlugin_ValidatorPipePath"/>
+      </shape_selector>
+      <shape_selector id="binormal"
+                label="Bi-Normal:"
+                tooltip="Select an edge for Bi-Normal"
+                shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+      </shape_selector>
+      <multi_selector id="Parameter_laws"
+                label="Select the laws"
+                icon=":icons/sketch.png"
+                tooltip="Select the laws"
+                type_choice="Objects">
+        <validator id="FeaturesPlugin_ValidatorParameterLaw"/>
+      </multi_selector>
+      <integervalue
+          id="nb_sect"
+          label="Number of sections for approx"
+          default="50"
+          min ="2"
+          icon=""
+          tooltip="Please input the number of sections for approx, by default 50">
+      </integervalue>
+      <boolvalue id="reverse_direction"
+                label="Reverse"
+                default="false"
+                tooltip="Reverse path direction"/>
+    
+  </box>
+  </toolbox>
+</source>
\ No newline at end of file
index 6a5cba33d306b83fdd3032f5513a1e6af3eacf4e..61ad6ecb000c2a8a361acf203caa14aaa6a5dcb6 100644 (file)
       <feature id="Pipe" title="Pipe" tooltip="Generates extrusion along a path" icon="icons/Features/pipe.png">
         <source path="pipe_widget.xml"/>
       </feature>
+    </group>
+       <group id="Parametric Pipe">
+      <feature id="PipeApprox" title="PipeApprox" tooltip="Create a Pipe by approx" icon="icons/Features/pipe.png">
+        <source path="pipeapprox_widget.xml"/>
+      </feature>
+      <feature id="ParameterLaw" title="ParameterLaw" tooltip="Create a ParameterLaw" icon="">
+        <source path="parameterlaw_widget.xml"/>
+      </feature>
+      <feature id="PipeApproxLaw" title="PipeApproxLaw" tooltip="Create a Pipe by approx with law" icon="icons/Features/pipe_locations_32x32.png">
+        <source path="pipeapproxlaw_widget.xml"/>
+      </feature>
     </group>
     <group id="Boolean">
       <feature id="Boolean" title="Boolean" tooltip="Perform boolean operations with solids" icon="icons/Features/cut.png"
index 7d05409ac4146915be14970d60eed8df079296a8..a64feb4f1efff42c6a5ad63b32f9b2ab97dd3ace 100644 (file)
@@ -41,6 +41,8 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_ShapeBuilder.h
     GeomAlgoAPI_XAOExport.h
     GeomAlgoAPI_XAOImport.h
+    GeomAlgoAPI_PipeApprox.h
+    GeomAlgoAPI_ParameterLaw.h
 )
 
 SET(PROJECT_SOURCES
@@ -78,6 +80,8 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_ShapeBuilder.cpp
     GeomAlgoAPI_XAOExport.cpp
     GeomAlgoAPI_XAOImport.cpp
+    GeomAlgoAPI_PipeApprox.cpp
+    GeomAlgoAPI_ParameterLaw.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.cpp
new file mode 100644 (file)
index 0000000..c0c7c14
--- /dev/null
@@ -0,0 +1,314 @@
+// Copyright
+
+// File:        GeomAlgoAPI_ParameterLaw.cpp
+
+
+#include "GeomAlgoAPI_ParameterLaw.h"
+
+//trier les include un jour...
+//#include <GeomAPI_Face.h>
+#include <math.h>   
+#include <GeomAPI_Lin.h>
+#include <Geom_Line.hxx>
+#include <gp_Lin.hxx>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAlgoAPI_DFLoader.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAlgoAPI_Cut.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepOffsetAPI_MakePipe.hxx>
+#include <GeomFill_Trihedron.hxx>
+#include <BRepOffsetAPI_MakePipeShell.hxx>
+#include <BRepGProp.hxx>
+#include <Geom_Plane.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <gp_Pln.hxx>
+#include <GProp_GProps.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <GProp_PGProps.hxx>
+#include <Extrema_ExtPElC.hxx>
+#include "GeomAPI.h"
+#include "GeomAPI_Edge.h"
+#include "GeomAPI_Wire.h"
+#include "GeomAPI_Pnt.h"
+#include "GeomAPI_Dir.h"
+#include "GeomAPI_Ax3.h"
+#include "GeomAPI_Curve.h"
+
+#include <GeomAPI.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_BezierCurve.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <GeomAPI_IntCS.hxx>
+#include <BRepAlgo_NormalProjection.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
+#include <BRepAdaptor_HCompCurve.hxx>
+#include <BRepAdaptor_HCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <BRepOffsetAPI_ThruSections.hxx>
+#include "GeomAlgoAPI_Placement.h"
+#include <BRepBuilderAPI_Transform.hxx>
+#include "GeomAlgoAPI_MakeShape.h"
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+
+//#define NB_SECT 50
+
+/// \return solid created from face or shell.
+static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
+
+//=================================================================================================
+GeomAlgoAPI_ParameterLaw::GeomAlgoAPI_ParameterLaw()
+{
+}
+
+//=================================================================================================
+GeomAlgoAPI_ParameterLaw::GeomAlgoAPI_ParameterLaw(std::shared_ptr<GeomAPI_Shape> theDefShape,
+       std::shared_ptr<GeomAPI_Shape>   theRefShape,
+       bool isReverse)
+{
+       build(theDefShape, theRefShape, isReverse);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_ParameterLaw::build(const std::shared_ptr<GeomAPI_Shape>& theDefShape,
+       const std::shared_ptr<GeomAPI_Shape>&   theRefShape,
+       const bool isReverse)
+{
+       if(!theDefShape || !theRefShape) {
+               return;
+       }
+
+       // Getting Def
+       TopoDS_Edge aDefEdge;
+       if(theDefShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aDefEdge = TopoDS::Edge(theDefShape->impl<TopoDS_Shape>());
+       }
+       // Getting Ref
+       TopoDS_Edge aRefEdge;
+       if(theRefShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aRefEdge = TopoDS::Edge(theRefShape->impl<TopoDS_Shape>());
+       }
+
+
+       //COMPUTE RESULT
+       TopoDS_Shape aResult;
+
+       double defFirst, defLast, refFirst, refLast;
+       Handle(Geom_Curve) aDefCurve = BRep_Tool::Curve(aDefEdge, defFirst, defLast);
+       if(isReverse)
+       {
+               double aTemp = defFirst;
+               defFirst = defLast;
+               defLast = aTemp;
+       }
+
+       //recover Ref line
+       Handle(Geom_Curve) aRefCurve = BRep_Tool::Curve(aRefEdge, refFirst, refLast);
+       GeomAdaptor_Curve aRefAdaptorCurve = GeomAdaptor_Curve(aRefCurve);
+
+       gp_Pnt rFP, rLP;
+       gp_XYZ rF, rL;
+       aRefCurve->D0(refFirst, rFP);
+       aRefCurve->D0(refLast, rLP);
+       rF = rFP.XYZ();
+       rL = rLP.XYZ();
+       rL.Subtract(rF);
+       gp_Lin aRefLin = gp_Lin(rFP, rL);
+       refFirst = aRefAdaptorCurve.FirstParameter();
+       refLast = aRefAdaptorCurve.LastParameter();
+
+       gp_Pnt DF;
+       aDefCurve->D0(defFirst, DF);
+
+
+       //to store edges for the final result
+       BRepBuilderAPI_MakeEdge mkEdge;
+       TopTools_ListOfShape aEL;
+
+       //project First Point of the def curve on the ref line
+       // to get the translation vector
+       double Tol = 1.0e-10;
+       Extrema_ExtPElC aProjDF = Extrema_ExtPElC(DF, aRefLin, Tol, refFirst, refLast);
+       int nbDMin = aProjDF.NbExt();
+       nbDMin++;
+       int k = 1;
+       while(k < nbDMin && !aProjDF.IsMin(k))
+       {
+               k++;
+       }
+
+       Extrema_POnCurv DFPOC = aProjDF.Point(k);
+       gp_Pnt DFP = DFPOC.Value();
+
+       //get translation vector
+       // and make the translation transformation
+       // then do the transformation and recover curve.
+       gp_Vec aTransVec = rF - DFP.XYZ();
+       gp_Trsf aTrans = gp_Trsf();
+       aTrans.SetTranslation(aTransVec);
+
+       TopoDS_Edge aTransDefEdge;
+       BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aDefEdge, aTrans, false);
+       if(aBuilder) {
+               if(aBuilder->IsDone()) {
+                       aTransDefEdge = TopoDS::Edge(aBuilder->Shape());
+               }
+       }
+
+       aEL.Append(aTransDefEdge);
+       double tdFirst, tdLast;
+       Handle(Geom_Curve) aTransDefCurve = BRep_Tool::Curve(aTransDefEdge, tdFirst, tdLast);
+       if(isReverse)
+       {
+               double aTemp = tdFirst;
+               tdFirst = tdLast;
+               tdLast = aTemp;
+       }
+
+       //now project last point of the transDefEdge
+       // then make the needed edges for final result
+       gp_Pnt TDF, TDL;
+       aTransDefCurve->D0(tdLast, TDL);
+       aTransDefCurve->D0(tdFirst, TDF);
+       Extrema_ExtPElC aProjDL = Extrema_ExtPElC(TDL, aRefLin, Tol, refFirst, refLast);
+       nbDMin = aProjDF.NbExt();
+       nbDMin++;
+       k = 1;
+       while(k < nbDMin && !aProjDF.IsMin(k))
+       {
+               k++;
+       }
+       Extrema_POnCurv DLPOC = aProjDL.Point(k);
+       gp_Pnt DLP = DLPOC.Value();
+
+       mkEdge = BRepBuilderAPI_MakeEdge(rFP, DLP);
+       if(mkEdge.IsDone())
+               aEL.Append(mkEdge.Edge());
+       mkEdge = BRepBuilderAPI_MakeEdge(DLP, TDL);
+       if(mkEdge.IsDone())
+               aEL.Append(mkEdge.Edge());
+       mkEdge = BRepBuilderAPI_MakeEdge(TDF, rFP);
+       if(mkEdge.IsDone())
+               aEL.Append(mkEdge.Edge());
+
+       BRepBuilderAPI_MakeWire mkWire;
+       mkWire.Add(aEL);
+       BRepBuilderAPI_MakeFace mkFace;
+       if(mkWire.IsDone())
+               mkFace = BRepBuilderAPI_MakeFace(mkWire.Wire());
+       if(mkFace.IsDone())
+               aResult = mkFace.Face();
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+
+
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+}
+
+
+
+//=================================================================================================
+std::vector<double> GeomAlgoAPI_ParameterLaw::getVectorOfScalar(const std::shared_ptr<GeomAPI_Shape>&   theDef,
+       const std::shared_ptr<GeomAPI_Shape>&   theRef,
+       const bool isReverse,
+       const int nbSect)
+{
+       std::vector<double> result;
+
+       // Getting law
+       // DEF
+       TopoDS_Edge aDefEdge;
+       if(theDef->shapeType() == GeomAPI_Shape::EDGE) {
+               aDefEdge = TopoDS::Edge(theDef->impl<TopoDS_Shape>());
+       }
+       // REF
+       TopoDS_Edge aRefEdge;
+       if(theRef->shapeType() == GeomAPI_Shape::EDGE) {
+               aRefEdge = TopoDS::Edge(theRef->impl<TopoDS_Shape>());
+       }
+
+       double d, dFirst, dLast, rFirst, rLast;
+
+       //recover Def curve
+       Handle(Geom_Curve) aDefCurve = BRep_Tool::Curve(aDefEdge, dFirst, dLast);
+       if(isReverse)
+       {
+               //aPathCurve = aPathCurve->Reversed();
+               double aTemp = dFirst;
+               dFirst = dLast;
+               dLast = aTemp;
+       }
+       d = dFirst;
+       const double dStep = abs(dLast - dFirst) / (nbSect - 1);
+
+       double coeffReverse = 1.0;
+       if(isReverse)
+       {
+               coeffReverse = -1.0;
+       }
+
+       //recover Ref line
+       Handle(Geom_Curve) aRefCurve = BRep_Tool::Curve(aRefEdge, rFirst, rLast);
+       GeomAdaptor_Curve aRefAdaptorCurve = GeomAdaptor_Curve(aRefCurve);
+
+       gp_Pnt rFP, rLP;
+       gp_XYZ rF, rL;
+       aRefCurve->D0(rFirst, rFP);
+       aRefCurve->D0(rLast, rLP);
+       rF = rFP.XYZ();
+       rL = rLP.XYZ();
+       rL.Subtract(rF);
+       gp_Lin aRefLin = gp_Lin(rFP, rL);
+       rFirst = aRefAdaptorCurve.FirstParameter();
+       rLast = aRefAdaptorCurve.LastParameter();
+
+       gp_Pnt D;
+
+       for (int i = 0; i < nbSect; ++i)
+       {       
+               //get value for param
+               //will calculate from law
+
+               aDefCurve->D0(d, D);
+               double Tol = 1.0e-10;
+               Extrema_ExtPElC aCalcD = Extrema_ExtPElC(D, aRefLin, Tol, rFirst, rLast);
+               int nbDMin = aCalcD.NbExt();
+               nbDMin++;
+               int k = 1;
+               while(k < nbDMin && !aCalcD.IsMin(k))
+               {
+                       k++;
+               }
+               double ii = aCalcD.SquareDistance(k);
+               ii = sqrt(ii);
+               result.push_back(ii);
+
+               d+= (coeffReverse*dStep);
+       }
+
+       return result;
+}
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.h b/src/GeomAlgoAPI/GeomAlgoAPI_ParameterLaw.h
new file mode 100644 (file)
index 0000000..6e9c6d2
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright
+
+// File:        GeomAlgoAPI_ParameterLaw.h
+// Created:     
+// Author:      
+
+#ifndef GeomAlgoAPI_ParameterLaw_H_
+#define GeomAlgoAPI_ParameterLaw_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeSweep.h>
+#include <ModelAPI_Feature.h>
+#include <GeomAPI_Face.h>
+#include <memory>
+#include <list>
+#include <vector>
+
+
+class GeomAlgoAPI_ParameterLaw : public GeomAlgoAPI_MakeSweep
+{
+public:
+
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_ParameterLaw();
+
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_ParameterLaw(std::shared_ptr<GeomAPI_Shape> theDefShape,
+                                            std::shared_ptr<GeomAPI_Shape>   theRefShape,
+                                                                                       bool isReverse);
+
+  GEOMALGOAPI_EXPORT std::vector<double> getVectorOfScalar(const std::shared_ptr<GeomAPI_Shape>&   theDef,
+       const std::shared_ptr<GeomAPI_Shape>&   theRef,
+       const bool isReverse,
+       const int nbSect);
+
+private:
+  /// Builds resulting shape.
+  void build(const std::shared_ptr<GeomAPI_Shape>& theDef,
+             const std::shared_ptr<GeomAPI_Shape>&   theRef,
+                        const bool isReverse);
+};
+#endif
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.cpp
new file mode 100644 (file)
index 0000000..05d4bce
--- /dev/null
@@ -0,0 +1,1107 @@
+// Copyright
+
+// File:        GeomAlgoAPI_PipeApprox.cpp
+
+
+#include "GeomAlgoAPI_PipeApprox.h"
+
+//trier les include un jour...
+//#include <GeomAPI_Face.h>
+#include <math.h>   
+#include <GeomAPI_Lin.h>
+#include <Geom_Line.hxx>
+#include <gp_Lin.hxx>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAlgoAPI_DFLoader.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include "GeomConvert_ApproxCurve.hxx"
+#include "Geom_BSplineCurve.hxx"
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepAlgoAPI_Cut.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepOffsetAPI_MakePipe.hxx>
+#include <GeomFill_Trihedron.hxx>
+#include <BRepOffsetAPI_MakePipeShell.hxx>
+#include <BRepGProp.hxx>
+#include <Geom_Plane.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <gp_Pln.hxx>
+#include <GProp_GProps.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <GProp_PGProps.hxx>
+#include <Extrema_ExtPElC.hxx>
+#include "GeomAPI.h"
+#include "GeomAPI_Edge.h"
+#include "GeomAPI_Wire.h"
+#include "GeomAPI_Pnt.h"
+#include "GeomAPI_Dir.h"
+#include "GeomAPI_Ax3.h"
+#include "GeomAPI_Curve.h"
+
+#include <GeomAPI.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_BezierCurve.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <GeomAPI_IntCS.hxx>
+#include <BRepAlgo_NormalProjection.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
+#include <Adaptor3d_Curve.hxx>
+#include <BRepAdaptor_HCompCurve.hxx>
+#include <BRepAdaptor_HCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <BRepOffsetAPI_ThruSections.hxx>
+#include "GeomAlgoAPI_Placement.h"
+#include <BRepBuilderAPI_Transform.hxx>
+#include "GeomAlgoAPI_MakeShape.h"
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+
+#include <TopAbs_Orientation.hxx>
+
+//the define are only for the pipe not using ParamLaws
+#define THRUSECT
+#define NB_SECT 50
+
+//based on the GeomAlgoAPI_Revolution
+
+/// \return solid created from face or shell.
+static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
+
+/// to make wire from a face after transformation, to use in thruSections
+static TopoDS_Wire makeWireFromTransf(const TopoDS_Shape &theSourceShape,
+       gp_Trsf  theTrsf);
+
+//=================================================================================================
+// Constructors
+//=================================================================================================
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox()
+{
+}
+
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+       std::shared_ptr<GeomAPI_Shape>   thePathShape)
+{
+       build(theProfileShape, thePathShape);
+}
+
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+       std::shared_ptr<GeomAPI_Shape>   thePathShape,
+       std::shared_ptr<GeomAPI_Shape>  theBiNormal)
+{
+       build(theProfileShape, thePathShape, theBiNormal);
+}
+
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+       std::shared_ptr<GeomAPI_Shape>   thePathShape,
+       std::shared_ptr<GeomAPI_Shape>   theDef,
+       std::shared_ptr<GeomAPI_Shape>   theRef)
+{
+       build(theProfileShape, thePathShape, theDef, theRef);
+}
+
+
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox(ListOfShape theProfileShapeList,
+       std::shared_ptr<GeomAPI_Shape>   thePath,
+       bool isReverse,
+       int nbSect,
+       bool withFrenet)
+{
+       build(theProfileShapeList, thePath, isReverse, nbSect, withFrenet);
+}
+
+//=================================================================================================
+GeomAlgoAPI_PipeApprox::GeomAlgoAPI_PipeApprox(ListOfShape theProfileShapeList,
+       std::shared_ptr<GeomAPI_Shape>   thePath,
+       std::shared_ptr<GeomAPI_Shape>   theBinormal,
+       bool isReverse,
+       int nbSect)
+{
+       build(theProfileShapeList, thePath, theBinormal, isReverse, nbSect);
+}
+
+
+//=================================================================================================
+// BUILD() when doing simple pipe with ThruSect
+//=================================================================================================
+
+//=================================================================================================
+void GeomAlgoAPI_PipeApprox::build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+       const std::shared_ptr<GeomAPI_Shape>&   thePathShape)
+{
+       if(!theProfileShape || !thePathShape) {
+               return;
+       }
+
+       // Getting profile.
+       TopoDS_Face aProfileFace = TopoDS::Face(theProfileShape->impl<TopoDS_Shape>());
+
+       // Getting path
+       const TopoDS_Shape& aPathShape = thePathShape->impl<TopoDS_Shape>();
+       TopoDS_Edge aPathEdge;
+       if(thePathShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aPathEdge = TopoDS::Edge(thePathShape->impl<TopoDS_Shape>());
+       }
+
+       //COMPUTE RESULT
+       TopoDS_Shape aResult;
+       double u, aFirst, aLast;
+
+       //recover curve
+       aPathEdge.Oriented(TopAbs_FORWARD );
+       Handle(Geom_Curve) aPathCurve = BRep_Tool::Curve(aPathEdge, aFirst, aLast);
+
+       u = aFirst;
+       const double uStep = (aLast - aFirst) / (NB_SECT - 1);
+
+#ifdef THRUSECT
+       const Standard_Boolean isSolid = Standard_True;
+       const Standard_Boolean isRuled = Standard_False;
+       const Standard_Real    pres3d = 1.0e-02;
+
+       //building thrusection algo)
+       BRepOffsetAPI_ThruSections* aGenerator = new BRepOffsetAPI_ThruSections(isSolid, isRuled, pres3d);
+       if(!aGenerator) {
+               return;
+       }
+       aGenerator->SetSmoothing(Standard_True);
+       aGenerator->SetMaxDegree(5);
+       aGenerator->CheckCompatibility(Standard_False);
+#else
+       std::shared_ptr<GeomAPI_Shape> aCompoundResult;
+       std::list<std::shared_ptr<GeomAPI_Shape> > aCompoundResultList;
+#endif
+
+       //iterating on sections
+       TopoDS_Wire aWire;
+       gp_Trsf aTrsf = gp_Trsf();
+       gp_Pnt P;
+       gp_Vec T, N, Vx;
+
+       aPathCurve->D2(u, P, T, N);
+       Vx = T ^ N; //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+       Vx = Vx ^ T;
+
+       gp_Ax3 gp_Ax3_0(P, T, Vx);
+
+       for (int i = 0; i < NB_SECT; ++i)
+       {       
+               u += uStep;
+               aPathCurve->D2(u, P, T, N);
+               Vx = T ^ N;
+               Vx = Vx ^ T;
+
+               aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+
+               aWire = makeWireFromTransf(aProfileFace, aTrsf);
+
+
+               // Add section to skinner
+#ifdef THRUSECT
+               aGenerator->AddWire(aWire);
+#else
+               std::shared_ptr<GeomAPI_Shape> aForCompoundShape(new GeomAPI_Shape);
+               aForCompoundShape->setImpl(new TopoDS_Shape(aWire));
+               aCompoundResultList.push_back(aForCompoundShape);
+#endif
+       }
+#ifdef THRUSECT
+       aGenerator->Build();
+
+       if (!aGenerator->IsDone()){
+               return;
+       }
+
+       aResult = aGenerator->Shape();
+
+       // Setting naming.
+       // JE SAIS PAS
+       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+       aFromShape->setImpl(new TopoDS_Shape(aGenerator->FirstShape()));
+       aToShape->setImpl(new TopoDS_Shape(aGenerator->LastShape()));
+       this->addFromShape(aFromShape);
+       this->addToShape(aToShape);
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+#else
+       aCompoundResult = GeomAlgoAPI_CompoundBuilder::compound(aCompoundResultList);
+       this->setShape(aCompoundResult);
+       this->setDone(true);
+#endif
+}
+
+//=================================================================================================
+void GeomAlgoAPI_PipeApprox::build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+       const std::shared_ptr<GeomAPI_Shape>&   theBiNormal)
+{
+       if(!theProfileShape || !thePathShape || !theBiNormal) {
+               return;
+       }
+
+       // Getting profile.
+       TopoDS_Face aProfileFace = TopoDS::Face(theProfileShape->impl<TopoDS_Shape>());
+
+       // Getting path
+
+       const TopoDS_Shape& aPathShape = thePathShape->impl<TopoDS_Shape>();
+       TopoDS_Edge aPathEdge;
+       if(thePathShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aPathEdge = TopoDS::Edge(thePathShape->impl<TopoDS_Shape>());
+       }
+
+       // Getting binormal
+
+       TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
+
+       TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
+       double aFirst, aLast;
+       Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
+       Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
+
+       gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
+
+
+       //COMPUTE RESULT
+       TopoDS_Shape aResult;
+
+       double u;
+       //recover curve
+       aPathEdge.Oriented(TopAbs_FORWARD );
+
+       Handle(Geom_Curve) aPathCurve = BRep_Tool::Curve(aPathEdge, aFirst, aLast);
+
+       u = aFirst;
+       const double uStep = (aLast - aFirst) / (NB_SECT - 1);
+
+#ifdef THRUSECT
+       const Standard_Boolean isSolid = Standard_True;
+       const Standard_Boolean isRuled = Standard_False;
+       const Standard_Real    pres3d = 1.0e-02;
+
+       //building thrusection algo)
+       BRepOffsetAPI_ThruSections* aGenerator = new BRepOffsetAPI_ThruSections(isSolid, isRuled, pres3d);
+       if(!aGenerator) {
+               return;
+       }
+       aGenerator->SetSmoothing(Standard_True);
+       aGenerator->SetMaxDegree(5);
+       aGenerator->CheckCompatibility(Standard_False);
+#else
+       std::shared_ptr<GeomAPI_Shape> aCompoundResult;
+       std::list<std::shared_ptr<GeomAPI_Shape> > aCompoundResultList;
+#endif
+
+       //iterating on sections
+       TopoDS_Wire aWire;
+       gp_Trsf aTrsf = gp_Trsf();
+       gp_Pnt P;
+       gp_Vec T, Vx;
+
+       aPathCurve->D1(u, P, T);
+       //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+       //if D2 undefined, replace it with "binormal"
+       Vx = T ^ aBiNormalDir;
+       Vx = Vx ^ T;
+
+       gp_Ax3 gp_Ax3_0(P, T, Vx);
+
+       for (int i = 0; i < NB_SECT; ++i)
+       {       
+               u += uStep;
+               aPathCurve->D1(u, P, T);
+               Vx = T ^ aBiNormalDir;
+               Vx = Vx ^ T;
+
+               aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+
+               aWire = makeWireFromTransf(aProfileFace, aTrsf);
+
+
+               // Add section to skinner
+#ifdef THRUSECT
+               aGenerator->AddWire(aWire);
+#else
+               std::shared_ptr<GeomAPI_Shape> aForCompoundShape(new GeomAPI_Shape);
+               aForCompoundShape->setImpl(new TopoDS_Shape(aWire));
+               aCompoundResultList.push_back(aForCompoundShape);
+#endif
+       }
+#ifdef THRUSECT
+       aGenerator->Build();
+
+       if (!aGenerator->IsDone()){
+               return;
+       }
+
+       aResult = aGenerator->Shape();
+
+       // Setting naming.
+       // JE SAIS PAS
+       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+       aFromShape->setImpl(new TopoDS_Shape(aGenerator->FirstShape()));
+       aToShape->setImpl(new TopoDS_Shape(aGenerator->LastShape()));
+       this->addFromShape(aFromShape);
+       this->addToShape(aToShape);
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+#else
+       aCompoundResult = GeomAlgoAPI_CompoundBuilder::compound(aCompoundResultList);
+       this->setShape(aCompoundResult);
+       this->setDone(true);
+#endif
+}
+
+//=================================================================================================
+// BUILD() when using a law directly defined in the feature (pipeapprox)
+//=================================================================================================
+
+//=================================================================================================
+void GeomAlgoAPI_PipeApprox::build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+       const std::shared_ptr<GeomAPI_Shape>&   theDef,
+       const std::shared_ptr<GeomAPI_Shape>&   theRef)
+{
+       if(!theProfileShape || !thePathShape || !theDef || !theRef) {
+               return;
+       }
+
+       // Getting profile.
+       TopoDS_Face aProfileFace = TopoDS::Face(theProfileShape->impl<TopoDS_Shape>());
+
+       // Getting path
+       //const TopoDS_Shape& aPathShape = thePathShape->impl<TopoDS_Shape>();
+       TopoDS_Edge aPathEdge;
+       if(thePathShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aPathEdge = TopoDS::Edge(thePathShape->impl<TopoDS_Shape>());
+       }
+
+       // Getting law
+       // DEF
+       TopoDS_Edge aDefEdge;
+       if(theDef->shapeType() == GeomAPI_Shape::EDGE) {
+               aDefEdge = TopoDS::Edge(theDef->impl<TopoDS_Shape>());
+       }
+       // REF
+       TopoDS_Edge aRefEdge;
+       if(theRef->shapeType() == GeomAPI_Shape::EDGE) {
+               aRefEdge = TopoDS::Edge(theRef->impl<TopoDS_Shape>());
+       }
+
+       //COMPUTE RESULT
+       TopoDS_Shape aResult;
+
+       double u, aFirst, aLast;
+       double d, dFirst, dLast, rFirst, rLast;
+       //recover curve
+       aPathEdge.Oriented(TopAbs_FORWARD );
+       Handle(Geom_Curve) aPathCurve = BRep_Tool::Curve(aPathEdge, aFirst, aLast);
+
+       u = aFirst;
+       const double uStep = (aLast - aFirst) / (NB_SECT - 1);
+
+       //recover Def curve
+       Handle(Geom_Curve) aDefCurve = BRep_Tool::Curve(aDefEdge, dFirst, dLast);
+       d = dFirst;
+       const double dStep = (dLast - dFirst) / (NB_SECT - 1);
+
+       //recover Ref line
+       Handle(Geom_Curve) aRefCurve = BRep_Tool::Curve(aRefEdge, rFirst, rLast);
+       GeomAdaptor_Curve aRefAdaptorCurve = GeomAdaptor_Curve(aRefCurve);
+       gp_Pnt rFP, rLP;
+       gp_XYZ rF, rL;
+       aRefCurve->D0(rFirst, rFP);
+       aRefCurve->D0(rLast, rLP);
+       rF = rFP.XYZ();
+       rL = rLP.XYZ();
+       rL.Subtract(rF);
+       gp_Lin aRefLin = gp_Lin(rFP, rL);
+       rFirst = aRefAdaptorCurve.FirstParameter();
+       rLast = aRefAdaptorCurve.LastParameter();
+
+#ifdef THRUSECT
+       const Standard_Boolean isSolid = Standard_True;
+       const Standard_Boolean isRuled = Standard_False;
+       const Standard_Real    pres3d = 1.0e-02;
+
+       //building thrusection algo)
+       BRepOffsetAPI_ThruSections* aGenerator = new BRepOffsetAPI_ThruSections(isSolid, isRuled, pres3d);
+       if(!aGenerator) {
+               return;
+       }
+       aGenerator->SetSmoothing(Standard_True);
+       aGenerator->SetMaxDegree(5);
+       aGenerator->CheckCompatibility(Standard_False);
+#else
+       std::shared_ptr<GeomAPI_Shape> aCompoundResult;
+       std::list<std::shared_ptr<GeomAPI_Shape> > aCompoundResultList;
+#endif
+
+       //iterating on sections
+       TopoDS_Wire aWire;
+       gp_Trsf aTrsf = gp_Trsf();
+       gp_Trsf bTrsf = gp_Trsf();
+       gp_Pnt P, D, C;
+       gp_Vec T, N, Vx;
+
+       aPathCurve->D2(u, P, T, N);
+       //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+       Vx = T ^ N;
+       Vx = Vx ^ T;
+
+       gp_Ax3 gp_Ax3_0(P, T, Vx);
+
+       //get center for scaling
+       GProp_PGProps aCConstr = GProp_PGProps();
+       TopExp_Explorer aVertexExp(aProfileFace, TopAbs_VERTEX);
+       for (; aVertexExp.More(); aVertexExp.Next()) {
+               TopoDS_Vertex aVS = TopoDS::Vertex(aVertexExp.Current());
+               gp_Pnt aP = BRep_Tool::Pnt(aVS);
+               aCConstr.AddPoint(aP);
+       }
+       C = aCConstr.CentreOfMass();
+
+       for (int i = 0; i < NB_SECT; ++i)
+       {       
+               u += uStep;
+               aPathCurve->D2(u, P, T, N);
+               Vx = T ^ N;
+               Vx = Vx ^ T;
+
+               //set scale
+               //will calculate from law
+               d+= dStep;
+               aDefCurve->D0(d, D);
+               double Tol = 1.0e-10;
+               Extrema_ExtPElC aCalcD = Extrema_ExtPElC(D, aRefLin, Tol, rFirst, rLast);
+               int nbDMin = aCalcD.NbExt();
+               nbDMin++;
+               int k = 1;
+               while(k < nbDMin && !aCalcD.IsMin(k))
+               {
+                       k++;
+               }
+               double ii = aCalcD.SquareDistance(k);
+               ii = sqrt(ii);
+               //for the scale maybe get init "length" to divide ii by it?
+
+               bTrsf.SetScale(C, ii);
+               BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aProfileFace, bTrsf, true);
+
+               TopoDS_Shape aScaledPorfileFace = aBuilder->Shape();
+
+               aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+               aWire = makeWireFromTransf(aScaledPorfileFace, aTrsf);
+
+
+               // Add section to skinner
+#ifdef THRUSECT
+               aGenerator->AddWire(aWire);
+#else
+               std::shared_ptr<GeomAPI_Shape> aForCompoundShape(new GeomAPI_Shape);
+               aForCompoundShape->setImpl(new TopoDS_Shape(aWire));
+               aCompoundResultList.push_back(aForCompoundShape);
+#endif
+       }
+#ifdef THRUSECT
+       aGenerator->Build();
+
+       if (!aGenerator->IsDone()){
+               return;
+       }
+
+       aResult = aGenerator->Shape();
+
+       // Setting naming.
+       // JE SAIS PAS
+       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+       aFromShape->setImpl(new TopoDS_Shape(aGenerator->FirstShape()));
+       aToShape->setImpl(new TopoDS_Shape(aGenerator->LastShape()));
+       this->addFromShape(aFromShape);
+       this->addToShape(aToShape);
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+#else
+       aCompoundResult = GeomAlgoAPI_CompoundBuilder::compound(aCompoundResultList);
+       this->setShape(aCompoundResult);
+       this->setDone(true);
+#endif
+}
+
+//=================================================================================================
+// BUILD() when using paramLaws
+//=================================================================================================
+
+//=================================================================================================
+
+void GeomAlgoAPI_PipeApprox::build(const ListOfShape& theProfileShapeList,
+       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+       const bool isReverse,
+       const int nbSect,
+       const bool withFrenet)
+{
+       if(!theProfileShapeList.size() || !thePathShape) {
+               return;
+       }
+
+       double coeffReverse = 1.0;
+       if(isReverse)
+       {
+               coeffReverse = -1.0;
+       }
+
+       //To COMPUTE the RESULT
+       TopoDS_Shape aResult;
+
+       BRepOffsetAPI_ThruSections* aGenerator;
+
+       const Standard_Boolean isSolid = Standard_True;
+       const Standard_Boolean isRuled = Standard_False;
+       const Standard_Real    pres3d = 1.0e-02;
+
+       aGenerator = new BRepOffsetAPI_ThruSections(isSolid, isRuled, pres3d);
+       if(!aGenerator) {
+               return;
+       }
+       aGenerator->SetSmoothing(Standard_True);
+       aGenerator->SetMaxDegree(5);
+       aGenerator->CheckCompatibility(Standard_False);
+
+       //used for dump
+       std::shared_ptr<GeomAPI_Shape> aCompoundResult;
+       std::shared_ptr<GeomAPI_Shape> aCompoundPointResult;
+       std::list<std::shared_ptr<GeomAPI_Shape> > aCompoundResultList;
+       std::list<std::shared_ptr<GeomAPI_Shape> > aCompoundPointList;
+
+       // Getting path
+       double u, aFirst, aLast, uStep;
+       TopoDS_Edge aPathEdge;
+       TopoDS_Wire aPathWire;
+       Handle(Geom_Curve) aPathCurve;
+
+       if(thePathShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aPathEdge = TopoDS::Edge(thePathShape->impl<TopoDS_Shape>());
+               //recover curve
+
+               aPathCurve = BRep_Tool::Curve(aPathEdge, aFirst, aLast);
+               if(isReverse)
+               {
+                       double aTemp = aFirst;
+                       aFirst = aLast;
+                       aLast = aTemp;
+               }
+
+               u = aFirst;
+               uStep = abs(aLast - aFirst) / (nbSect - 1);
+
+               //iterating on sections
+               TopoDS_Wire aWire;
+               gp_Trsf aTrsf = gp_Trsf();
+               gp_Pnt P;
+               gp_Vec T, N, Vx;
+               double Tol = 1.0e-10;
+
+               //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+               aPathCurve->D2(u, P, T, N);
+               if(!withFrenet && (N.X() == 0) && (N.Y() == 0) && (N.Z() == 0))
+               {
+                       //no 2nd derivative to help find a normal oriented towards the curvature
+                       //use random orthogonal vecotr to T
+                       N.SetX(-T.Y());
+                       N.SetY(T.X());
+                       N.SetZ(0.0);
+
+                       Vx = N ^ T;
+                       Vx = T ^ Vx;
+
+               }
+               else
+               {
+                       //use standard Frenet
+
+                       //need to add error management...
+                       Vx = N ^ T;
+                       Vx = T ^ Vx;
+                       //currently force "crash", which means need for binormal, 
+               }       
+
+               gp_Ax3 gp_Ax3_0(P, T, Vx);
+
+
+               for(ListOfShape::const_reverse_iterator anIter = theProfileShapeList.crbegin(); anIter != theProfileShapeList.crend(); anIter++) {
+                       const TopoDS_Face aProfile = TopoDS::Face((*anIter)->impl<TopoDS_Shape>());
+                       if(withFrenet)
+                       {
+                               //normal frenet frame
+                               aPathCurve->D2(u, P, T, N);
+                               Vx = N ^ T;
+                               Vx = T ^ Vx;
+                       }
+                       else
+                       {
+                               //iterative placement of the frames
+                               //based on  http://webhome.cs.uvic.ca/~blob/courses/305/notes/pdf/ref-frames.pdf
+                               //might need to be checked
+                               //process from lines 816-837 is valid (tested and debugged) 
+                               //and work based on global transformation from start to actual and not iterative
+                               gp_Vec aux;
+                               aPathCurve->D1(u, P, aux);
+                               if (T.IsParallel(aux, Tol))
+                               {
+                                       if(T.IsOpposite(aux, Tol))
+                                       {
+                                               Vx.Reverse();
+                                       }
+                               }
+                               else
+                               {
+                                       gp_Vec cross(T);
+                                       cross.Cross(aux);
+                                       double alpha = T.AngleWithRef(aux, cross);
+                                       gp_Ax1 axe(gp::Origin(), cross.XYZ());
+
+                                       //have T and Vx for the new frame
+                                       Vx.Rotate(axe, alpha);
+                               }
+                               T = aux;
+                       }
+
+                       aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+                       aWire = makeWireFromTransf(aProfile, aTrsf);
+
+
+                       aGenerator->AddWire(aWire);
+
+                       //for dump
+                       std::shared_ptr<GeomAPI_Shape> aForCompoundShape(new GeomAPI_Shape);
+                       aForCompoundShape->setImpl(new TopoDS_Shape(aWire));
+                       aCompoundResultList.push_back(aForCompoundShape);
+                       //
+
+                       u += (coeffReverse*uStep);
+               }
+       }else if(thePathShape->shapeType() == GeomAPI_Shape::WIRE){
+               aPathWire = TopoDS::Wire(thePathShape->impl<TopoDS_Shape>());
+               BRepTools::Write(aPathWire, "C:/Users/occ/Desktop/pathDump.brep");
+
+               Handle(BRepAdaptor_HCompCurve) aPathCompCurve = new (BRepAdaptor_HCompCurve) (aPathWire);
+
+               Standard_Real aTol = Precision::Confusion();
+               GeomAbs_Shape aContinuity = GeomAbs_C2 /*highest supported continuity*/;
+               Standard_Integer aMaxSeg = 10000, /*max number of spans*/
+                       aMaxDeg = 9; /*max degree, consistent with settings in Algo*/
+               GeomConvert_ApproxCurve anApproxPath (aPathCompCurve, aTol, aContinuity, aMaxSeg, aMaxDeg);
+               Handle(Geom_BSplineCurve) aBSplinePath = anApproxPath.Curve();
+               BRepBuilderAPI_MakeEdge * aBE = new BRepBuilderAPI_MakeEdge(aBSplinePath);
+               TopoDS_Edge aBSE = aBE->Edge();
+               BRepTools::Write(aBSE, "C:/Users/occ/Desktop/pathBspline.brep");
+               aFirst = aBSplinePath->FirstParameter();
+               aLast = aBSplinePath->LastParameter();
+
+               if(isReverse)
+               {
+                       double aTemp = aFirst;
+                       aFirst = aLast;
+                       aLast = aTemp;
+               }
+
+               u = aFirst;
+               uStep = abs(aLast - aFirst) / (nbSect - 1);
+
+               //iterating on sections
+               TopoDS_Wire aWire;
+               gp_Trsf aTrsf = gp_Trsf();
+               gp_Trsf bTrsf = gp_Trsf();
+               gp_Pnt P;
+               gp_Vec T, N, Vx;
+               gp_Ax1 axe0;
+               double Tol = 1.0e-10;
+
+               //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+               aBSplinePath->D2(u, P, T, N);
+
+               if(!withFrenet && (N.X() == 0) && (N.Y() == 0) && (N.Z() == 0))
+               {
+                       //no 2nd derivative to help find a normal oriented towards the curvature
+                       //use random orthogonal vecotr to T
+                       if(T.X() == 0)
+                       {
+                               N.SetX(0.0);
+                               N.SetY(-T.Z());
+                               N.SetZ(T.Y());
+                       }else if (T.Y() == 0)
+                       {
+                               N.SetX(-T.Z());
+                               N.SetY(0.0);
+                               N.SetZ(T.X());
+                       }
+                       else
+                       {
+                               N.SetX(-T.Y());
+                               N.SetY(T.X());
+                               N.SetZ(0.0);
+                       }
+                       //can first derivative be null ? assume not
+                       Vx = N ^ T;
+                       axe0 = gp_Ax1(gp::Origin(), Vx.XYZ());
+                       Vx = T ^ Vx;
+               }
+               else
+               {
+                       //use standard Frenet
+                       //no checks to force "crash" if withFrenet, which means need for binormal, to add error
+                       Vx = N ^ T;
+                       axe0 = gp_Ax1(gp::Origin(), Vx.XYZ());
+                       Vx = T ^ Vx;
+               }       
+               const gp_Ax3 gp_Ax3_0(P, T, Vx);
+               const gp_Pnt P0(P);
+               const gp_Vec T0(T);
+               double alpha = 0.0;
+
+               for(ListOfShape::const_reverse_iterator anIter = theProfileShapeList.crbegin(); anIter != theProfileShapeList.crend(); anIter++) {
+                       const TopoDS_Face aProfile = TopoDS::Face((*anIter)->impl<TopoDS_Shape>());
+                       if(withFrenet)
+                       {
+                               //normal frenet frame
+                               aBSplinePath->D2(u, P, T, N);
+                               Vx = N ^ T;
+                               Vx = T ^ Vx;
+
+                               aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+                               aWire = makeWireFromTransf(aProfile, aTrsf);
+                       }
+                       else
+                       {//this works better, not iterative anymore but global from initial place to actual
+                               gp_Pnt Paux;
+                               gp_Vec Taux;
+                               aBSplinePath->D1(u, Paux, Taux);
+
+                               bTrsf = gp_Trsf();
+                               if (T0.IsParallel(Taux, Tol))
+                               {
+                                       if(T0.IsOpposite(Taux, Tol))
+                                       {
+                                               bTrsf.SetMirror(axe0);
+                                       }
+                               }
+                               else
+                               {
+                                       gp_Vec cross(Taux);
+                                       cross.Cross(T);
+                                       double angle = T0.AngleWithRef(Taux, cross);
+                                       bTrsf.SetRotation(axe0, angle);
+                               }
+
+                               gp_Vec VT(Paux.XYZ() - P0.XYZ());
+                               bTrsf.SetTranslationPart(VT);
+
+                               aWire = makeWireFromTransf(aProfile, bTrsf);
+                       }
+
+                       aGenerator->AddWire(aWire);
+
+                       //for dump
+                       std::shared_ptr<GeomAPI_Shape> aForCompoundShape(new GeomAPI_Shape);
+                       aForCompoundShape->setImpl(new TopoDS_Shape(aWire));
+                       aCompoundResultList.push_back(aForCompoundShape);
+
+                       //ForDump
+                       BRepBuilderAPI_MakeVertex coucou(P);
+                       std::shared_ptr<GeomAPI_Shape> aForCompoundPoint(new GeomAPI_Shape);
+                       aForCompoundPoint->setImpl(new TopoDS_Shape(coucou.Vertex()));
+                       aCompoundPointList.push_back(aForCompoundPoint);
+                       //
+
+                       u += (coeffReverse*uStep);
+               }
+       }
+
+       aGenerator->Build();
+
+
+
+       aResult = aGenerator->Shape();
+
+       // Setting naming.
+       // JE SAIS PAS
+
+       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+       aFromShape->setImpl(new TopoDS_Shape(aGenerator->LastShape()));
+       aToShape->setImpl(new TopoDS_Shape(aGenerator->FirstShape()));
+       this->addFromShape(aFromShape);
+       this->addToShape(aToShape);
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+
+       //dump
+       aCompoundResult = GeomAlgoAPI_CompoundBuilder::compound(aCompoundResultList);
+       TopoDS_Compound aComp = TopoDS::Compound(aCompoundResult->impl<TopoDS_Shape>());
+       BRepTools::Write(aComp, "C:/Users/occ/Desktop/forDump.brep");
+
+       aCompoundPointResult = GeomAlgoAPI_CompoundBuilder::compound(aCompoundPointList);
+       TopoDS_Compound aComp2 = TopoDS::Compound(aCompoundResult->impl<TopoDS_Shape>());
+       BRepTools::Write(aComp2, "C:/Users/occ/Desktop/forDumpPoint.brep");
+}
+
+
+//=================================================================================================
+void GeomAlgoAPI_PipeApprox::build(const ListOfShape& theProfileShapeList,
+       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+       const std::shared_ptr<GeomAPI_Shape>&   theBinormal,
+       const bool isReverse,
+       const int nbSect)
+{
+       //METHOD MIGHT NEED TO BE DEBUGGED/MODIFIED BASED ON BUILD WITHOUT BINORMAL
+       if(!theProfileShapeList.size() || !thePathShape || !theBinormal) {
+               return;
+       }
+
+       double coeffReverse = 1.0;
+       if(isReverse)
+       {
+               coeffReverse = -1.0;
+       }
+
+       //COMPUTE RESULT
+       TopoDS_Shape aResult;
+
+       BRepOffsetAPI_ThruSections* aGenerator; 
+
+       const Standard_Boolean isSolid = Standard_True;
+       const Standard_Boolean isRuled = Standard_False;
+       const Standard_Real    pres3d = 1.0e-02;
+
+       aGenerator = new BRepOffsetAPI_ThruSections(isSolid, isRuled, pres3d);
+       if(!aGenerator) {
+               return;
+       }
+       aGenerator->SetSmoothing(Standard_True);
+       aGenerator->SetMaxDegree(5);
+       aGenerator->CheckCompatibility(Standard_False);
+
+
+       // Getting binormal
+       TopoDS_Shape aBiNormalShape = theBinormal->impl<TopoDS_Shape>();
+       TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
+       double aFirst, aLast;
+
+       Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
+       Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
+
+       gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
+
+       // Getting path
+       double u, uStep;
+       TopoDS_Edge aPathEdge;
+       TopoDS_Wire aPathWire;
+       Handle(Geom_Curve) aPathCurve;
+
+       if(thePathShape->shapeType() == GeomAPI_Shape::EDGE) {
+               aPathEdge = TopoDS::Edge(thePathShape->impl<TopoDS_Shape>());
+
+
+               //recover curve
+
+               aPathCurve = BRep_Tool::Curve(aPathEdge, aFirst, aLast);
+
+               if(isReverse)
+               {
+                       double aTemp = aFirst;
+                       aFirst = aLast;
+                       aLast = aTemp;
+               }
+
+               u = aFirst;
+               const double uStep = abs(aLast - aFirst) / (nbSect - 1);
+
+               //iterating on sections
+               TopoDS_Wire aWire;
+               gp_Trsf aTrsf = gp_Trsf();
+               gp_Pnt P;
+               gp_Vec T, Vx;
+
+               aPathCurve->D1(u, P, T);
+               //Vx should be in the plane of (P,D1,D2) so that (P,D1,Vx) is orthogonal
+               //if D2 undefined, replace it with "binormal"
+               Vx = T ^ aBiNormalDir;
+               Vx = Vx ^ T;
+
+               gp_Ax3 gp_Ax3_0(P, T, Vx);
+
+               int cpt = nbSect - 1;
+               for(ListOfShape::const_reverse_iterator anIter = theProfileShapeList.crbegin(); anIter != theProfileShapeList.crend(); anIter++) {
+                       const TopoDS_Face aProfile = TopoDS::Face((*anIter)->impl<TopoDS_Shape>());
+
+                       aPathCurve->D1(u, P, T);
+                       Vx = T ^ aBiNormalDir;
+                       Vx = Vx ^ T;
+                       aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+
+                       aWire = makeWireFromTransf(aProfile, aTrsf);
+
+
+                       aGenerator->AddWire(aWire);
+
+                       u += (coeffReverse*uStep);
+                       cpt--;
+               }
+       }else if(thePathShape->shapeType() == GeomAPI_Shape::WIRE)
+       {
+               aPathWire = TopoDS::Wire(thePathShape->impl<TopoDS_Shape>());
+               Handle(BRepAdaptor_HCompCurve) aPathCompCurve = new (BRepAdaptor_HCompCurve) (aPathWire);
+
+               Standard_Real aTol = Precision::Confusion();
+               GeomAbs_Shape aContinuity = GeomAbs_C2 /*highest supported continuity*/;
+               Standard_Integer aMaxSeg = 10000, /*max number of spans*/
+                       aMaxDeg = 9; /*max degree, consistent with settings in Algo*/
+               GeomConvert_ApproxCurve anApproxPath (aPathCompCurve, aTol, aContinuity, aMaxSeg, aMaxDeg);
+               Handle(Geom_BSplineCurve) aBSplinePath = anApproxPath.Curve();
+
+               aFirst = aBSplinePath->FirstParameter();
+               aLast = aBSplinePath->LastParameter();
+
+
+               gp_Ax3 gp_Ax3_0;
+
+
+               if(isReverse)
+               {
+                       double aTemp = aFirst;
+                       aFirst = aLast;
+                       aLast = aTemp;
+               }
+
+               u = aFirst;
+               uStep = abs(aLast-aFirst) / (nbSect - 1);
+               TopoDS_Wire aWire;
+               gp_Trsf aTrsf = gp_Trsf();
+               gp_Pnt P;
+               gp_Vec T,Vx;
+
+               aPathCurve->D1(u, P, T);
+               Vx = T ^ aBiNormalDir;
+               Vx = Vx ^ T;
+
+               gp_Ax3_0 = gp_Ax3(P, T, Vx);
+               for(ListOfShape::const_reverse_iterator anIter = theProfileShapeList.crbegin(); anIter != theProfileShapeList.crend(); anIter++) {
+                       const TopoDS_Face aProfile = TopoDS::Face((*anIter)->impl<TopoDS_Shape>());
+
+                       aPathCurve->D1(u, P, T);
+                       Vx = T ^ aBiNormalDir;
+                       Vx = Vx ^ T;
+                       aTrsf.SetDisplacement(gp_Ax3_0, gp_Ax3(P, T, Vx));
+                       aWire = makeWireFromTransf(aProfile, aTrsf);
+
+
+                       aGenerator->AddWire(aWire);
+
+
+                       u += (coeffReverse*uStep);
+               }
+
+       }
+       aGenerator->Build();
+
+       if (!aGenerator->IsDone()){
+               return;
+       }
+
+       aResult = aGenerator->Shape();
+
+       // Setting naming.
+       // JE SAIS PAS
+       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
+       aFromShape->setImpl(new TopoDS_Shape(aGenerator->LastShape()));
+       aToShape->setImpl(new TopoDS_Shape(aGenerator->FirstShape()));
+       this->addFromShape(aFromShape);
+       this->addToShape(aToShape);
+
+       // Setting result.
+       if(aResult.IsNull()) {
+               return;
+       }
+       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+       aShape->setImpl(new TopoDS_Shape(aResult));
+       this->setShape(aShape);
+       this->setDone(true);
+}
+
+//=================================================================================================
+TopoDS_Wire makeWireFromTransf(const TopoDS_Shape &theSourceShape,
+       gp_Trsf  theTrsf)
+{
+       TopoDS_Wire aResult;
+       if(theSourceShape.IsNull()) {
+               return aResult;
+       }
+
+       BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(theSourceShape, theTrsf, true);
+       if(!aBuilder) {
+               return aResult;
+       }
+
+       if(aBuilder->IsDone() != Standard_True) {
+               return aResult;
+       }
+
+       BRepBuilderAPI_MakeWire mkWire;
+
+       TopExp_Explorer aEdgeExp(aBuilder->Shape(), TopAbs_EDGE);
+       for (; aEdgeExp.More(); aEdgeExp.Next()) {
+               TopoDS_Edge aES = TopoDS::Edge(aEdgeExp.Current());
+               mkWire.Add(aES);
+       }
+       aResult = mkWire.Wire();
+
+       return aResult;
+}
\ No newline at end of file
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.h b/src/GeomAlgoAPI/GeomAlgoAPI_PipeApprox.h
new file mode 100644 (file)
index 0000000..8b11c06
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright
+
+// File:        GeomAlgoAPI_PipeApprox.h
+// Created:     
+// Author:      
+
+#ifndef GeomAlgoAPI_PipeApprox_H_
+#define GeomAlgoAPI_PipeApprox_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeSweep.h>
+#include <ModelAPI_Feature.h>
+#include <GeomAPI_Face.h>
+#include <memory>
+#include <list>
+#include <vector>
+/// \class GeomAlgoAPI_PipeApprox
+/// \ingroup DataAlgo
+/// \brief Allows to create the Pipe based on a given face and path.
+
+class GeomAlgoAPI_PipeApprox : public GeomAlgoAPI_MakeSweep
+{
+public:
+  /// \brief Creates Pipe for the given shape.
+  /// \param[in] theBaseShape face for Pipe.
+  /// \param[in] thePath path for Pipe.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox();
+
+  //basic pipe with thrusection algo
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+                                            std::shared_ptr<GeomAPI_Shape>   thePathShape);
+
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+                                            std::shared_ptr<GeomAPI_Shape>   thePathShape,
+                                                                                       std::shared_ptr<GeomAPI_Shape>   theBiNormal);
+
+  //single law, does a "scaling"
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox(std::shared_ptr<GeomAPI_Shape> theProfileShape,
+                                            std::shared_ptr<GeomAPI_Shape>   thePathShape,
+                                                                                       std::shared_ptr<GeomAPI_Shape>   theDef,
+                                                                                       std::shared_ptr<GeomAPI_Shape>   theRef);
+
+
+
+  //WHEN USING LAWS
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox(ListOfShape theProfileShapeList,
+                       std::shared_ptr<GeomAPI_Shape>   thePath,
+                       bool isReverse,
+                       int nbSect,
+                       bool withFrenet);
+
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_PipeApprox(ListOfShape theProfileShapeList,
+                       std::shared_ptr<GeomAPI_Shape>   thePath,
+                       std::shared_ptr<GeomAPI_Shape>   theBinormal,
+                       bool isReverse,
+                       int nbSect);
+
+private:
+  /// Builds resulting shape.
+  void build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+             const std::shared_ptr<GeomAPI_Shape>&   thePathShape);
+
+  void build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+                                                                       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+                                                                       const std::shared_ptr<GeomAPI_Shape>&   theBiNormal);
+  //
+  void build(const std::shared_ptr<GeomAPI_Shape>& theProfileShape,
+                                                                       const std::shared_ptr<GeomAPI_Shape>&   thePathShape,
+                                                                       const std::shared_ptr<GeomAPI_Shape>&   theDef,
+                                                                       const std::shared_ptr<GeomAPI_Shape>&   theRef);
+
+  //
+  void build(const ListOfShape& theProfileShapeList,
+                       const std::shared_ptr<GeomAPI_Shape>&   thePath,
+                       const bool isReverse,
+                       const int nbSect,
+                       const bool withFrenet);
+
+  void build(const ListOfShape& theProfileShapeList,
+                       const std::shared_ptr<GeomAPI_Shape>&   thePath,
+                       const std::shared_ptr<GeomAPI_Shape>&   theBinormal,
+                       const bool isReverse,
+                       const int nbSect);
+};
+#endif
\ No newline at end of file
index 1f6c8319f6e7950e42d4505e79a2bafee60ca786..8de329477509a403e71f366aef557d6954ed77e7 100755 (executable)
@@ -400,7 +400,20 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
         "Feature '%1' is updated in infinitive loop").arg(theFeature->data()->name()).send();
       return false;
     }
-    myProcessed[theFeature] = aCount + 1;
+       //TEST FOR SWEEP (EdMei)
+       if(theFeature->getKind() == "PipeApproxLaw" || theFeature->getKind() == "PipeApprox")
+       {
+               std::map<std::shared_ptr<ModelAPI_Feature>, int >::iterator it;
+               for(it = myProcessed.begin(); it != myProcessed.end(); it++)
+               {
+                       it->second = 0;
+               }
+       }
+       else
+       {
+               myProcessed[theFeature] = aCount + 1;
+       }
+       //END TEST FOR SWEEP (EdMei)
   }
 
   // check this feature is not yet checked or processed