FeaturesAPI_MultiTranslation.h
FeaturesAPI_Partition.h
FeaturesAPI_Pipe.h
+ FeaturesAPI_Loft.h
FeaturesAPI_Placement.h
FeaturesAPI_PointCloudOnFace.h
FeaturesAPI_Recover.h
FeaturesAPI_MultiTranslation.cpp
FeaturesAPI_Partition.cpp
FeaturesAPI_Pipe.cpp
+ FeaturesAPI_Loft.cpp
FeaturesAPI_Placement.cpp
FeaturesAPI_PointCloudOnFace.cpp
FeaturesAPI_Recover.cpp
%shared_ptr(FeaturesAPI_MultiTranslation)
%shared_ptr(FeaturesAPI_Partition)
%shared_ptr(FeaturesAPI_Pipe)
+%shared_ptr(FeaturesAPI_Loft)
%shared_ptr(FeaturesAPI_Placement)
%shared_ptr(FeaturesAPI_PointCloudOnFace)
%shared_ptr(FeaturesAPI_Recover)
%include "FeaturesAPI_MultiTranslation.h"
%include "FeaturesAPI_Partition.h"
%include "FeaturesAPI_Pipe.h"
+%include "FeaturesAPI_Loft.h"
%include "FeaturesAPI_Placement.h"
%include "FeaturesAPI_PointCloudOnFace.h"
%include "FeaturesAPI_Recover.h"
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FeaturesAPI_Loft.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+FeaturesAPI_Loft::FeaturesAPI_Loft(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+//==================================================================================================
+FeaturesAPI_Loft::FeaturesAPI_Loft(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theFirstObject,
+ const ModelHighAPI_Selection& theSecondObject)
+: ModelHighAPI_Interface(theFeature)
+{
+ if(initialize()) {
+ fillAttribute(theFirstObject, myfisrstObject);
+ fillAttribute(theSecondObject, mysecondObject);
+ execute();
+ }
+}
+
+//==================================================================================================
+FeaturesAPI_Loft::~FeaturesAPI_Loft()
+{
+
+}
+
+//==================================================================================================
+void FeaturesAPI_Loft::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ AttributeSelectionPtr anAttrFirstObject =
+ aBase->selection(FeaturesPlugin_Loft::FIRST_OBJECT_ID());
+ AttributeSelectionPtr anAttrSecondObject =
+ aBase->selection(FeaturesPlugin_Loft::SECOND_OBJECT_ID());
+
+ theDumper << aBase << " = model.addLoft(" << aDocName << ", "
+ << anAttrFirstObject << ", " << anAttrSecondObject;
+
+ theDumper << ")" << std::endl;
+}
+
+//==================================================================================================
+LoftPtr addLoft(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theFirstObject,
+ const ModelHighAPI_Selection& theSecondObject)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Loft::ID());
+
+ return LoftPtr(new FeaturesAPI_Loft(aFeature, theFirstObject, theSecondObject));
+}
+
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FeaturesAPI_Loft_H_
+#define FeaturesAPI_Loft_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Loft.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Loft
+/// \ingroup CPPHighAPI
+/// \brief Interface for Loft feature.
+class FeaturesAPI_Loft: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_Loft(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_Loft(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theFirstObject,
+ const ModelHighAPI_Selection& theSecondObject);
+
+ /// Destructor.
+ FEATURESAPI_EXPORT
+ virtual ~FeaturesAPI_Loft();
+
+ INTERFACE_2(FeaturesPlugin_Loft::ID(),
+ fisrstObject, FeaturesPlugin_Loft::FIRST_OBJECT_ID(),
+ ModelAPI_AttributeSelection, /** First object */,
+ secondObject, FeaturesPlugin_Loft::SECOND_OBJECT_ID(),
+ ModelAPI_AttributeSelection, /** second objexct */)
+
+ /// Dump wrapped feature
+ FEATURESAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Loft object.
+typedef std::shared_ptr<FeaturesAPI_Loft> LoftPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Loft feature.
+FEATURESAPI_EXPORT
+LoftPtr addLoft(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theFirstObject,
+ const ModelHighAPI_Selection& theSecondObject);
+
+#endif // FeaturesAPI_Loft_H_
#include "FeaturesAPI_MultiTranslation.h"
#include "FeaturesAPI_Partition.h"
#include "FeaturesAPI_Pipe.h"
+ #include "FeaturesAPI_Loft.h"
#include "FeaturesAPI_Placement.h"
#include "FeaturesAPI_PointCloudOnFace.h"
#include "FeaturesAPI_Recover.h"
FeaturesPlugin_Intersection.h
FeaturesPlugin_Partition.h
FeaturesPlugin_Pipe.h
+ FeaturesPlugin_Loft.h
FeaturesPlugin_Placement.h
FeaturesPlugin_PointCloudOnFace.h
FeaturesPlugin_CompositeBoolean.h
FeaturesPlugin_Intersection.cpp
FeaturesPlugin_Partition.cpp
FeaturesPlugin_Pipe.cpp
+ FeaturesPlugin_Loft.cpp
FeaturesPlugin_Placement.cpp
FeaturesPlugin_PointCloudOnFace.cpp
FeaturesPlugin_CompositeBoolean.cpp
placement_widget.xml
intersection_widget.xml
pipe_widget.xml
+ loft_widget.xml
remove_subshapes_widget.xml
union_widget.xml
symmetry_widget.xml
IF(${HAVE_SALOME})
enable_testing()
set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/FeaturesPlugin")
-
+
install(FILES CTestTestfileInstall.cmake
DESTINATION ${TEST_INSTALL_DIRECTORY}
RENAME CTestTestfile.cmake)
install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
-
+
set(TMP_TESTS_NAMES)
foreach(tfile ${TEST_NAMES})
list(APPEND TMP_TESTS_NAMES "Test/${tfile}")
endforeach(tfile ${TEST_NAMES})
-
+
install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY})
ENDIF(${HAVE_SALOME})
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FeaturesPlugin_Loft.h"
+#include "FeaturesPlugin_Tools.h"
+
+#include <ModelAPI_AttributeSelection.h>
+
+#include <GeomAlgoAPI_Copy.h>
+#include <GeomAlgoAPI_Filling.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_Tools.h>
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+#include <cmath>
+
+//==================================================================================================
+FeaturesPlugin_Loft::FeaturesPlugin_Loft()
+{
+}
+
+//==================================================================================================
+void FeaturesPlugin_Loft::initAttributes()
+{
+ data()->addAttribute(FIRST_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(SECOND_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+}
+
+//==================================================================================================
+void FeaturesPlugin_Loft::execute()
+{
+ AttributeSelectionPtr aFirstSelection = selection(FIRST_OBJECT_ID());
+ AttributeSelectionPtr aSecondelection = selection(SECOND_OBJECT_ID());
+
+ if (aFirstSelection->isInitialized() && aSecondelection->isInitialized()) {
+
+ GeomShapePtr aFirstShape, aSecondShape;
+
+ if (aFirstSelection && aSecondelection) {
+ aFirstShape = aFirstSelection->value();
+ if (!aFirstShape && aFirstSelection->context())
+ aFirstShape = aFirstSelection->context()->shape();
+
+ aSecondShape = aSecondelection->value();
+ if (!aSecondShape && aSecondelection->context())
+ aSecondShape = aSecondelection->context()->shape();
+ }
+
+ std::string anError;
+ std::shared_ptr<GeomAlgoAPI_Loft> aLoftAlgo(new GeomAlgoAPI_Loft(aFirstShape, aSecondShape));
+
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aLoftAlgo, getKind(), anError)) {
+ setError(anError);
+ return;
+ }
+ ListOfShape theBoundaryShapes;
+ theBoundaryShapes.push_back(aFirstShape);
+ theBoundaryShapes.push_back(aSecondShape);
+
+ // Create result body.
+ ResultBodyPtr aResultBody = document()->createBody(data());
+
+ aResultBody->store(aLoftAlgo->shape());
+ // store Faces
+ for(GeomAPI_ShapeExplorer anExp(aLoftAlgo->shape(), GeomAPI_Shape::FACE);
+ anExp.more(); anExp.next()) {
+ GeomShapePtr anEdge = anExp.current();
+ aResultBody->generated(anEdge, "Loft_Face");
+ }
+ setResult(aResultBody, 0);
+ }
+}
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FeaturesPlugin_Loft_H_
+#define FeaturesPlugin_Loft_H_
+
+#include "FeaturesPlugin.h"
+
+#include <GeomAlgoAPI_Loft.h>
+
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultBody.h>
+
+class GeomAPI_Pnt;
+
+/// \class FeaturesPlugin_Loft
+/// \ingroup Plugins
+/// \brief Feature for creation of extrusion along a path.
+/// Pipe creates extrusion of objects along a path.
+/// It produces the following results from objects:
+/// Vertex -> Edge
+/// Edge -> Face
+/// Wire -> Shell
+/// Face -> Solid
+class FeaturesPlugin_Loft : public ModelAPI_Feature
+{
+public:
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_FEATURE_ID("Loft");
+ return MY_FEATURE_ID;
+ }
+
+ /// Attribute name for first object selected.
+ inline static const std::string& FIRST_OBJECT_ID()
+ {
+ static const std::string MY_FIRST_OBJECT("first_object");
+ return MY_FIRST_OBJECT;
+ }
+
+ /// Attribute name for second object selected.
+ inline static const std::string& SECOND_OBJECT_ID()
+ {
+ static const std::string MY_SECOND_OBJECT("second_object");
+ return MY_SECOND_OBJECT;
+ }
+
+ /// \return the kind of a feature.
+ FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = FeaturesPlugin_Loft::ID();
+ return MY_KIND;
+ }
+
+ /// Performs the algorithm and stores results it in the data structure.
+ 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_Loft();
+
+ private:
+ /// Convert shape to edge
+ std::shared_ptr<GeomAPI_Edge> toEdge(const std::shared_ptr<GeomAPI_Shape>& theShape);
+
+ private:
+ std::shared_ptr<GeomAPI_Pnt> myLastEdgeStartPoint;
+ std::shared_ptr<GeomAPI_Pnt> myLastEdgeEndPoint;
+};
+
+#endif
#include <FeaturesPlugin_NormalToFace.h>
#include <FeaturesPlugin_Partition.h>
#include <FeaturesPlugin_Pipe.h>
+#include <FeaturesPlugin_Loft.h>
#include <FeaturesPlugin_Placement.h>
#include <FeaturesPlugin_PointCloudOnFace.h>
#include <FeaturesPlugin_Recover.h>
new FeaturesPlugin_ValidatorPipeLocations);
aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocationsNumber",
new FeaturesPlugin_ValidatorPipeLocationsNumber);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorLoftSameTypeShape",
+ new FeaturesPlugin_ValidatorLoftSameTypeShape);
aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir",
new FeaturesPlugin_ValidatorExtrusionDir);
aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionBoundary",
return FeaturePtr(new FeaturesPlugin_Partition);
} else if (theFeatureID == FeaturesPlugin_Pipe::ID()) {
return FeaturePtr(new FeaturesPlugin_Pipe);
+ } else if (theFeatureID == FeaturesPlugin_Loft::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Loft);
} else if (theFeatureID == FeaturesPlugin_Placement::ID()) {
return FeaturePtr(new FeaturesPlugin_Placement);
} else if (theFeatureID == FeaturesPlugin_Recover::ID()) {
}
// LCOV_EXCL_STOP
+//==================================================================================================
+bool FeaturesPlugin_ValidatorLoftSameTypeShape::isValid(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ static const std::string aFirstObjetcID = "first_object";
+ static const std::string aSecondObjetcID = "second_object";
+
+ if (theFeature->getKind() != "Loft") {
+ theError = "Error: Feature \"%1\" does not supported by this validator.";
+ theError.arg(theFeature->getKind());
+ return false;
+ }
+
+ AttributeSelectionPtr aFirstObjectsSelection = theFeature->selection(aFirstObjetcID);
+ if ( !aFirstObjectsSelection->isInitialized()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aFirstObjetcID);
+ return false;
+ }
+
+ AttributeSelectionPtr aSecondObjectsSelection = theFeature->selection(aSecondObjetcID);
+ if (!aSecondObjectsSelection->isInitialized()) {
+ theError = "Error: Could not get \"%1\" attribute.";
+ theError.arg(aSecondObjetcID);
+ return false;
+ }
+
+ GeomShapePtr aFirstShape = aFirstObjectsSelection->value();
+ if (!aFirstShape.get()) {
+ aFirstShape = aFirstObjectsSelection->context()->shape();
+ }
+ GeomShapePtr aSecondShape = aSecondObjectsSelection->value();
+ if (!aSecondShape.get()) {
+ aSecondShape = aSecondObjectsSelection->context()->shape();
+ }
+
+ if (aFirstShape->isEqual(aSecondShape)) {
+ theError = "Error: the shapes are equal";
+ return false;
+ }
+
+ if (aFirstShape->shapeType()!=aSecondShape->shapeType()) {
+ theError = "Error: the shapes have different type";
+ return false;
+ }
+
+ return true;
+}
+
//==================================================================================================
bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const;
};
+/// \class FeaturesPlugin_ValidatorLoftSameTypeShape
+/// \ingroup Validators
+/// \brief Validator for the same type of shape.
+class FeaturesPlugin_ValidatorLoftSameTypeShape: public ModelAPI_FeatureValidator
+{
+ public:
+ //! \return true if the type of selected are the same
+ //! \param theFeature the checked feature
+ //! \param theArguments arguments of the feature (not used)
+ //! \param theError error message
+ virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
/// \class FeaturesPlugin_ValidatorBaseForGeneration
/// \ingroup Validators
/// \brief A validator for selection base for generation. Allows to select faces on sketch,
<source>Pipe</source>
<translation>Tuyau</translation>
</message>
+ <message>
+ <source>Loft</source>
+ <translation>Lissage</translation>
+ </message>
<message>
<source>Recover</source>
<translation>Récupérer</translation>
</message>
</context>
+ <!-- Loft -->
+ <context>
+ <name>Loft</name>
+ <message>
+ <source>Loft</source>
+ <translation>Lissage</translation>
+ </message>
+ </context>
+ <context>
+ <name>Loft:first_object</name>
+ <message>
+ <source>First object:</source>
+ <translation>Premier objet:</translation>
+ </message>
+ </context>
+ <context>
+ <name>Loft:second_object</name>
+ <message>
+ <source>Second object:</source>
+ <translation>Deuxième objet:</translation>
+ </message>
+ </context>
<!-- Recover -->
<context>
<name>Recover</name>
--- /dev/null
+# Copyright (C) 2018-2022 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Sketch
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+
+### Create SketchLine
+SketchLine_1 = Sketch_1.addLine(65.56914119359536, 34.84279475982533, -62.33478893740904, 34.84279475982533)
+
+### Create SketchLine
+SketchLine_2 = Sketch_1.addLine(-62.33478893740904, 34.84279475982533, -62.33478893740904, -28.08005822416302)
+
+### Create SketchLine
+SketchLine_3 = Sketch_1.addLine(-62.33478893740904, -28.08005822416302, 65.56914119359536, -28.08005822416302)
+
+### Create SketchLine
+SketchLine_4 = Sketch_1.addLine(65.56914119359536, -28.08005822416302, 65.56914119359536, 34.84279475982533)
+Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+Sketch_1.setHorizontal(SketchLine_1.result())
+Sketch_1.setVertical(SketchLine_2.result())
+Sketch_1.setHorizontal(SketchLine_3.result())
+Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+
+### Create Plane
+Plane_4 = model.addPlane(Part_1_doc, model.selection("EDGE", "Sketch_1/SketchLine_4"), model.selection("VERTEX", "Sketch_1/SketchLine_3_StartVertex"), False)
+
+### Create Plane
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f"), 100, False)
+
+### Create Sketch
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+
+### Create SketchCircle
+SketchCircle_1 = Sketch_2.addCircle(60.9581866489876, 39.76685108527785, 26.86156014153439)
+model.do()
+
+### Create Plane
+Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r"), 100, False)
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Box
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Translation
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_2")], axis = model.selection("EDGE", "PartSet/OY"), distance = 100, keepSubResults = True)
+
+### Create Wire
+Wire_1_objects = [model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"),
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"),
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"),
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]")]
+Wire_1 = model.addWire(Part_1_doc, Wire_1_objects, False)
+
+### Create Wire
+Wire_2_objects = [model.selection("EDGE", "[Translation_1_1_1/MF:Translated&Box_2_1/Left][Translation_1_1_1/MF:Translated&Box_2_1/Top]"),
+ model.selection("EDGE", "[Translation_1_1_1/MF:Translated&Box_2_1/Front][Translation_1_1_1/MF:Translated&Box_2_1/Left]"),
+ model.selection("EDGE", "[Translation_1_1_1/MF:Translated&Box_2_1/Left][Translation_1_1_1/MF:Translated&Box_2_1/Bottom]"),
+ model.selection("EDGE", "[Translation_1_1_1/MF:Translated&Box_2_1/Back][Translation_1_1_1/MF:Translated&Box_2_1/Left]")]
+Wire_2 = model.addWire(Part_1_doc, Wire_2_objects, False)
+
+### Create Box
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Wire
+Wire_3 = model.addWire(Part_1_doc, [model.selection("EDGE", "[Box_3_1/Left][Box_3_1/Top]"), model.selection("EDGE", "[Box_3_1/Front][Box_3_1/Left]")], False)
+
+### Create Box
+Box_4 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Translation
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_4")], axis = model.selection("EDGE", "PartSet/OY"), distance = 40, keepSubResults = True)
+
+### Create Wire
+Wire_4 = model.addWire(Part_1_doc, [model.selection("EDGE", "[Translation_2_1_1/MF:Translated&Box_4_1/Left][Translation_2_1_1/MF:Translated&Box_4_1/Top]"), model.selection("EDGE", "[Translation_2_1_1/MF:Translated&Box_4_1/Front][Translation_2_1_1/MF:Translated&Box_4_1/Left]")], False)
+
+### Create Loft
+Loft_1 = model.addLoft(Part_1_doc, model.selection("FACE", "Plane_2"), model.selection("FACE", "Plane_1"))
+
+### Create Loft
+Loft_2 = model.addLoft(Part_1_doc, model.selection("WIRE", "Wire_2_1"), model.selection("WIRE", "Wire_1_1"))
+
+### Create Loft
+Loft_3 = model.addLoft(Part_1_doc, model.selection("WIRE", "Wire_3_1"), model.selection("WIRE", "Wire_4_1"))
+
+### Create Loft
+Loft_4 = model.addLoft(Part_1_doc, model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchLine_4"))
+
+# # Errors tests
+# Wire and Edge
+Box_5 = model.addBox(Part_1_doc, 10, 10, 10)
+Wire_5_objects = [model.selection("EDGE", "[Box_5_1/Back][Box_5_1/Left]"),
+ model.selection("EDGE", "[Box_5_1/Left][Box_5_1/Top]"),
+ model.selection("EDGE", "[Box_5_1/Front][Box_5_1/Left]"),
+ model.selection("EDGE", "[Box_5_1/Left][Box_5_1/Bottom]")]
+Wire_5 = model.addWire(Part_1_doc, Wire_5_objects, False)
+Box_6 = model.addBox(Part_1_doc, 10, 10, 10)
+Loft_5 = model.addLoft(Part_1_doc, model.selection("WIRE", "Wire_5_1"), model.selection("EDGE", "[Box_6_1/Right][Box_6_1/Top]"))
+assert(Loft_5.feature().error() == "Error: the shapes have different type")
+
+# Wire and Face
+Wire_6_objects = [model.selection("EDGE", "[Loft_1_1/Loft_Face_1][Loft_1_1/Loft_Face_5]"),
+ model.selection("EDGE", "[Loft_1_1/Loft_Face_1][Loft_1_1/Loft_Face_4]"),
+ model.selection("EDGE", "[Loft_1_1/Loft_Face_1][Loft_1_1/Loft_Face_2]"),
+ model.selection("EDGE", "[Loft_1_1/Loft_Face_1][Loft_1_1/Loft_Face_6]")]
+Wire_6 = model.addWire(Part_1_doc, Wire_6_objects, False)
+Loft_6 = model.addLoft(Part_1_doc, model.selection("WIRE", "Wire_6_1"), model.selection("EDGE", "Plane_3"))
+assert(Loft_6.feature().error() == "Error: the shapes have different type")
+
+# Only one element
+Box_7 = model.addBox(Part_1_doc, 10, 10, 10)
+Loft_7 = model.addLoft(Part_1_doc, model.selection("SOLID", "Box_7_1"), model.selection())
+assert(Loft_7.feature().error() == 'Error: Could not get "second_object" attribute.')
+
+# Two faces with different number of edges
+Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+Loft_8 = model.addLoft(Part_1_doc, model.selection("FACE", "Cone_1_1/Face_2"), model.selection("EDGE", "Plane_3"))
+
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+#test loft with two face
+model.testNbResults(Loft_1, 1)
+model.testNbSubResults(Loft_1, [0])
+model.testNbSubShapes(Loft_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Loft_1, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(Loft_1, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Loft_1, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Loft_1, [996988.58940])
+
+#test loft with two wire
+model.testNbResults(Loft_2, 1)
+model.testNbSubResults(Loft_2, [0])
+model.testNbSubShapes(Loft_2, GeomAPI_Shape.SHELL, [1])
+model.testNbSubShapes(Loft_2, GeomAPI_Shape.FACE, [4])
+model.testNbSubShapes(Loft_2, GeomAPI_Shape.EDGE, [16])
+model.testNbSubShapes(Loft_2, GeomAPI_Shape.VERTEX, [32])
+model.testResultsVolumes(Loft_2, [0.0])
+
+#test loft with two wire
+model.testNbResults(Loft_3, 1)
+model.testNbSubResults(Loft_3, [0])
+model.testNbSubShapes(Loft_3, GeomAPI_Shape.SHELL, [1])
+model.testNbSubShapes(Loft_3, GeomAPI_Shape.FACE, [2])
+model.testNbSubShapes(Loft_3, GeomAPI_Shape.EDGE, [8])
+model.testNbSubShapes(Loft_3, GeomAPI_Shape.VERTEX, [16])
+model.testResultsVolumes(Loft_3, [0.0])
+
+#test loft with two edge
+model.testNbResults(Loft_4, 1)
+model.testNbSubResults(Loft_4, [0])
+model.testNbSubShapes(Loft_4, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Loft_4, GeomAPI_Shape.EDGE, [4])
+model.testNbSubShapes(Loft_4, GeomAPI_Shape.VERTEX, [8])
+model.testResultsVolumes(Loft_4, [0.0])
+
+#test loft with faces with different number of edges
+model.testNbResults(Loft_8, 1)
+model.testNbSubResults(Loft_8, [0])
+model.testNbSubShapes(Loft_8, GeomAPI_Shape.FACE, [7])
+model.testNbSubShapes(Loft_8, GeomAPI_Shape.EDGE, [30])
+model.testNbSubShapes(Loft_8, GeomAPI_Shape.VERTEX, [60])
+model.testResultsVolumes(Loft_8, [151868.70541])
+
+
+
+
geometryCalculationFeature.rst
importResultFeature.rst
linearCopyFeature.rst
+ loftFeature.rst
measurementFeature.rst
normalToFaceFeature.rst
pipeFeature.rst
--- /dev/null
+
+ .. _tui_loft:
+
+loft
+====
+
+.. literalinclude:: examples/loft.py
+ :linenos:
+ :language: python
+
+:download:`Download this script <examples/loft.py>`
--- /dev/null
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Sketch
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+
+### Create SketchLine
+SketchLine_1 = Sketch_1.addLine(65.56914119359536, 34.84279475982533, -62.33478893740904, 34.84279475982533)
+
+### Create SketchLine
+SketchLine_2 = Sketch_1.addLine(-62.33478893740904, 34.84279475982533, -62.33478893740904, -28.08005822416302)
+
+### Create SketchLine
+SketchLine_3 = Sketch_1.addLine(-62.33478893740904, -28.08005822416302, 65.56914119359536, -28.08005822416302)
+
+### Create SketchLine
+SketchLine_4 = Sketch_1.addLine(65.56914119359536, -28.08005822416302, 65.56914119359536, 34.84279475982533)
+Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+Sketch_1.setHorizontal(SketchLine_1.result())
+Sketch_1.setVertical(SketchLine_2.result())
+Sketch_1.setHorizontal(SketchLine_3.result())
+Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+
+### Create Plane
+Plane_1 = model.addPlane(Part_1_doc, model.selection("EDGE", "Sketch_1/SketchLine_4"), model.selection("VERTEX", "Sketch_1/SketchLine_3_StartVertex"), False)
+
+### Create Plane
+Plane_2 = model.addPlane(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f"), 100, False)
+
+### Create Loft
+Loft_1 = model.addLoft(Part_1_doc, model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2"))
+
+model.end()
--- /dev/null
+.. |loft.icon| image:: images/loft.png
+
+Loft
+====
+
+**Loft** feature is used to create a face, shell or a solid shape from two or more objects.
+The two objects can be edges, wires or faces but must be of the same type
+
+To create a Loft in the active part:
+
+#. select in the Main Menu *Features - > Loft* item or
+#. click |loft.icon| **Loft** button in the toolbar
+
+The following property panel appears.
+
+.. figure:: images/loftPropertyPanel.png
+ :align: center
+
+ Loft property panel
+
+Input fields:
+
+- **First object** defines the first shape (edge, wire, face) selected in 3D OCC viewer or object browser;
+- **Second object** defines the second shape (edge, wire, face) selected in 3D OCC viewer or object browser;
+
+**TUI Command**:
+
+.. py:function:: model.addLoft(Part_doc, [shape], [shape])
+
+ :param part: The current part object.
+ :param object: A shape in format *model.selection(TYPE, shape)*.
+ :param object: A shape in format *model.selection(TYPE, shape)*.
+ :return: Created object.
+
+Result
+""""""
+
+Result of loft between two faces.
+
+.. figure:: images/resultLoft.png
+ :align: center
+
+ Loft between two faces
+
+**See Also** a sample TUI Script of :ref:`tui_loft` operation.
--- /dev/null
+<source>
+ <shape_selector id="first_object"
+ label="First object:"
+ tooltip="Select a object"
+ shape_types="edge face wire"
+ concealment="true"
+ default="">
+ <validator id="GeomValidators_ShapeType" parameters="line,edge,wire,face,shell"/>
+ </shape_selector>
+ <shape_selector id="second_object"
+ label="Second object:"
+ tooltip="Select a object"
+ shape_types="edge face wire"
+ concealment="true"
+ default="">
+ <validator id="GeomValidators_ShapeType" parameters="line,edge,wire,face,shell"/>
+ </shape_selector>
+ <validator id="FeaturesPlugin_ValidatorLoftSameTypeShape"/>
+</source>
icon="icons/Features/pipe.png" helpfile="pipeFeature.html">
<source path="pipe_widget.xml"/>
</feature>
+ <feature id="Loft" title="Loft" tooltip="Generates a shape xwith two elements"
+ icon="icons/Features/loft.png" helpfile="loftFeature.html">
+ <source path="loft_widget.xml"/>
+ </feature>
</group>
<group id="Boolean" toolbar="yes">
<feature id="Cut" title="Cut" tooltip="Perform boolean cut operation with objects"
TestMeasurementAngle3Points.py
TestMeasurementPresentation.py
TestFusionFaces.py
- TestFusionFaces2697.py
+ TestFusionFaces2697.py
Test1379.py
Test1922.py
Test1942.py
TestBoundingBox.py
Test23885.py
TestNormalToFace.py
+ TestLoft.py
)
GeomAlgoAPI_PointCloudOnFace.h
GeomAlgoAPI_Intersection.h
GeomAlgoAPI_Pipe.h
+ GeomAlgoAPI_Loft.h
GeomAlgoAPI_WireBuilder.h
GeomAlgoAPI_Sewing.h
GeomAlgoAPI_ShapeBuilder.h
GeomAlgoAPI_PointCloudOnFace.cpp
GeomAlgoAPI_Intersection.cpp
GeomAlgoAPI_Pipe.cpp
+ GeomAlgoAPI_Loft.cpp
GeomAlgoAPI_WireBuilder.cpp
GeomAlgoAPI_Sewing.cpp
GeomAlgoAPI_ShapeBuilder.cpp
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "GeomAlgoAPI_DFLoader.h"
+#include "GeomAlgoAPI_Loft.h"
+#include "GeomAlgoAPI_WireBuilder.h"
+
+#include <BRepOffsetAPI_ThruSections.hxx>
+#include <Precision.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+
+//==================================================================================================
+GeomAlgoAPI_Loft::GeomAlgoAPI_Loft(const GeomShapePtr theFirstShape, const GeomShapePtr theSecondShape)
+{
+ build(theFirstShape, theSecondShape);
+}
+
+//==================================================================================================
+void GeomAlgoAPI_Loft::build(const GeomShapePtr theFirstShape,
+ const GeomShapePtr theSecondShape)
+{
+ // Getting base shape.
+ if(!theFirstShape.get() || !theSecondShape.get()) {
+ return;
+ }
+ TopoDS_Shape aFirstShape = theFirstShape->impl<TopoDS_Shape>();
+ if(aFirstShape.IsNull()) {
+ return;
+ }
+ TopoDS_Shape aSecondShape= theSecondShape->impl<TopoDS_Shape>();
+ if(aSecondShape.IsNull()) {
+ return;
+ }
+
+ bool anIsSolid = false;
+
+ TopoDS_Shape aFirstShapeOut;
+ TopoDS_Shape aSecondShapeOut;
+ if (aFirstShape.ShapeType() == TopAbs_FACE) {
+ TopExp_Explorer anExp(aFirstShape, TopAbs_WIRE);
+ aFirstShapeOut = anExp.Current();
+ TopExp_Explorer anExp2(aSecondShape, TopAbs_WIRE);
+ aSecondShapeOut = anExp2.Current();
+ anIsSolid = true;
+ }
+
+ if (aFirstShape.ShapeType() == TopAbs_WIRE) {
+ aFirstShapeOut = aFirstShape;
+ aSecondShapeOut = aSecondShape;
+ }
+
+ if (aFirstShape.ShapeType() == TopAbs_EDGE)
+ {
+ GeomShapePtr aFirstWire, aSecondWire;
+ ListOfShape aFirstEdge, aSecondEdge;
+
+ // Convert first edge to wire
+ aFirstEdge.push_back(theFirstShape);
+ aFirstWire = GeomAlgoAPI_WireBuilder::wire(aFirstEdge);
+ TopoDS_Shape aFirstShape = aFirstWire->impl<TopoDS_Shape>();
+
+ // Convert first edge to wire
+ aSecondEdge.push_back(theSecondShape);
+ aSecondWire = GeomAlgoAPI_WireBuilder::wire(aSecondEdge);
+ TopoDS_Shape aSecondShape = aSecondWire->impl<TopoDS_Shape>();
+
+ aFirstShapeOut = aFirstShape;
+ aSecondShapeOut = aSecondShape;
+ }
+
+ // Initialize and build
+ BRepOffsetAPI_ThruSections * ThruSections =
+ new BRepOffsetAPI_ThruSections(anIsSolid);
+ ThruSections->AddWire( TopoDS::Wire( aFirstShapeOut ) );
+ ThruSections->AddWire( TopoDS::Wire( aSecondShapeOut) );
+
+ try
+ {
+ ThruSections->Build();
+ }
+ catch (Standard_Failure& aFail)
+ {
+ delete ThruSections;
+ return;
+ }
+ // Checking result.
+ if(!ThruSections->IsDone() || ThruSections->Shape().IsNull()) {
+ delete ThruSections;
+ return;
+ }
+
+ this->initialize(ThruSections);
+
+ // Setting result.
+ TopoDS_Shape aResult = ThruSections->Shape();
+ aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
+ GeomShapePtr aGeomSh(new GeomAPI_Shape());
+ aGeomSh->setImpl(new TopoDS_Shape(aResult));
+ this->setShape(aGeomSh);
+ this->setDone(true);
+}
--- /dev/null
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef GeomAlgoAPI_Loft_H_
+#define GeomAlgoAPI_Loft_H_
+
+#include "GeomAlgoAPI.h"
+
+#include "GeomAlgoAPI_MakeShape.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Loft
+/// \ingroup DataAlgo
+/// \brief Allows to create loft of two objects with same type.
+/// It produces the following results from objects:
+/// 2 edges -> Face
+/// 2 Wire -> Shell
+/// 2 Face -> Solid
+class GeomAlgoAPI_Loft : public GeomAlgoAPI_MakeShape
+{
+ public:
+ /// \brief Creates loft for two given shape with same type.
+ /// \param[in] theFirstShape the first shape.
+ /// \param[in] theSecondShape the second shape.
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Loft(const GeomShapePtr theFirstShape,
+ const GeomShapePtr theSecondShape);
+
+ private:
+ void build(const GeomShapePtr theFirstShape,
+ const GeomShapePtr theSecondShape);
+
+};
+
+#endif
from FeaturesAPI import addMultiTranslation, addMultiRotation
from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse
from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse
-from FeaturesAPI import addPipe
+from FeaturesAPI import addPipe, addLoft
from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addSplit
from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes
from FeaturesAPI import addRecover