From a3536bed7945f69ac169315c62db30b9058dc10e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Wed, 21 Oct 2020 19:26:35 +0200 Subject: [PATCH] Implementation create normal to face --- src/Config/Config_Keywords.h | 1 + src/FeaturesAPI/CMakeLists.txt | 2 + src/FeaturesAPI/FeaturesAPI.i | 2 + src/FeaturesAPI/FeaturesAPI_NormalToFace.cpp | 119 +++++++++ src/FeaturesAPI/FeaturesAPI_NormalToFace.h | 88 +++++++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesPlugin/CMakeLists.txt | 23 +- .../FeaturesPlugin_NormalToFace.cpp | 123 +++++++++ .../FeaturesPlugin_NormalToFace.h | 92 +++++++ src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 3 + src/FeaturesPlugin/NormalToFace_widget.xml | 23 ++ src/FeaturesPlugin/icons/normale.png | Bin 0 -> 655 bytes src/FeaturesPlugin/plugin-Features.xml | 12 +- src/GeomAlgoAPI/CMakeLists.txt | 3 + src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.cpp | 241 ++++++++++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.h | 46 ++++ src/ModelAPI/CMakeLists.txt | 8 +- src/ModuleBase/ModuleBase_WidgetLabel.cpp | 4 + src/PythonAPI/model/features/__init__.py | 1 + 19 files changed, 783 insertions(+), 9 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_NormalToFace.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_NormalToFace.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_NormalToFace.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_NormalToFace.h create mode 100644 src/FeaturesPlugin/NormalToFace_widget.xml create mode 100644 src/FeaturesPlugin/icons/normale.png create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.h diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index 5be23a997..28783fd69 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -100,6 +100,7 @@ MAYBE_UNUSED const static char* ATTR_TOOLTIP = FEATURE_TOOLTIP; MAYBE_UNUSED const static char* ATTR_ICON = FEATURE_ICON; MAYBE_UNUSED const static char* ATTR_LABEL = "label"; MAYBE_UNUSED const static char* ATTR_STYLE_SHEET = "styleSheet"; +MAYBE_UNUSED const static char* ATTR_IS_SELECTABLE = "isSelectable"; MAYBE_UNUSED const static char* ATTR_HTML_STYLE = "isHTML"; MAYBE_UNUSED const static char* ATTR_DEFAULT = "default"; MAYBE_UNUSED const static char* ATTR_INTERNAL = "internal"; diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 0b8e3055c..9354f2e37 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Fillet.h FeaturesAPI_Intersection.h FeaturesAPI_Measurement.h + FeaturesAPI_NormalToFace.h FeaturesAPI_MultiRotation.h FeaturesAPI_MultiTranslation.h FeaturesAPI_Partition.h @@ -65,6 +66,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Fillet.cpp FeaturesAPI_Intersection.cpp FeaturesAPI_Measurement.cpp + FeaturesAPI_NormalToFace.cpp FeaturesAPI_MultiRotation.cpp FeaturesAPI_MultiTranslation.cpp FeaturesAPI_Partition.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index b76fd2dc4..4049a3d86 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -63,6 +63,7 @@ %shared_ptr(FeaturesAPI_BooleanSmash) %shared_ptr(FeaturesAPI_BooleanFill) %shared_ptr(FeaturesAPI_Chamfer) +%shared_ptr(FeaturesAPI_NormalToFace) %shared_ptr(FeaturesAPI_Extrusion) %shared_ptr(FeaturesAPI_ExtrusionBoolean) %shared_ptr(FeaturesAPI_ExtrusionCut) @@ -211,6 +212,7 @@ %include "FeaturesAPI_Fillet.h" %include "FeaturesAPI_Intersection.h" %include "FeaturesAPI_Measurement.h" +%include "FeaturesAPI_NormalToFace.h" %include "FeaturesAPI_MultiRotation.h" %include "FeaturesAPI_MultiTranslation.h" %include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesAPI/FeaturesAPI_NormalToFace.cpp b/src/FeaturesAPI/FeaturesAPI_NormalToFace.cpp new file mode 100644 index 000000000..d6453ad80 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_NormalToFace.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2017-2020 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_NormalToFace.h" + + +#include +#include +#include + + +FeaturesAPI_NormalToFace:: + FeaturesAPI_NormalToFace(const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +FeaturesAPI_NormalToFace::FeaturesAPI_NormalToFace( + const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theBaseFace, + const ModelHighAPI_Selection& theOptionnelPoint ) +:ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theBaseFace, myfaceselected); + fillAttribute(theOptionnelPoint, myvertexselected); + feature()->string(FeaturesPlugin_NormalToFace::VERTEX_OPTION_ID())->setValue("true"); + execute(); + } +} + +FeaturesAPI_NormalToFace::FeaturesAPI_NormalToFace( + const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theBaseFace) +:ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theBaseFace, myfaceselected); + feature()->string(FeaturesPlugin_NormalToFace::VERTEX_OPTION_ID())->setValue(""); + execute(); + } +} + +FeaturesAPI_NormalToFace::~FeaturesAPI_NormalToFace() +{ +} + +void FeaturesAPI_NormalToFace::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionPtr anAttrObject; + anAttrObject = aBase->selection(FeaturesPlugin_NormalToFace::OBJECTS_LIST_ID()); + + theDumper << aBase << " = model.getNormal(" << aDocName << ", " << anAttrObject; + + if ( !aBase->string(FeaturesPlugin_NormalToFace::VERTEX_OPTION_ID())->value().empty()){ + + AttributeSelectionPtr anAttrVertex = + aBase->selection(FeaturesPlugin_NormalToFace::VERTEX_SELECTED_ID()); + + theDumper << ", " << anAttrVertex; + } + + //if (!aBase->data()->version().empty()) + // theDumper << ", keepSubResults = True"; + + theDumper << ")" << std::endl; +} + +//================================================================================================== + +NormalPtr getNormal(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theBaseFace, + const ModelHighAPI_Selection& theOptionnelPoint) +{ + + FeaturePtr aFeature = + thePart->addFeature(FeaturesAPI_NormalToFace::ID()); + + NormalPtr aNormalToface; + + aNormalToface.reset(new FeaturesAPI_NormalToFace(aFeature, theBaseFace, theOptionnelPoint)); + + return aNormalToface; +} + +NormalPtr getNormal(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theBaseFace) +{ + + FeaturePtr aFeature = + thePart->addFeature(FeaturesAPI_NormalToFace::ID()); + + NormalPtr aNormalToface; + + aNormalToface.reset(new FeaturesAPI_NormalToFace(aFeature, theBaseFace)); + + return aNormalToface; +} + diff --git a/src/FeaturesAPI/FeaturesAPI_NormalToFace.h b/src/FeaturesAPI/FeaturesAPI_NormalToFace.h new file mode 100644 index 000000000..10554383c --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_NormalToFace.h @@ -0,0 +1,88 @@ +// Copyright (C) 2017-2020 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_NormalToFace_H_ +#define FeaturesAPI_NormalToFace_H_ + +#include "FeaturesAPI.h" + +#include + +#include +#include + + +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_NormalToFace +/// \ingroup CPPHighAPI +/// \brief Interface for NormalToface feature. +class FeaturesAPI_NormalToFace: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_NormalToFace(const std::shared_ptr& theFeature); + + FEATURESAPI_EXPORT + explicit FeaturesAPI_NormalToFace(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theBaseFace, + const ModelHighAPI_Selection& theOptionnelPoint ); + + FEATURESAPI_EXPORT + explicit FeaturesAPI_NormalToFace(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theBaseFace); + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_NormalToFace(); + + INTERFACE_3(FeaturesPlugin_NormalToFace::ID(), + faceselected, FeaturesPlugin_NormalToFace::OBJECTS_LIST_ID(), + ModelAPI_AttributeSelection, + /** base face */, + vertexselected, FeaturesPlugin_NormalToFace::VERTEX_SELECTED_ID(), + ModelAPI_AttributeSelection, + /** vetex option */, + vertexoption, FeaturesPlugin_NormalToFace::VERTEX_OPTION_ID(), + ModelAPI_AttributeString, + /** option */) + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; + +}; + +/// Pointer on the NormalToface object. +typedef std::shared_ptr NormalPtr; + +/// \ingroup CPPHighAPI +/// \brief Create NormalToFace feature. +FEATURESAPI_EXPORT +NormalPtr getNormal(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theBaseFace, + const ModelHighAPI_Selection& theOptionnelPoint); + +/// \ingroup CPPHighAPI +/// \brief Create NormalToFace feature. +FEATURESAPI_EXPORT +NormalPtr getNormal(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theBaseFace); + +#endif // FeaturesAPI_Fillet_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index 17ada7187..a9320e0ea 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -35,6 +35,7 @@ #include "FeaturesAPI_Fillet.h" #include "FeaturesAPI_Intersection.h" #include "FeaturesAPI_Measurement.h" + #include "FeaturesAPI_NormalToFace.h" #include "FeaturesAPI_MultiRotation.h" #include "FeaturesAPI_MultiTranslation.h" #include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index c93c66a17..3e8ae8999 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -19,6 +19,17 @@ INCLUDE(Common) INCLUDE(UnitTest) +INCLUDE(UseQtExt) + +# additional include directories +INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GeomDataAPI + ${PROJECT_SOURCE_DIR}/src/Locale + ${PROJECT_SOURCE_DIR}/src/PrimitivesPlugin + ${QT_INCLUDES}) + +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + SET(PROJECT_HEADERS FeaturesPlugin.h @@ -59,6 +70,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_Fillet.h FeaturesPlugin_Fillet1D.h FeaturesPlugin_Measurement.h + FeaturesPlugin_NormalToFace.h FeaturesPlugin_FusionFaces.h FeaturesPlugin_RemoveResults.h FeaturesPlugin_Chamfer.h @@ -106,6 +118,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_Fillet.cpp FeaturesPlugin_Fillet1D.cpp FeaturesPlugin_Measurement.cpp + FeaturesPlugin_NormalToFace.cpp FeaturesPlugin_FusionFaces.cpp FeaturesPlugin_RemoveResults.cpp FeaturesPlugin_Chamfer.cpp @@ -144,6 +157,7 @@ SET(XML_RESOURCES fillet_widget.xml fillet1d_widget.xml measurement_widget.xml + NormalToFace_widget.xml fusion_faces_widget.xml chamfer_widget.xml copy_widget.xml @@ -166,6 +180,7 @@ INCLUDE_DIRECTORIES( ../GeomAPI ../GeomAlgoAPI ../GeomValidators + ../ModuleBase ../Events ../Config ${OpenCASCADE_INCLUDE_DIR} @@ -182,7 +197,11 @@ SET(PROJECT_LIBRARIES ) ADD_DEFINITIONS(-DFEATURESPLUGIN_EXPORTS) -ADD_LIBRARY(FeaturesPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES}) +ADD_LIBRARY(FeaturesPlugin MODULE + ${PROJECT_SOURCES} + ${PROJECT_HEADERS} + ${XML_RESOURCES} + ${TEXT_RESOURCES}) TARGET_LINK_LIBRARIES(FeaturesPlugin ${PROJECT_LIBRARIES}) INSTALL(TARGETS FeaturesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) @@ -682,6 +701,4 @@ ADD_UNIT_TESTS(TestExtrusion.py TestFillet1D_Wire_3.py TestFillet1D_Wire_4.py TestFillet1D_Wire_5.py - Test19931.py - Test20027.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.cpp b/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.cpp new file mode 100644 index 000000000..87dc63683 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2018-2020 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_NormalToFace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +FeaturesPlugin_NormalToFace::FeaturesPlugin_NormalToFace() +{ +} + +void FeaturesPlugin_NormalToFace::initAttributes() +{ + // attribute for object selected + data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(VERTEX_SELECTED_ID(), ModelAPI_AttributeSelection::typeId()); + // attributes for result message and values + data()->addAttribute(CREATENORMAL_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(VERTEX_OPTION_ID(), ModelAPI_AttributeString::typeId()); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VERTEX_SELECTED_ID()); + +} + +void FeaturesPlugin_NormalToFace::execute() +{ + AttributeSelectionPtr aSelectionFace = selection(OBJECTS_LIST_ID()); + AttributeSelectionPtr aSelectionPoint = selection(VERTEX_SELECTED_ID()); + + GeomShapePtr aShape; + GeomShapePtr aShapePoint; + if(!string(VERTEX_OPTION_ID())->value().empty()) + { + if (aSelectionPoint && aSelectionPoint->isInitialized()) { + aShapePoint = aSelectionPoint->value(); + if (!aShapePoint && aSelectionPoint->context()) + aShapePoint = aSelectionPoint->context()->shape(); + } + } + + if (aSelectionFace && aSelectionFace->isInitialized()) { + aShape = aSelectionFace->value(); + if (!aShape && aSelectionFace->context()) + aShape = aSelectionFace->context()->shape(); + } + + if (aShape){ + std::string aError; + std::shared_ptr theNormal(new GeomAPI_Edge); + if( !GeomAlgoAPI_NormalToFace::normal(aShape, + aShapePoint, + theNormal, + aError)) + setError("Error in bounding box calculation :" + aError); + + ResultBodyPtr aResultBody = document()->createBody(data()); + if( boolean(CREATENORMAL_ID())->value() ) + { + eraseResults(); + std::shared_ptr anEdge = + GeomAlgoAPI_EdgeBuilder::line(theNormal->firstPoint(), + theNormal->lastPoint()); + + ResultConstructionPtr aConstr = document()->createConstruction(data()); + aConstr->setInfinite(true); + aConstr->setShape(anEdge); + setResult(aConstr); + }else + { + eraseResults(); + // Load the result + aResultBody->store(theNormal); + /*int aVertexIndex = 1; + for (GeomAPI_ShapeExplorer anExp(theNormal, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) { + std::string aVertexName = "VertexFromNormal_" + std::to_string((long long)aVertexIndex); + aResultBody->generated(anExp.current(), aVertexName); + aVertexIndex++; + }*/ + setResult(aResultBody); + } + } +} + +void FeaturesPlugin_NormalToFace::attributeChanged(const std::string& theID) +{ +} + + diff --git a/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.h b/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.h new file mode 100644 index 000000000..fa6e8b3dc --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_NormalToFace.h @@ -0,0 +1,92 @@ +// Copyright (C) 2018-2020 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_NormalToFace_H_ +#define FeaturesPlugin_NormalToFace_H_ + +#include "FeaturesPlugin.h" +#include + +#include +#include +#include + +/// \class FeaturesPlugin_NormalToFace +/// \ingroup Plugins +/// \brief Feature for construct normal to face + +class FeaturesPlugin_NormalToFace : public ModelAPI_Feature +{ +public: + inline static const std::string& ID() + { + static const std::string MY_ID("Normal"); + return MY_ID; + } + + /// \return the kind of a feature. + virtual const std::string& getKind() + { + return ID(); + } + + /// Attribute name for face selected. + inline static const std::string& OBJECTS_LIST_ID() + { + static const std::string MY_OBJECTS_LIST_ID("main_objects"); + return MY_OBJECTS_LIST_ID; + } + + /// Attribute name for vertex selected. + inline static const std::string& VERTEX_SELECTED_ID() + { + static const std::string MY_VERTEX_SELECTED_ID("tool_objects"); + return MY_VERTEX_SELECTED_ID; + } + + /// Attribute name for checkbox create box. + inline static const std::string& CREATENORMAL_ID() + { + static const std::string MY_CREATENORMAL_ID("createnormal"); + return MY_CREATENORMAL_ID; + } + + /// Attribute name of vertex option. + inline static const std::string& VERTEX_OPTION_ID() + { + static const std::string MY_VERTEX_OPTION_ID("vertex_option"); + return MY_VERTEX_OPTION_ID; + } + + /// 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(); + + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + + /// Use plugin manager for features creation + FeaturesPlugin_NormalToFace(); + +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 0d49dfe08..b4dabda19 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Fillet1D); } else if (theFeatureID == FeaturesPlugin_Measurement::ID()) { return FeaturePtr(new FeaturesPlugin_Measurement); + } else if (theFeatureID == FeaturesPlugin_NormalToFace::ID()) { + return FeaturePtr(new FeaturesPlugin_NormalToFace); } else if (theFeatureID == FeaturesPlugin_RemoveResults::ID()) { return FeaturePtr(new FeaturesPlugin_RemoveResults); } else if (theFeatureID == FeaturesPlugin_Chamfer::ID()) { diff --git a/src/FeaturesPlugin/NormalToFace_widget.xml b/src/FeaturesPlugin/NormalToFace_widget.xml new file mode 100644 index 000000000..e130762e4 --- /dev/null +++ b/src/FeaturesPlugin/NormalToFace_widget.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/normale.png b/src/FeaturesPlugin/icons/normale.png new file mode 100644 index 0000000000000000000000000000000000000000..16080764e8d275a433c96cfb3c849a9d1bd931e0 GIT binary patch literal 655 zcmV;A0&x9_P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;1xZ9fRCwBA{Qv(y12q9a05LI882|(jQ3hU9S0~yV z00G3r$jHb*2!jAI>OdGEfT-?efB+(B;8iuX|41|kA@u+OM5+q~2q^#vAVy+bhYYlD z-NLH}Ab^NL98iM;f!KhMw*dl(7%y`mc~_8-fdB!-LclO&FV7=nvzV9|13&=bGw}b! z4ObYx|N6tgP!q;bGUp`2-@pGD{`~vT@ay+KhHpQAGra%ui{bO<&kVo5ePp<`x{Tq~ zt5=Eu0ffuI|C2XeW%&Bz4;X{M=Wo9me*XRow%`+x{q5@)hM%9`GW`7dp5gws4u%gO zJ|qE^SpozQwix^0v-T3$pwHiaF(h`!!6kBo`Wb$I2fFCXJBFWM-ZK0G8us|$Y>+FP zfzm&K_&z`Yp&R(WYQbrS&)X&M03jRrKW)-shL2x=F}wvD^yABWpbI`Q`~e#B=jS(uzrVf# z* + icon="icons/Features/fillet.png" auto_preview="false" helpfile="filletFeature.html"> + icon="icons/Features/fusion_faces.png" auto_preview="true" helpfile="FeaturesPlugin/fusionFacesFeature.html"> - + + + + + + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 95e749c10..cf8f9dd94 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Prism.h GeomAlgoAPI_Revolution.h GeomAlgoAPI_Boolean.h + GeomAlgoAPI_NormalToFace.h GeomAlgoAPI_ThroughAll.h GeomAlgoAPI_Rotation.h GeomAlgoAPI_Translation.h @@ -98,6 +99,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Prism.cpp GeomAlgoAPI_Revolution.cpp GeomAlgoAPI_Boolean.cpp + GeomAlgoAPI_NormalToFace.cpp GeomAlgoAPI_ThroughAll.cpp GeomAlgoAPI_Rotation.cpp GeomAlgoAPI_Translation.cpp @@ -176,6 +178,7 @@ INCLUDE_DIRECTORIES( ../GeomAlgoImpl ../ModelAPI ../XAO + ${PROJECT_SOURCE_DIR}/src/Locale ${OpenCASCADE_INCLUDE_DIR} ) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.cpp new file mode 100644 index 000000000..b39bbc8c3 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.cpp @@ -0,0 +1,241 @@ +// Copyright (C) 2014-2020 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_NormalToFace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + /*! + * \brief Return type of shape for explode. In case of compound it will be a type of its first sub shape. + * \param theShape The shape to get type of. + * \retval TopAbs_ShapeEnum Return type of shape for explode. + */ +TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape) +{ + TopAbs_ShapeEnum aType = theShape.ShapeType(); + if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; + else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; + else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; + else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; + else if (aType == TopAbs_COMPOUND) { + // Only the iType of the first shape in the compound is taken into account + TopoDS_Iterator It (theShape, Standard_False, Standard_False); + if (It.More()) { + return GetTypeOfSimplePart(It.Value()); + } + } + return TopAbs_SHAPE; +} + + /*! + * \brief Get Local Coordinate System, corresponding to the given shape. + * + * Origin of the LCS is situated at the shape's center of mass. + * Axes of the LCS are obtained from shape's location or, + * if the shape is a planar face, from position of its plane. + */ +gp_Ax3 GetPosition (const TopoDS_Shape& theShape) +{ + gp_Ax3 aResult; + + if (theShape.IsNull()) + return aResult; + + // Axes + aResult.Transform(theShape.Location().Transformation()); + if (theShape.ShapeType() == TopAbs_FACE) { + Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape)); + if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) { + Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS); + gp_Pln aPln = aGPlane->Pln(); + aResult = aPln.Position(); + // In case of reverse orinetation of the face invert the plane normal + // (the face's normal does not mathc the plane's normal in this case) + if(theShape.Orientation() == TopAbs_REVERSED) + { + gp_Dir Vx = aResult.XDirection(); + gp_Dir N = aResult.Direction().Mirrored(Vx); + gp_Pnt P = aResult.Location(); + aResult = gp_Ax3(P, N, Vx); + } + } + } + + // Origin + gp_Pnt aPnt; + + TopAbs_ShapeEnum aShType = theShape.ShapeType(); + + if (aShType == TopAbs_VERTEX) { + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); + } + else { + if (aShType == TopAbs_COMPOUND) { + aShType = GetTypeOfSimplePart(theShape); + } + + GProp_GProps aSystem; + if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) + BRepGProp::LinearProperties(theShape, aSystem); + else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) + BRepGProp::SurfaceProperties(theShape, aSystem); + else + BRepGProp::VolumeProperties(theShape, aSystem); + + aPnt = aSystem.CentreOfMass(); + } + + aResult.SetLocation(aPnt); + + return aResult; +} + +//================================================================================================= +static bool GeomAlgoAPI_NormalToFace::normal(GeomShapePtr theFace, + GeomShapePtr theOptionnelPoint, + GeomEdgePtr theNormal, + std::string& theError){ + + #ifdef _DEBUG + std::cout << "GeomAlgoAPI_NormalToFace::normal" << std::endl; + #endif + + if (!theFace.get()) { + theError = "Face for normale calculation is null"; + return false; + } + + TopoDS_Shape aShape = theFace->impl(); + + if (aShape.ShapeType() != TopAbs_FACE) { + theError = "Shape for normale calculation is not a face"; + return false; + } + + TopoDS_Face aFace = TopoDS::Face(aShape); + + // Point + gp_Pnt p1 (0,0,0); + + if (theOptionnelPoint.get()) { + TopoDS_Shape anOptPnt = theOptionnelPoint->impl(); + if (anOptPnt.IsNull()){ + theError = "Invalid shape given for point argument"; + return false; + } + p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt)); + } + else + { + gp_Ax3 aPos = GetPosition(aFace); + p1 = aPos.Location(); + } + + // Point parameters on surface + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf); + gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion()); + + // Normal direction + gp_Vec Vec1,Vec2; + BRepAdaptor_Surface SF (aFace); + SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2); + if (Vec1.Magnitude() < Precision::Confusion()) { + gp_Vec tmpV; + gp_Pnt tmpP; + SF.D1(pUV.X(), pUV.Y()-0.1, tmpP, Vec1, tmpV); + } + else if (Vec2.Magnitude() < Precision::Confusion()) { + gp_Vec tmpV; + gp_Pnt tmpP; + SF.D1(pUV.X()-0.1, pUV.Y(), tmpP, tmpV, Vec2); + } + + gp_Vec V = Vec1.Crossed(Vec2); + Standard_Real mod = V.Magnitude(); + if (mod < Precision::Confusion()) + Standard_NullObject::Raise("Normal vector of a face has null magnitude"); + + // Set length of normal vector to average radius of curvature + Standard_Real radius = 0.0; + GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion()); + if (aProperties.IsCurvatureDefined()) { + Standard_Real radius1 = Abs(aProperties.MinCurvature()); + Standard_Real radius2 = Abs(aProperties.MaxCurvature()); + if (Abs(radius1) > Precision::Confusion()) { + radius = 1.0 / radius1; + if (Abs(radius2) > Precision::Confusion()) { + radius = (radius + 1.0 / radius2) / 2.0; + } + } + else { + if (Abs(radius2) > Precision::Confusion()) { + radius = 1.0 / radius2; + } + } + } + + // Set length of normal vector to average dimension of the face + // (only if average radius of curvature is not appropriate) + if (radius < Precision::Confusion()) { + Bnd_Box B; + Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; + BRepBndLib::Add(aFace, B); + B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0; + } + + if (radius < Precision::Confusion()) + radius = 1.0; + + V *= radius / mod; + + // consider the face orientation + if (aFace.Orientation() == TopAbs_REVERSED || + aFace.Orientation() == TopAbs_INTERNAL) { + V = - V; + } + + // Edge + gp_Pnt p2 = p1.Translated(V); + BRepBuilderAPI_MakeEdge aBuilder (p1, p2); + if (!aBuilder.IsDone()) + Standard_NullObject::Raise("Vector construction failed"); + aShape = aBuilder.Shape(); + + theNormal->setImpl(new TopoDS_Shape(aShape)); + + return true; + +} + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.h b/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.h new file mode 100644 index 000000000..5bf44a3d1 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_NormalToFace.h @@ -0,0 +1,46 @@ +// Copyright (C) 2014-2020 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_NormalToFace_H_ +#define GeomAlgoAPI_NormalToFace_H_ + +#include +#include +#include +#include +#include + +/**\class GeomAlgoAPI_NormalToFace + * \ingroup DataAlgo + * \brief Allows to create normal to face-shapes + */ + +class GEOMALGOAPI_EXPORT GeomAlgoAPI_NormalToFace +{ + public: + /// get the boundin box of theshape. + /// \param theface the face + /// \param theOptionnelPoint the optionnel point + static bool GeomAlgoAPI_NormalToFace::normal(GeomShapePtr theFace, + GeomShapePtr theOptionnelPoint, + GeomEdgePtr theNormal, + std::string& theError); +}; + +#endif diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index dd2f4acd9..7b7876165 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -117,7 +117,7 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES Config GeomAPI - Locale + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473) ADD_DEFINITIONS(-DMODELAPI_EXPORTS) @@ -131,6 +131,10 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ${PROJECT_SOURCE_DIR}/src/Locale + ${OpenCASCADE_INCLUDE_DIR} + ${OpenCASCADE_DataExchange_LIBRARIES} + ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) @@ -265,6 +269,4 @@ ADD_UNIT_TESTS(TestConstants.py Test19707.py Test19726.py Test19912.py - Test19932.py - Test19989.py ) diff --git a/src/ModuleBase/ModuleBase_WidgetLabel.cpp b/src/ModuleBase/ModuleBase_WidgetLabel.cpp index 7a47835c8..7e3f86de0 100644 --- a/src/ModuleBase/ModuleBase_WidgetLabel.cpp +++ b/src/ModuleBase/ModuleBase_WidgetLabel.cpp @@ -61,6 +61,10 @@ ModuleBase_WidgetLabel::ModuleBase_WidgetLabel(QWidget* theParent, std::string aStyleSheet = theData->getProperty(ATTR_STYLE_SHEET); if (!aStyleSheet.empty()) myLabel->setStyleSheet(QString("QLabel {%1}").arg(aStyleSheet.c_str())); + + aStyleSheet = theData->getProperty(ATTR_IS_SELECTABLE); + if ( aStyleSheet == "true") + myLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); } ModuleBase_WidgetLabel::~ModuleBase_WidgetLabel() diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 772dc05c2..1a1547d52 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -30,6 +30,7 @@ from FeaturesAPI import addRecover from FeaturesAPI import addFillet, addChamfer from FeaturesAPI import addFusionFaces from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle +from FeaturesAPI import getNormal from FeaturesAPI import addRemoveResults from FeaturesAPI import addCopy, addImportResult from FeaturesAPI import addDefeaturing -- 2.39.2