CMAKE_POLICY(SET CMP0020 OLD) # disable automatic linking to qtmain.lib
ENDIF(WIN32)
-SET (SHAPER_Version 2.9.1)
+SET (SHAPER_Version 2.10.0RC)
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH})
# High Level C++/Python API
ADD_SUBDIRECTORY (src/ModelHighAPI)
ADD_SUBDIRECTORY (src/BuildAPI)
-ADD_SUBDIRECTORY (src/ConnectorAPI)
ADD_SUBDIRECTORY (src/ConstructionAPI)
ADD_SUBDIRECTORY (src/ExchangeAPI)
ADD_SUBDIRECTORY (src/FeaturesAPI)
ADD_SUBDIRECTORY (src/PrimitivesAPI)
ADD_SUBDIRECTORY (src/SketchAPI)
ADD_SUBDIRECTORY (src/GDMLAPI)
+ADD_SUBDIRECTORY (src/ConnectorAPI)
# Tests
ADD_SUBDIRECTORY (test.API/SHAPER)
%include "std_shared_ptr.i"
// shared pointers
+%shared_ptr(BuildAPI_Compound)
+%shared_ptr(BuildAPI_CompSolid)
%shared_ptr(BuildAPI_Edge)
%shared_ptr(BuildAPI_Face)
+%shared_ptr(BuildAPI_Filling)
%shared_ptr(BuildAPI_Shell)
+%shared_ptr(BuildAPI_Solid)
%shared_ptr(BuildAPI_SubShapes)
%shared_ptr(BuildAPI_Vertex)
%shared_ptr(BuildAPI_Wire)
// all supported interfaces
+%include "BuildAPI_Compound.h"
+%include "BuildAPI_CompSolid.h"
%include "BuildAPI_Edge.h"
%include "BuildAPI_Face.h"
+%include "BuildAPI_Filling.h"
%include "BuildAPI_Shell.h"
+%include "BuildAPI_Solid.h"
%include "BuildAPI_SubShapes.h"
%include "BuildAPI_Vertex.h"
%include "BuildAPI_Wire.h"
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildAPI_CompSolid.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+BuildAPI_CompSolid::BuildAPI_CompSolid(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+//==================================================================================================
+BuildAPI_CompSolid::BuildAPI_CompSolid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+: ModelHighAPI_Interface(theFeature)
+{
+ if(initialize()) {
+ setBase(theBaseObjects);
+ }
+}
+
+//==================================================================================================
+BuildAPI_CompSolid::~BuildAPI_CompSolid()
+{
+}
+
+//==================================================================================================
+void BuildAPI_CompSolid::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ fillAttribute(theBaseObjects, mybaseObjects);
+ execute();
+}
+
+//==================================================================================================
+void BuildAPI_CompSolid::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ std::string aPartName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.addCompSolid(" << aPartName << ", "
+ << aBase->selectionList(BuildPlugin_CompSolid::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
+//==================================================================================================
+CompSolidPtr addCompSolid(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_CompSolid::ID());
+ return CompSolidPtr(new BuildAPI_CompSolid(aFeature, theBaseObjects));
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildAPI_CompSolid_H_
+#define BuildAPI_CompSolid_H_
+
+#include "BuildAPI.h"
+
+#include <BuildPlugin_CompSolid.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Selection;
+
+/// \class BuildAPI_CompSolid
+/// \ingroup CPPHighAPI
+/// \brief Interface for CompSolid feature.
+class BuildAPI_CompSolid: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_CompSolid(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_CompSolid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Destructor.
+ BUILDAPI_EXPORT
+ virtual ~BuildAPI_CompSolid();
+
+ INTERFACE_1(BuildPlugin_CompSolid::ID(),
+ baseObjects, BuildPlugin_CompSolid::BASE_OBJECTS_ID(),
+ ModelAPI_AttributeSelectionList, /** Base objects */)
+
+ /// Modify base attribute of the feature.
+ BUILDAPI_EXPORT
+ void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Dump wrapped feature
+ BUILDAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on CompSolid object.
+typedef std::shared_ptr<BuildAPI_CompSolid> CompSolidPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create CompSolid feature.
+BUILDAPI_EXPORT
+CompSolidPtr addCompSolid(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+#endif // BuildAPI_CompSolid_H_
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildAPI_Compound.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+BuildAPI_Compound::BuildAPI_Compound(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+//==================================================================================================
+BuildAPI_Compound::BuildAPI_Compound(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+: ModelHighAPI_Interface(theFeature)
+{
+ if(initialize()) {
+ setBase(theBaseObjects);
+ }
+}
+
+//==================================================================================================
+BuildAPI_Compound::~BuildAPI_Compound()
+{
+}
+
+//==================================================================================================
+void BuildAPI_Compound::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ fillAttribute(theBaseObjects, mybaseObjects);
+ execute();
+}
+
+//==================================================================================================
+void BuildAPI_Compound::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ std::string aPartName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.addCompound(" << aPartName << ", "
+ << aBase->selectionList(BuildPlugin_Compound::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
+//==================================================================================================
+CompoundPtr addCompound(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Compound::ID());
+ return CompoundPtr(new BuildAPI_Compound(aFeature, theBaseObjects));
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildAPI_Compound_H_
+#define BuildAPI_Compound_H_
+
+#include "BuildAPI.h"
+
+#include <BuildPlugin_Compound.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Selection;
+
+/// \class BuildAPI_Compound
+/// \ingroup CPPHighAPI
+/// \brief Interface for Compound feature.
+class BuildAPI_Compound: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Compound(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Compound(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Destructor.
+ BUILDAPI_EXPORT
+ virtual ~BuildAPI_Compound();
+
+ INTERFACE_1(BuildPlugin_Compound::ID(),
+ baseObjects, BuildPlugin_Compound::BASE_OBJECTS_ID(),
+ ModelAPI_AttributeSelectionList, /** Base objects */)
+
+ /// Modify base attribute of the feature.
+ BUILDAPI_EXPORT
+ void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Dump wrapped feature
+ BUILDAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Compound object.
+typedef std::shared_ptr<BuildAPI_Compound> CompoundPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Compound feature.
+BUILDAPI_EXPORT
+CompoundPtr addCompound(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+#endif // BuildAPI_Compound_H_
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildAPI_Filling.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+BuildAPI_Filling::BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+ : ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+BuildAPI_Filling::BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+ : ModelHighAPI_Interface(theFeature)
+{
+ if(initialize())
+ setBase(theBaseObjects);
+}
+
+BuildAPI_Filling::BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const std::string& theOrientCorrection,
+ const int theMinDegree,
+ const int theMaxDegree,
+ const int theNbIter,
+ const double theTolerance2D,
+ const double theTolerance3D,
+ const bool theApproximate)
+ : ModelHighAPI_Interface(theFeature)
+{
+ if(initialize()) {
+ setOrientationMethod(theOrientCorrection);
+ setMinDegree(theMinDegree);
+ setMaxDegree(theMaxDegree);
+ setNbIterations(theNbIter);
+ setTolerance2d(theTolerance2D);
+ setTolerance3d(theTolerance3D);
+ setApproximation(theApproximate);
+ setAdvancedOptions();
+ setBase(theBaseObjects);
+ }
+}
+
+BuildAPI_Filling::~BuildAPI_Filling()
+{
+}
+
+void BuildAPI_Filling::execIfBaseNotEmpty()
+{
+ if (baseObjects()->size() > 0)
+ execute();
+}
+
+void BuildAPI_Filling::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ fillAttribute(theBaseObjects, mybaseObjects);
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setOrientationMethod(const std::string& theMethod)
+{
+ fillAttribute(theMethod, myorientationMethod);
+ if (theMethod != BuildPlugin_Filling::METHOD_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setMinDegree(const int theMinDegree)
+{
+ fillAttribute(theMinDegree, myminDegree);
+ if (theMinDegree != BuildPlugin_Filling::MINIMAL_DEGREE_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setMaxDegree(const int theMaxDegree)
+{
+ fillAttribute(theMaxDegree, mymaxDegree);
+ if (theMaxDegree != BuildPlugin_Filling::MAXIMAL_DEGREE_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setNbIterations(const int theNbIter)
+{
+ fillAttribute(theNbIter, mynbIterations);
+ if (theNbIter != BuildPlugin_Filling::NUMBER_OF_ITERATIONS_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setTolerance2d(const double theTol2d)
+{
+ fillAttribute(theTol2d, mytolerance2d);
+ if (theTol2d != BuildPlugin_Filling::TOLERANCE_2D_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setTolerance3d(const double theTol3d)
+{
+ fillAttribute(theTol3d, mytolerance3d);
+ if (theTol3d != BuildPlugin_Filling::TOLERANCE_3D_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setApproximation(const bool theApproximate)
+{
+ fillAttribute(theApproximate, myapproximate);
+ if (theApproximate != BuildPlugin_Filling::APPROXIMATION_DEFAULT())
+ setAdvancedOptions();
+ execIfBaseNotEmpty();
+}
+
+void BuildAPI_Filling::setAdvancedOptions()
+{
+ feature()->string(BuildPlugin_Filling::ADVANCED_OPTIONS_ID())->setValue("true");
+}
+
+void BuildAPI_Filling::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ std::string aPartName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.addFilling(" << aPartName << ", " << baseObjects();
+
+ if (!aBase->string(BuildPlugin_Filling::ADVANCED_OPTIONS_ID())->value().empty()) {
+ // dump options too,
+ theDumper << ", " << orientationMethod()
+ << ", " << minDegree() << ", " << maxDegree() << ", " << nbIterations()
+ << ", " << tolerance2d() << ", " << tolerance3d()
+ << ", " << approximate();
+ }
+ theDumper << ")" << std::endl;
+}
+
+//==================================================================================================
+
+FillingPtr addFilling(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Filling::ID());
+ return FillingPtr(new BuildAPI_Filling(aFeature, theBaseObjects));
+}
+
+FillingPtr addFilling(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const std::string& theOrientCorrection,
+ const int theMinDegree,
+ const int theMaxDegree,
+ const int theNbIter,
+ const double theTolerance2D,
+ const double theTolerance3D,
+ const bool theApproximate)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Filling::ID());
+ return FillingPtr(new BuildAPI_Filling(aFeature, theBaseObjects, theOrientCorrection,
+ theMinDegree, theMaxDegree, theNbIter, theTolerance2D, theTolerance3D, theApproximate));
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildAPI_Filling_H_
+#define BuildAPI_Filling_H_
+
+#include "BuildAPI.h"
+
+#include <BuildPlugin_Filling.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Selection;
+
+/// \class BuildAPI_Filling
+/// \ingroup CPPHighAPI
+/// \brief Interface for Filling feature.
+class BuildAPI_Filling : public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ BUILDAPI_EXPORT explicit BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with base objects.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Constructor with values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Filling(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const std::string& theOrientCorrection,
+ const int theMinDegree,
+ const int theMaxDegree,
+ const int theNbIter,
+ const double theTolerance2D,
+ const double theTolerance3D,
+ const bool theApproximate);
+
+ /// Destructor.
+ BUILDAPI_EXPORT virtual ~BuildAPI_Filling();
+
+ INTERFACE_8(BuildPlugin_Filling::ID(),
+ baseObjects, BuildPlugin_Filling::BASE_OBJECTS_ID(),
+ ModelAPI_AttributeSelectionList,
+ /** Base objects */,
+ orientationMethod, BuildPlugin_Filling::METHOD_ID(),
+ ModelAPI_AttributeString,
+ /** Method to keep edge orientaion */,
+ minDegree, BuildPlugin_Filling::MINIMAL_DEGREE_ID(),
+ ModelAPI_AttributeInteger,
+ /** Minimal degree */,
+ maxDegree, BuildPlugin_Filling::MAXIMAL_DEGREE_ID(),
+ ModelAPI_AttributeInteger,
+ /** Maximal degree */,
+ nbIterations, BuildPlugin_Filling::NUMBER_OF_ITERATIONS_ID(),
+ ModelAPI_AttributeInteger,
+ /** Number of iterations */,
+ tolerance2d, BuildPlugin_Filling::TOLERANCE_2D_ID(),
+ ModelAPI_AttributeDouble,
+ /** 2D tolerance */,
+ tolerance3d, BuildPlugin_Filling::TOLERANCE_3D_ID(),
+ ModelAPI_AttributeDouble,
+ /** 3D tolerance */,
+ approximate, BuildPlugin_Filling::APPROXIMATION_ID(),
+ ModelAPI_AttributeBoolean,
+ /** Approximate original edges */)
+
+ /// Modify base attribute of the feature.
+ BUILDAPI_EXPORT void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Modify orientation method
+ BUILDAPI_EXPORT void setOrientationMethod(const std::string& theMethod);
+
+ /// Modify minimal degree of result B-spline
+ BUILDAPI_EXPORT void setMinDegree(const int theMinDegree);
+
+ /// Modify maximal degree of result B-spline
+ BUILDAPI_EXPORT void setMaxDegree(const int theMaxDegree);
+
+ /// Modify number of iterations
+ BUILDAPI_EXPORT void setNbIterations(const int theNbIter);
+
+ /// Set 2D tolerance
+ BUILDAPI_EXPORT void setTolerance2d(const double theTol2d);
+
+ /// Set 3D tolerance
+ BUILDAPI_EXPORT void setTolerance3d(const double theTol3d);
+
+ /// Set approximation flag
+ BUILDAPI_EXPORT void setApproximation(const bool theApproximate);
+
+ /// Dump wrapped feature
+ BUILDAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+ void execIfBaseNotEmpty();
+ void setAdvancedOptions();
+};
+
+/// Pointer on Face object.
+typedef std::shared_ptr<BuildAPI_Filling> FillingPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Filling feature.
+BUILDAPI_EXPORT FillingPtr addFilling(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+/// \ingroup CPPHighAPI
+/// \brief Create Filling feature.
+BUILDAPI_EXPORT FillingPtr addFilling(
+ const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const std::string& theOrientCorrection,
+ const int theMinDegree = BuildPlugin_Filling::MINIMAL_DEGREE_DEFAULT(),
+ const int theMaxDegree = BuildPlugin_Filling::MAXIMAL_DEGREE_DEFAULT(),
+ const int theNbIter = BuildPlugin_Filling::NUMBER_OF_ITERATIONS_DEFAULT(),
+ const double theTolerance2D = BuildPlugin_Filling::TOLERANCE_2D_DEFAULT(),
+ const double theTolerance3D = BuildPlugin_Filling::TOLERANCE_3D_DEFAULT(),
+ const bool theApproximate = BuildPlugin_Filling::APPROXIMATION_DEFAULT());
+
+#endif // BuildAPI_Filling_H_
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildAPI_Solid.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+BuildAPI_Solid::BuildAPI_Solid(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+//==================================================================================================
+BuildAPI_Solid::BuildAPI_Solid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+: ModelHighAPI_Interface(theFeature)
+{
+ if(initialize()) {
+ setBase(theBaseObjects);
+ }
+}
+
+//==================================================================================================
+BuildAPI_Solid::~BuildAPI_Solid()
+{
+}
+
+//==================================================================================================
+void BuildAPI_Solid::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ fillAttribute(theBaseObjects, mybaseObjects);
+ execute();
+}
+
+//==================================================================================================
+void BuildAPI_Solid::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ std::string aPartName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.addSolid(" << aPartName << ", "
+ << aBase->selectionList(BuildPlugin_Solid::BASE_OBJECTS_ID()) << ")" << std::endl;
+}
+
+//==================================================================================================
+SolidPtr addSolid(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Solid::ID());
+ return SolidPtr(new BuildAPI_Solid(aFeature, theBaseObjects));
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildAPI_Solid_H_
+#define BuildAPI_Solid_H_
+
+#include "BuildAPI.h"
+
+#include <BuildPlugin_Solid.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Selection;
+
+/// \class BuildAPI_Solid
+/// \ingroup CPPHighAPI
+/// \brief Interface for Solid feature.
+class BuildAPI_Solid: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Solid(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ BUILDAPI_EXPORT
+ explicit BuildAPI_Solid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Destructor.
+ BUILDAPI_EXPORT
+ virtual ~BuildAPI_Solid();
+
+ INTERFACE_1(BuildPlugin_Solid::ID(),
+ baseObjects, BuildPlugin_Solid::BASE_OBJECTS_ID(),
+ ModelAPI_AttributeSelectionList, /** Base objects */)
+
+ /// Modify base attribute of the feature.
+ BUILDAPI_EXPORT
+ void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Dump wrapped feature
+ BUILDAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Solid object.
+typedef std::shared_ptr<BuildAPI_Solid> SolidPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Solid feature.
+BUILDAPI_EXPORT
+SolidPtr addSolid(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+#endif // BuildAPI_Solid_H_
#include <ModelHighAPI_swig.h>
+ #include "BuildAPI_Compound.h"
+ #include "BuildAPI_CompSolid.h"
#include "BuildAPI_Edge.h"
#include "BuildAPI_Face.h"
+ #include "BuildAPI_Filling.h"
#include "BuildAPI_Shell.h"
+ #include "BuildAPI_Solid.h"
#include "BuildAPI_SubShapes.h"
#include "BuildAPI_Vertex.h"
#include "BuildAPI_Wire.h"
SET(PROJECT_HEADERS
BuildAPI.h
+ BuildAPI_Compound.h
+ BuildAPI_CompSolid.h
BuildAPI_Edge.h
BuildAPI_Face.h
+ BuildAPI_Filling.h
BuildAPI_Shell.h
+ BuildAPI_Solid.h
BuildAPI_SubShapes.h
BuildAPI_Vertex.h
BuildAPI_Wire.h
)
SET(PROJECT_SOURCES
+ BuildAPI_Compound.cpp
+ BuildAPI_CompSolid.cpp
BuildAPI_Edge.cpp
BuildAPI_Face.cpp
+ BuildAPI_Filling.cpp
BuildAPI_Shell.cpp
+ BuildAPI_Solid.cpp
BuildAPI_SubShapes.cpp
BuildAPI_Vertex.cpp
BuildAPI_Wire.cpp
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildPlugin_CompSolid.h"
+
+#include <GeomAlgoAPI_MakeShape.h>
+#include <ModelAPI_AttributeSelectionList.h>
+
+//=================================================================================================
+BuildPlugin_CompSolid::BuildPlugin_CompSolid()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_CompSolid::initAttributes()
+{
+ data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void BuildPlugin_CompSolid::execute()
+{
+ ListOfShape anOriginalShapes;
+ std::shared_ptr<GeomAlgoAPI_MakeShape> aVolumeMaker;
+ if (!build(anOriginalShapes, aVolumeMaker))
+ return;
+
+ GeomShapePtr aVolumeRes = aVolumeMaker->shape();
+
+ // check and process result of volume maker
+ GeomShapePtr aResShape = getSingleSubshape(aVolumeRes, GeomAPI_Shape::COMPSOLID);
+ if (!aResShape) // try to build a solid
+ aResShape = getSingleSubshape(aVolumeRes, GeomAPI_Shape::SOLID);
+
+ int anIndex = 0;
+ if (aResShape) {
+ storeResult(anOriginalShapes, aResShape, aVolumeMaker);
+ ++anIndex;
+ }
+ removeResults(anIndex);
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildPlugin_CompSolid_H_
+#define BuildPlugin_CompSolid_H_
+
+#include "BuildPlugin.h"
+#include "BuildPlugin_Solid.h"
+
+/// \class BuildPlugin_CompSolid
+/// \ingroup Plugins
+/// \brief Feature for creation of compsolid from solids or compsolids.
+class BuildPlugin_CompSolid: public BuildPlugin_Solid
+{
+public:
+ /// Use plugin manager for features creation
+ BuildPlugin_CompSolid();
+
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("CompSolid");
+ return MY_ID;
+ }
+
+ /// Attribute name of base objects.
+ inline static const std::string& BASE_OBJECTS_ID()
+ {
+ static const std::string MY_BASE_OBJECTS_ID("base_objects");
+ return MY_BASE_OBJECTS_ID;
+ }
+
+ /// \return the kind of a feature.
+ BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = BuildPlugin_CompSolid::ID();
+ return MY_KIND;
+ }
+
+ /// Request for initialization of data model of the feature: adding all attributes.
+ BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Creates a new part document if needed.
+ BUILDPLUGIN_EXPORT virtual void execute();
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildPlugin_Compound.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+
+
+//=================================================================================================
+BuildPlugin_Compound::BuildPlugin_Compound()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_Compound::initAttributes()
+{
+ data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void BuildPlugin_Compound::execute()
+{
+ // Get base objects list.
+ AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+ if(!aSelectionList.get()) {
+ setError("Error: Could not get selection list.");
+ return;
+ }
+ if(aSelectionList->size() == 0) {
+ setError("Error: Empty selection list.");
+ return;
+ }
+
+ // Collect base shapes.
+ ListOfShape anOriginalShapes;
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ GeomShapePtr aShape = aSelection->value();
+ if (!aShape.get())
+ aShape = aSelection->context()->shape();
+ anOriginalShapes.push_back(aShape);
+ }
+
+ // Build compound.
+ GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(anOriginalShapes);
+ int anIndexToRemove = 0;
+ if (aCompound) {
+ ResultBodyPtr aResultBody = document()->createBody(data(), anIndexToRemove++);
+ aResultBody->store(aCompound);
+
+//// // Store faces
+//// std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubs = theAlgorithm->mapOfSubShapes();
+//// int aModifiedTag = 1;
+//// for(ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
+//// anIt != theOriginalShapes.cend(); ++anIt) {
+//// GeomShapePtr aShape = *anIt;
+//// aResultBody->loadAndOrientModifiedShapes(theAlgorithm.get(), aShape, GeomAPI_Shape::FACE,
+//// aModifiedTag, "Modified_Face", *aMapOfSubs.get(), false, true, true);
+//// }
+
+ setResult(aResultBody);
+ }
+ removeResults(anIndexToRemove);
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildPlugin_Compound_H_
+#define BuildPlugin_Compound_H_
+
+#include "BuildPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+/// \class BuildPlugin_Compound
+/// \ingroup Plugins
+/// \brief Feature for creation of compound from different kinds of shapes.
+class BuildPlugin_Compound: public ModelAPI_Feature
+{
+public:
+ /// Use plugin manager for features creation
+ BuildPlugin_Compound();
+
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("Compound");
+ return MY_ID;
+ }
+
+ /// Attribute name of base objects.
+ inline static const std::string& BASE_OBJECTS_ID()
+ {
+ static const std::string MY_BASE_OBJECTS_ID("base_objects");
+ return MY_BASE_OBJECTS_ID;
+ }
+
+ /// \return the kind of a feature.
+ BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = BuildPlugin_Compound::ID();
+ return MY_KIND;
+ }
+
+ /// Request for initialization of data model of the feature: adding all attributes.
+ BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Creates a new part document if needed.
+ BUILDPLUGIN_EXPORT virtual void execute();
+};
+
+#endif
// Collect base shapes.
ListOfShape anEdges;
+ ListOfShape anOriginalFaces;
std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
if(!aShape.get()) {
aShape = aContext;
}
+ // keep selected faces "as is"
+ if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+ anOriginalFaces.push_back(aShape);
+ continue;
+ }
+
for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
GeomShapePtr anEdge = anExp.current();
anEdges.push_back(anEdge);
aListOfNormals.push_back(aSketch->norm());
}
- // Get plane.
- std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
- std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
- bool isReverse = !aListOfNormals.empty();
- std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = aListOfNormals.begin();
- for (; aNormIt != aListOfNormals.end() && isReverse; ++aNormIt)
- if ((*aNormIt)->dot(aNormal) > 1.e-7)
- isReverse = false;
- if (isReverse) {
- aNormal->reverse();
- aPln = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aPln->location(), aNormal));
- }
-
- // Get faces.
+ // Build faces by edges.
ListOfShape aFaces;
- GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
- aPln->direction(), anEdges, aFaces);
-
- // Get wires from faces.
- ListOfShape aWires;
- for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
- aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
- //for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
- // if(anExp.current()->orientation() == GeomAPI_Shape::REVERSED) {
- // continue;
- // }
- // aWires.push_back(anExp.current());
- //}
- }
+ if (!anEdges.empty())
+ buildFacesByEdges(anEdges, aListOfNormals, aFaces);
- // Make faces with holes.
- aFaces.clear();
- GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
+ // Add faces selected by user.
+ aFaces.insert(aFaces.end(), anOriginalFaces.begin(), anOriginalFaces.end());
// Store result.
int anIndex = 0;
removeResults(anIndex);
}
+
+void BuildPlugin_Face::buildFacesByEdges(
+ const ListOfShape& theEdges,
+ const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
+ ListOfShape& theFaces) const
+{
+ // Get plane.
+ std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges);
+ std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
+ bool isReverse = !theNormals.empty();
+ std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = theNormals.begin();
+ for (; aNormIt != theNormals.end() && isReverse; ++aNormIt)
+ if ((*aNormIt)->dot(aNormal) > 1.e-7)
+ isReverse = false;
+ if (isReverse) {
+ aNormal->reverse();
+ aPln = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aPln->location(), aNormal));
+ }
+
+ // Get faces.
+ GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
+ aPln->direction(), theEdges, theFaces);
+
+ // Get wires from faces.
+ ListOfShape aWires;
+ for(ListOfShape::const_iterator anIt = theFaces.cbegin(); anIt != theFaces.cend(); ++anIt)
+ aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
+
+ // Make faces with holes.
+ theFaces.clear();
+ GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(),
+ aWires, theFaces);
+}
#include <ModelAPI_Feature.h>
+class GeomAPI_Dir;
+class GeomAPI_Shape;
+
/// \class BuildPlugin_Face
/// \ingroup Plugins
/// \brief Feature for creation of face from sketch edges or existing wires.
/// Creates a new part document if needed.
BUILDPLUGIN_EXPORT virtual void execute();
+
+private:
+ /// Create faces basing on the list of edges
+ void buildFacesByEdges(const std::list< std::shared_ptr<GeomAPI_Shape> >& theEdges,
+ const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
+ std::list< std::shared_ptr<GeomAPI_Shape> >& theFaces) const;
};
#endif
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildPlugin_Filling.h"
+
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_Copy.h>
+#include <GeomAlgoAPI_Filling.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_Wire.h>
+
+#include <cmath>
+
+struct FillingParameters
+{
+ std::string method;
+ int minDegree;
+ int maxDegree;
+ int nbIter;
+ double tol2D;
+ double tol3D;
+ bool isApprox;
+};
+
+
+//=================================================================================================
+BuildPlugin_Filling::BuildPlugin_Filling()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_Filling::initAttributes()
+{
+ data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+ data()->addAttribute(ADVANCED_OPTIONS_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(METHOD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(MINIMAL_DEGREE_ID(), ModelAPI_AttributeInteger::typeId());
+ data()->addAttribute(MAXIMAL_DEGREE_ID(), ModelAPI_AttributeInteger::typeId());
+ data()->addAttribute(NUMBER_OF_ITERATIONS_ID(), ModelAPI_AttributeInteger::typeId());
+ data()->addAttribute(TOLERANCE_2D_ID(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(TOLERANCE_3D_ID(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(APPROXIMATION_ID(), ModelAPI_AttributeBoolean::typeId());
+
+ restoreDefaultParameters();
+ string(ADVANCED_OPTIONS_ID())->setValue("");
+}
+
+//=================================================================================================
+void BuildPlugin_Filling::execute()
+{
+ // get parameters of algorithm
+ FillingParameters aParameters;
+ aParameters.method = string(METHOD_ID())->value();
+ aParameters.minDegree = integer(MINIMAL_DEGREE_ID())->value();
+ aParameters.maxDegree = integer(MAXIMAL_DEGREE_ID())->value();
+ aParameters.nbIter = integer(NUMBER_OF_ITERATIONS_ID())->value();
+ aParameters.tol2D = real(TOLERANCE_2D_ID())->value();
+ aParameters.tol3D = real(TOLERANCE_3D_ID())->value();
+ aParameters.isApprox = boolean(APPROXIMATION_ID())->value();
+
+ if (aParameters.minDegree > aParameters.maxDegree) {
+ setError("Error: " + getKind() + " algorithm failed (max deg < min deg).");
+ return;
+ }
+
+ std::shared_ptr<GeomAlgoAPI_Filling> aFilling(
+ new GeomAlgoAPI_Filling(aParameters.minDegree, aParameters.maxDegree, aParameters.nbIter,
+ aParameters.tol2D, aParameters.tol3D));
+
+ // get base objects list
+ AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+ if (aSelectionList->size() <= 1)
+ return;
+
+ // collect base shapes
+ for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ GeomEdgePtr anEdge = toEdge(aSelection->value(), aParameters.method);
+ if (!anEdge) {
+ myLastEdgeStartPoint = GeomPointPtr();
+ myLastEdgeEndPoint = GeomPointPtr();
+ return;
+ }
+ aFilling->add(anEdge);
+ }
+ myLastEdgeStartPoint = GeomPointPtr();
+ myLastEdgeEndPoint = GeomPointPtr();
+
+ // build result
+ aFilling->build(aParameters.isApprox);
+ if (isAlgorithmFailed(aFilling)) {
+ removeResults(0);
+ return;
+ }
+
+ /// store result
+ GeomShapePtr aCreatedFace = aFilling->shape();
+ ResultBodyPtr aResultBody = document()->createBody(data());
+ aResultBody->store(aCreatedFace);
+ // store edges
+ int anEdgeInd = 0;
+ for(GeomAPI_ShapeExplorer anExp(aCreatedFace, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+ GeomShapePtr anEdge = anExp.current();
+ aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeInd), ++anEdgeInd);
+ }
+ setResult(aResultBody, 0);
+}
+
+bool BuildPlugin_Filling::isAlgorithmFailed(
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+ if (!theAlgorithm->isDone()) {
+ static const std::string aFeatureError = "Error: filling algorithm failed.";
+ setError(aFeatureError);
+ return true;
+ }
+ if (theAlgorithm->shape()->isNull()) {
+ static const std::string aShapeError = "Error: Resulting shape of filling is Null.";
+ setError(aShapeError);
+ return true;
+ }
+ if (!theAlgorithm->isValid()) {
+ std::string aFeatureError = "Error: Resulting shape of filling is not valid.";
+ setError(aFeatureError);
+ return true;
+ }
+ return false;
+}
+
+//=================================================================================================
+void BuildPlugin_Filling::attributeChanged(const std::string& theID)
+{
+ if (theID == ADVANCED_OPTIONS_ID() && string(ADVANCED_OPTIONS_ID())->value().empty()) {
+ // Advanced options flag just unchecked => restore default state of all parameters
+ restoreDefaultParameters();
+ }
+}
+
+//=================================================================================================
+GeomEdgePtr BuildPlugin_Filling::toEdge(const GeomShapePtr& theShape, const std::string& theMethod)
+{
+ GeomEdgePtr anEdge;
+ switch (theShape->shapeType()) {
+ case GeomAPI_Shape::EDGE:
+ anEdge = GeomEdgePtr(new GeomAPI_Edge(GeomAlgoAPI_Copy(theShape).shape()));
+ break;
+ case GeomAPI_Shape::WIRE:
+ anEdge = GeomAlgoAPI_ShapeTools::wireToEdge(
+ GeomWirePtr(new GeomAPI_Wire(theShape)));
+ break;
+ default:
+ break;
+ }
+
+ if (!anEdge || anEdge->empty()) {
+ static const std::string aFeatureError =
+ "Error: incorrect type of input feature (edges/wire are supported only).";
+ setError(aFeatureError);
+ return anEdge;
+ }
+
+ // correct edge orientation according to filling method
+ if (theMethod == Method::AUTO_CORRECT_ORIENTATION()) {
+ // check the distance to previous edge boundaries, reverse edge if necessary
+ GeomPointPtr aStartPnt = anEdge->firstPoint();
+ GeomPointPtr aEndPnt = anEdge->lastPoint();
+ if (anEdge->orientation() == GeomAPI_Shape::REVERSED) {
+ aStartPnt = anEdge->lastPoint();
+ aEndPnt = anEdge->firstPoint();
+ }
+ bool isReverse = false;
+ if (myLastEdgeStartPoint) {
+ double d1 = myLastEdgeStartPoint->distance(aStartPnt)
+ + myLastEdgeEndPoint->distance(aEndPnt);
+ double d2 = myLastEdgeStartPoint->distance(aEndPnt)
+ + myLastEdgeEndPoint->distance(aStartPnt);
+ if (fabs(d1 - d2) < 1.e-7) {
+ // undefined case => check distance to start point only
+ d1 = myLastEdgeStartPoint->distance(aStartPnt);
+ d2 = myLastEdgeStartPoint->distance(aEndPnt);
+ }
+ isReverse = d2 < d1;
+ }
+
+ if (isReverse) {
+ anEdge->reverse();
+ myLastEdgeStartPoint = aEndPnt;
+ myLastEdgeEndPoint = aStartPnt;
+ } else {
+ myLastEdgeStartPoint = aStartPnt;
+ myLastEdgeEndPoint = aEndPnt;
+ }
+ }
+ else if (theMethod == Method::USE_CURVE_INFORMATION()) {
+ // make all edges FORWARD to avoid reversing the curves by GeomAlgoAPI_Filling algorithm
+ anEdge->setOrientation(GeomAPI_Shape::FORWARD);
+ }
+ return anEdge;
+}
+
+//=================================================================================================
+void BuildPlugin_Filling::restoreDefaultParameters()
+{
+ string(METHOD_ID())->setValue(METHOD_DEFAULT());
+ integer(MINIMAL_DEGREE_ID())->setValue(MINIMAL_DEGREE_DEFAULT());
+ integer(MAXIMAL_DEGREE_ID())->setValue(MAXIMAL_DEGREE_DEFAULT());
+ integer(NUMBER_OF_ITERATIONS_ID())->setValue(NUMBER_OF_ITERATIONS_DEFAULT());
+ real(TOLERANCE_2D_ID())->setValue(TOLERANCE_2D_DEFAULT());
+ real(TOLERANCE_3D_ID())->setValue(TOLERANCE_3D_DEFAULT());
+ boolean(APPROXIMATION_ID())->setValue(APPROXIMATION_DEFAULT());
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildPlugin_Filling_H_
+#define BuildPlugin_Filling_H_
+
+#include "BuildPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+#include <memory>
+#include <string>
+
+class GeomAlgoAPI_MakeShape;
+class GeomAPI_Edge;
+class GeomAPI_Pnt;
+class GeomAPI_Shape;
+
+/// \class BuildPlugin_Filling
+/// \ingroup Plugins
+/// \brief Feature for creation of face from list of edges (1D objects).
+class BuildPlugin_Filling: public ModelAPI_Feature
+{
+public:
+ /// Use plugin manager for features creation
+ BuildPlugin_Filling();
+
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("Filling");
+ return MY_ID;
+ }
+
+ /// \return the kind of a feature.
+ BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = BuildPlugin_Filling::ID();
+ return MY_KIND;
+ }
+
+ /// Attribute name of base objects.
+ inline static const std::string& BASE_OBJECTS_ID()
+ {
+ static const std::string MY_BASE_OBJECTS_ID("base_objects");
+ return MY_BASE_OBJECTS_ID;
+ }
+
+ /// Attribute name of advanced options.
+ inline static const std::string& ADVANCED_OPTIONS_ID()
+ {
+ static const std::string MY_ADVANCED_OPTIONS_ID("advanced_options");
+ return MY_ADVANCED_OPTIONS_ID;
+ }
+
+ /// Attribute name of method of edge orientation.
+ inline static const std::string& METHOD_ID()
+ {
+ static const std::string MY_METHOD_ID("orientation");
+ return MY_METHOD_ID;
+ }
+
+ /// Supported methods for edge orientation correction
+ struct Method {
+ inline static const std::string& AUTO_CORRECT_ORIENTATION()
+ {
+ static const std::string MY_AUTO_CORRECT_ORIENTATION("auto_correct");
+ return MY_AUTO_CORRECT_ORIENTATION;
+ }
+ inline static const std::string& USE_CURVE_INFORMATION()
+ {
+ static const std::string MY_USE_CURVE_INFORMATION("curve_info");
+ return MY_USE_CURVE_INFORMATION;
+ }
+ inline static const std::string& USE_EDGES_ORIENTATION()
+ {
+ static const std::string MY_USE_EDGES_ORIENTATION("edge_orient");
+ return MY_USE_EDGES_ORIENTATION;
+ }
+ };
+
+ /// Attribute name of minimal degree.
+ inline static const std::string& MINIMAL_DEGREE_ID()
+ {
+ static const std::string MY_MINIMAL_DEGREE_ID("min_degree");
+ return MY_MINIMAL_DEGREE_ID;
+ }
+
+ /// Attribute name of maximal degree.
+ inline static const std::string& MAXIMAL_DEGREE_ID()
+ {
+ static const std::string MY_MAXIMAL_DEGREE_ID("max_degree");
+ return MY_MAXIMAL_DEGREE_ID;
+ }
+
+ /// Attribute name of number of iterations.
+ inline static const std::string& NUMBER_OF_ITERATIONS_ID()
+ {
+ static const std::string MY_NUMBER_OF_ITERATIONS_ID("nb_iter");
+ return MY_NUMBER_OF_ITERATIONS_ID;
+ }
+
+ /// Attribute name of 2D tolerance.
+ inline static const std::string& TOLERANCE_2D_ID()
+ {
+ static const std::string MY_TOLERANCE_2D_ID("tol_2d");
+ return MY_TOLERANCE_2D_ID;
+ }
+
+ /// Attribute name of 3D tolerance.
+ inline static const std::string& TOLERANCE_3D_ID()
+ {
+ static const std::string MY_TOLERANCE_3D_ID("tol_3d");
+ return MY_TOLERANCE_3D_ID;
+ }
+
+ /// Attribute name of approximation.
+ inline static const std::string& APPROXIMATION_ID()
+ {
+ static const std::string MY_APPROXIMATION_ID("approximation");
+ return MY_APPROXIMATION_ID;
+ }
+
+ /// Default value of the orientation
+ inline static const std::string& METHOD_DEFAULT() { return Method::AUTO_CORRECT_ORIENTATION(); }
+ /// Default value of minimal degree
+ inline static int MINIMAL_DEGREE_DEFAULT() { return 2; }
+ /// Default value of maximal degree
+ inline static int MAXIMAL_DEGREE_DEFAULT() { return 5; }
+ /// Default value of number of iterations
+ inline static int NUMBER_OF_ITERATIONS_DEFAULT() { return 0; }
+ /// Default value of 2D tolerance
+ inline static double TOLERANCE_2D_DEFAULT() { return 1.e-4; }
+ /// Default value of 3D tolerance
+ inline static double TOLERANCE_3D_DEFAULT() { return 1.e-4; }
+ /// Default value of the approximation attribute
+ inline static bool APPROXIMATION_DEFAULT() { return false; }
+
+ /// Request for initialization of data model of the feature: adding all attributes.
+ BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Creates a new part document if needed.
+ BUILDPLUGIN_EXPORT virtual void execute();
+
+ /// Called on change of any argument-attribute of this object.
+ /// \param[in] theID identifier of changed attribute.
+ BUILDPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+private:
+ /// Check the filling algorithm is failed
+ bool isAlgorithmFailed(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+ /// Convert shape to edge according to construction method
+ std::shared_ptr<GeomAPI_Edge> toEdge(const std::shared_ptr<GeomAPI_Shape>& theShape,
+ const std::string& theMethod);
+
+ /// Update values of attributes by their default values
+ void restoreDefaultParameters();
+
+private:
+ std::shared_ptr<GeomAPI_Pnt> myLastEdgeStartPoint;
+ std::shared_ptr<GeomAPI_Pnt> myLastEdgeEndPoint;
+};
+
+#endif
-// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+// Copyright (C) 2017-20xx 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
#include <BuildPlugin_Wire.h>
#include <BuildPlugin_Face.h>
#include <BuildPlugin_Shell.h>
+#include <BuildPlugin_Solid.h>
+#include <BuildPlugin_CompSolid.h>
+#include <BuildPlugin_Compound.h>
#include <BuildPlugin_SubShapes.h>
+#include <BuildPlugin_Filling.h>
#include <BuildPlugin_Validators.h>
// the only created instance of this plugin
new BuildPlugin_ValidatorBaseForFace());
aFactory->registerValidator("BuildPlugin_ValidatorSubShapesSelection",
new BuildPlugin_ValidatorSubShapesSelection());
+ aFactory->registerValidator("BuildPlugin_ValidatorFillingSelection",
+ new BuildPlugin_ValidatorFillingSelection());
// Register this plugin.
ModelAPI_Session::get()->registerPlugin(this);
return FeaturePtr(new BuildPlugin_Face());
} else if(theFeatureID == BuildPlugin_Shell::ID()) {
return FeaturePtr(new BuildPlugin_Shell());
+ } else if(theFeatureID == BuildPlugin_Solid::ID()) {
+ return FeaturePtr(new BuildPlugin_Solid());
+ } else if(theFeatureID == BuildPlugin_CompSolid::ID()) {
+ return FeaturePtr(new BuildPlugin_CompSolid());
+ } else if(theFeatureID == BuildPlugin_Compound::ID()) {
+ return FeaturePtr(new BuildPlugin_Compound());
} else if(theFeatureID == BuildPlugin_SubShapes::ID()) {
return FeaturePtr(new BuildPlugin_SubShapes());
+ } else if(theFeatureID == BuildPlugin_Filling::ID()) {
+ return FeaturePtr(new BuildPlugin_Filling());
}
// Feature of such kind is not found.
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildPlugin_Solid.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAPI_ShapeIterator.h>
+
+#include <GeomAlgoAPI_MakeVolume.h>
+
+//=================================================================================================
+BuildPlugin_Solid::BuildPlugin_Solid()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_Solid::initAttributes()
+{
+ data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void BuildPlugin_Solid::execute()
+{
+ ListOfShape anOriginalShapes;
+ std::shared_ptr<GeomAlgoAPI_MakeShape> aVolumeMaker;
+ if (!build(anOriginalShapes, aVolumeMaker))
+ return;
+
+ // check and process result of volume maker
+ GeomShapePtr aResShape = getSingleSubshape(aVolumeMaker->shape(), GeomAPI_Shape::SOLID);
+ int anIndex = 0;
+ if (aResShape) {
+ storeResult(anOriginalShapes, aResShape, aVolumeMaker);
+ ++anIndex;
+ }
+ removeResults(anIndex);
+}
+
+//=================================================================================================
+bool BuildPlugin_Solid::build(ListOfShape& theOriginalShapes,
+ std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+ // Get base objects list.
+ AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+ if (!aSelectionList.get()) {
+ setError("Error: Could not get selection list.");
+ return false;
+ }
+ if (aSelectionList->size() == 0) {
+ setError("Error: Empty selection list.");
+ return false;
+ }
+
+ // Collect base shapes.
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ GeomShapePtr aShape = aSelection->value();
+ if (!aShape.get())
+ aShape = aSelection->context()->shape();
+ theOriginalShapes.push_back(aShape);
+ }
+
+ theAlgorithm =
+ std::shared_ptr<GeomAlgoAPI_MakeVolume>(new GeomAlgoAPI_MakeVolume(theOriginalShapes));
+ return !isAlgorithmFailed(theAlgorithm);
+}
+
+void BuildPlugin_Solid::storeResult(const ListOfShape& theOriginalShapes,
+ const GeomShapePtr& theResultShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+ ResultBodyPtr aResultBody = document()->createBody(data());
+ aResultBody->store(theResultShape);
+
+ // Store faces
+ std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubs = theAlgorithm->mapOfSubShapes();
+ int aModifiedTag = 1;
+ for(ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
+ anIt != theOriginalShapes.cend(); ++anIt) {
+ GeomShapePtr aShape = *anIt;
+ aResultBody->loadAndOrientModifiedShapes(theAlgorithm.get(), aShape, GeomAPI_Shape::FACE,
+ aModifiedTag, "Modified_Face", *aMapOfSubs.get(), false, true, true);
+ }
+
+ setResult(aResultBody);
+}
+
+GeomShapePtr BuildPlugin_Solid::getSingleSubshape(const GeomShapePtr& theCompound,
+ const GeomAPI_Shape::ShapeType theShapeType)
+{
+ if (theCompound->shapeType() == theShapeType)
+ return theCompound;
+ else if (theCompound->shapeType() == GeomAPI_Shape::COMPOUND) {
+ GeomAPI_ShapeIterator anIt(theCompound);
+ GeomShapePtr aFoundSub;
+ for (; anIt.more() && !aFoundSub; anIt.next()) {
+ aFoundSub = anIt.current();
+ if (aFoundSub->shapeType() != theShapeType)
+ return GeomShapePtr(); // not alone sub-shape
+ }
+ if (anIt.more()) {
+ std::string anError = "Error: unable to build a ";
+ switch (theShapeType) {
+ case GeomAPI_Shape::SOLID: anError += "solid"; break;
+ case GeomAPI_Shape::COMPSOLID: anError += "compsolid"; break;
+ default: anError += "subshape"; break;
+ }
+ setError(anError);
+ } else
+ return aFoundSub;
+ }
+ // not a solid
+ return GeomShapePtr();
+}
+
+bool BuildPlugin_Solid::isAlgorithmFailed(
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+ if (!theAlgorithm->isDone()) {
+ static const std::string aFeatureError = "Error: MakeVolume algorithm failed.";
+ setError(aFeatureError);
+ return true;
+ }
+ if (theAlgorithm->shape()->isNull()) {
+ static const std::string aShapeError = "Error: Resulting shape of MakeVolume is Null.";
+ setError(aShapeError);
+ return true;
+ }
+ if (!theAlgorithm->isValid()) {
+ std::string aFeatureError = "Error: Resulting shape of MakeVolume is not valid.";
+ setError(aFeatureError);
+ return true;
+ }
+ return false;
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildPlugin_Solid_H_
+#define BuildPlugin_Solid_H_
+
+#include "BuildPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+
+/// \class BuildPlugin_Solid
+/// \ingroup Plugins
+/// \brief Feature for creation of solid from faces or shells.
+class BuildPlugin_Solid: public ModelAPI_Feature
+{
+public:
+ /// Use plugin manager for features creation
+ BuildPlugin_Solid();
+
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("Solid");
+ return MY_ID;
+ }
+
+ /// Attribute name of base objects.
+ inline static const std::string& BASE_OBJECTS_ID()
+ {
+ static const std::string MY_BASE_OBJECTS_ID("base_objects");
+ return MY_BASE_OBJECTS_ID;
+ }
+
+ /// \return the kind of a feature.
+ BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = BuildPlugin_Solid::ID();
+ return MY_KIND;
+ }
+
+ /// Request for initialization of data model of the feature: adding all attributes.
+ BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Creates a new part document if needed.
+ BUILDPLUGIN_EXPORT virtual void execute();
+
+protected:
+ /// Build result
+ /// \param[out] theOriginalShapes list of original shapes
+ /// \param[out] theAlgorithm algorithm to build result
+ /// \return \c true if algorithm finished without errors
+ bool build(ListOfShape& theOriginalShapes, std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+ /// Store result of algorithm
+ void storeResult(const ListOfShape& theOriginalShapes,
+ const GeomShapePtr& theResultShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+ /// Check the algorithm is failed
+ bool isAlgorithmFailed(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+ /// Explode compound to get single shape of specified type
+ /// \return Empty shape if there is more than one shape in compound
+ GeomShapePtr getSingleSubshape(const GeomShapePtr& theCompound,
+ const GeomAPI_Shape::ShapeType theShapeType);
+};
+
+#endif
continue;
}
}
-
- if(!aShape->isEqual(aContextShape)) {
- // Local selection on body does not allowed.
- theError = "Selected shape is in the local selection. Only global selection is allowed.";
- return false;
- }
}
return true;
return false;
}
+ bool hasEdgesOrWires = false;
+ bool hasFaces = false;
+
// Collect base shapes.
ListOfShape anEdges;
for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
}
aShape = aSelection->context()->shape();
}
+ if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+ // skip faces exploding
+ hasFaces = true;
+ continue;
+ }
+
for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+ hasEdgesOrWires = true;
GeomShapePtr anEdge = anExp.current();
anEdges.push_back(anEdge);
}
}
- if(anEdges.empty()) {
+ if (hasFaces && hasEdgesOrWires) {
+ theError = "Faces and edges/wires should be selected together.";
+ return false;
+ } else if (hasEdgesOrWires && anEdges.empty()) {
theError = "Objects are not selected.";
return false;
}
}
}
- // Check that they are planar.
- std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
- if(!aPln.get()) {
- theError = "Selected object(s) should belong to only one plane.";
- return false;
- }
+ if (!anEdges.empty()) {
+ // Check that they are planar.
+ std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
+ if(!aPln.get()) {
+ theError = "Selected object(s) should belong to only one plane.";
+ return false;
+ }
- // Check that selected objects have closed contours.
- ListOfShape aFaces;
- GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
- aPln->direction(), anEdges, aFaces);
- if(aFaces.empty()) {
- theError = "Selected objects do not generate closed contour.";
- return false;
+ // Check that selected objects have closed contours.
+ ListOfShape aFaces;
+ GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
+ aPln->direction(), anEdges, aFaces);
+ if(aFaces.empty()) {
+ theError = "Selected objects do not generate closed contour.";
+ return false;
+ }
}
return true;
return true;
}
+
+
+//=================================================================================================
+bool BuildPlugin_ValidatorFillingSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ // Get base objects list.
+ if (theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
+ std::string aMsg =
+ "Error: BuildPlugin_ValidatorFillingSelection does not support attribute type \""
+ "%1\"\n Only \"%2\" supported.";
+ Events_InfoMessage("BuildPlugin_Validators", aMsg).
+ arg(theAttribute->attributeType()).arg(ModelAPI_AttributeSelectionList::typeId()).send();
+ return false;
+ }
+ AttributeSelectionListPtr aSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if (!aSelectionList.get()) {
+ theError = "Could not get selection list.";
+ return false;
+ }
+
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
+
+ // Check selected shapes.
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelectionAttrInList = aSelectionList->value(anIndex);
+ if (!aSelectionAttrInList.get()) {
+ theError = "Empty attribute in list.";
+ return false;
+ }
+
+ // Check shape exists.
+ GeomShapePtr aShapeInList = aSelectionAttrInList->value();
+ if (!aShapeInList.get()) {
+ theError = "Object has no shape";
+ return false;
+ }
+
+ // Check shape type.
+ GeomAPI_Shape::ShapeType aType = aShapeInList->shapeType();
+ if (aType != GeomAPI_Shape::EDGE && aType != GeomAPI_Shape::WIRE) {
+ theError = "Incorrect objects selected";
+ return false;
+ }
+ }
+
+ return true;
+}
Events_InfoMessage& theError) const;
};
+/// \class BuildPlugin_ValidatorFillingSelection
+/// \ingroup Validators
+/// \brief A validator for selection of Filling feature.
+class BuildPlugin_ValidatorFillingSelection: public ModelAPI_AttributeValidator
+{
+public:
+ //! Returns true if attribute is ok.
+ //! \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
BuildPlugin_Wire.h
BuildPlugin_Face.h
BuildPlugin_Shell.h
+ BuildPlugin_Solid.h
+ BuildPlugin_CompSolid.h
+ BuildPlugin_Compound.h
BuildPlugin_SubShapes.h
+ BuildPlugin_Filling.h
BuildPlugin_Validators.h
)
BuildPlugin_Wire.cpp
BuildPlugin_Face.cpp
BuildPlugin_Shell.cpp
+ BuildPlugin_Solid.cpp
+ BuildPlugin_CompSolid.cpp
+ BuildPlugin_Compound.cpp
BuildPlugin_SubShapes.cpp
+ BuildPlugin_Filling.cpp
BuildPlugin_Validators.cpp
)
wire_widget.xml
face_widget.xml
shell_widget.xml
+ solid_widget.xml
+ compsolid_widget.xml
+ compound_widget.xml
subshapes_widget.xml
+ filling_widget.xml
)
SET(TEXT_RESOURCES
TestWire.py
TestFace.py
TestShell.py
+ TestSolid.py
+ TestCompSolid.py
+ TestCompound.py
TestSubShapes.py
+ TestFilling_ByEdges.py
+ TestFilling_ByWires.py
+ TestFilling_Mixed.py
Test1920.py)
Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_3r-SketchLine_4r-SketchLine_5r")])
Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_5f")])
Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")], model.selection("EDGE", "PartSet/OY"), 100)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Translated_Edge_1"), model.selection("EDGE", "Face_1_1/Translated_Edge_2"), model.selection("EDGE", "Face_1_1/Translated_Edge_3"), model.selection("EDGE", "Face_1_1/Translated_Edge_4"), model.selection("EDGE", "Face_2_1/Translated_Edge_1"), model.selection("EDGE", "Face_2_1/Translated_Edge_2"), model.selection("EDGE", "Face_2_1/Translated_Edge_3"), model.selection("EDGE", "Face_2_1/Translated_Edge_4")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Translation_1_1/Translated_Edge_1"), model.selection("EDGE", "Translation_1_1/Translated_Edge_2"), model.selection("EDGE", "Translation_1_1/Translated_Edge_3"), model.selection("EDGE", "Translation_1_1/Translated_Edge_4"), model.selection("EDGE", "Translation_1_2/Translated_Edge_1"), model.selection("EDGE", "Translation_1_2/Translated_Edge_2"), model.selection("EDGE", "Translation_1_2/Translated_Edge_3"), model.selection("EDGE", "Translation_1_2/Translated_Edge_4")])
aGroupFeature = Group_1.feature()
aSelectionList = aGroupFeature.selectionList("group_list")
model.end()
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from SketchAPI import *
+from GeomAPI import GeomAPI_Shape
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(40, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 40)
+SketchLine_3 = Sketch_1.addLine(0, 40, 40, 40)
+SketchLine_4 = Sketch_1.addLine(40, 40, 40, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")])
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchLine_5 = Sketch_2.addLine(20, 0, 0, 0)
+SketchLine_6 = Sketch_2.addLine(0, 0, 0, 20)
+SketchLine_7 = Sketch_2.addLine(0, 20, 20, 20)
+SketchLine_8 = Sketch_2.addLine(20, 20, 20, 0)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), False)
+SketchLine_9 = SketchProjection_2.createdFeature()
+SketchConstraintMiddle_1 = Sketch_2.setMiddlePoint(SketchLine_5.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_9).startPoint(), SketchLine_5.endPoint())
+SketchConstraintEqual_2 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result())
+SketchLine_10 = Sketch_2.addLine(20, 20, 20, 40)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_2.addLine(20, 40, 0, 40)
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchLine_12 = Sketch_2.addLine(0, 40, 0, 20)
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_12.endPoint())
+SketchConstraintVertical_5 = Sketch_2.setVertical(SketchLine_10.result())
+SketchConstraintHorizontal_5 = Sketch_2.setHorizontal(SketchLine_11.result())
+SketchConstraintVertical_6 = Sketch_2.setVertical(SketchLine_12.result())
+SketchConstraintEqual_3 = Sketch_2.setEqual(SketchLine_6.result(), SketchLine_12.result())
+model.do()
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("FACE", "Face_2_1")], model.selection("EDGE", "PartSet/OZ"), 270, 2)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "AngularCopy_1_1_1"), model.selection("FACE", "AngularCopy_1_1_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_7f-SketchLine_10f-SketchLine_11f-SketchLine_12f")], model.selection(), 40, 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_13 = Sketch_3.addLine(40, 0, 20, 0)
+SketchLine_14 = Sketch_3.addLine(20, 0, 20, 40)
+SketchLine_15 = Sketch_3.addLine(20, 40, 40, 40)
+SketchLine_16 = Sketch_3.addLine(40, 40, 40, 0)
+SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchLine_16.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchConstraintHorizontal_6 = Sketch_3.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_7 = Sketch_3.setVertical(SketchLine_14.result())
+SketchConstraintHorizontal_7 = Sketch_3.setHorizontal(SketchLine_15.result())
+SketchConstraintVertical_8 = Sketch_3.setVertical(SketchLine_16.result())
+SketchProjection_3 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_5s-SketchLine_15s-SketchLine_8e-SketchLine_14e"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates())
+SketchProjection_4 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_11s-SketchLine_10e"), False)
+SketchPoint_3 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchAPI_Point(SketchPoint_3).coordinates())
+SketchProjection_5 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_2e"), False)
+SketchPoint_4 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_21 = Sketch_3.setCoincident(SketchLine_13.startPoint(), SketchAPI_Point(SketchPoint_4).coordinates())
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r")], model.selection(), 20, 0)
+Box_1 = model.addBox(Part_1_doc, 20, 20, 20)
+model.do()
+
+def createCompSolidStepByStep(theSelection, theExpectedType):
+ CompSolid = model.addCompSolid(Part_1_doc, [theSelection[0]])
+ aList = []
+ for selection, expected in zip(theSelection, theExpectedType):
+ aList.append(selection)
+ CompSolid.setBase(aList)
+ if expected == GeomAPI_Shape.SHAPE:
+ assert(len(CompSolid.results()) == 0), "FAILED: CompSolid should not be built"
+ else:
+ assert(len(CompSolid.results()) > 0), "FAILED: CompSolid is not built"
+ resultType = CompSolid.results()[0].resultSubShapePair()[0].shape().shapeType()
+ assert(resultType == expected), "FAILED: Result has unexpected type"
+ # remove solid if it is not built
+ if len(CompSolid.results()) == 0:
+ Part_1_doc.removeFeature(CompSolid.feature())
+ return None
+ return CompSolid
+
+# =============================================================================
+# Test 1. Build compsolid cointaining 2 solids
+# =============================================================================
+boundaries1 = [model.selection("FACE", "Face_1_1"),
+ model.selection("SHELL", "Shell_1_1"),
+ model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_2"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/To_Face_1"),
+ model.selection("FACE", "Box_1_1/Front")]
+expectType1 = [GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SOLID,
+ GeomAPI_Shape.COMPSOLID]
+CompSolid_1 = createCompSolidStepByStep(boundaries1, expectType1)
+
+model.checkBooleansResult(CompSolid_1, model, 1, [2], [2], [13], [54], [108])
+model.testHaveNamingSubshapes(CompSolid_1, model, Part_1_doc)
+
+# =============================================================================
+# Test 2. Build compsolid containing 3 solids
+# =============================================================================
+boundaries2 = [model.selection("FACE", "Face_1_1"),
+ model.selection("SHELL", "Shell_1_1"),
+ model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/To_Face_1"),
+ model.selection("FACE", "Box_1_1/Front"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_2"),
+ model.selection("SOLID", "Extrusion_1_1")]
+expectType2 = [GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SHAPE,
+ GeomAPI_Shape.SOLID,
+ GeomAPI_Shape.COMPSOLID,
+ GeomAPI_Shape.COMPSOLID]
+CompSolid_2 = createCompSolidStepByStep(boundaries2, expectType2)
+
+model.checkBooleansResult(CompSolid_2, model, 1, [3], [3], [21], [88], [176])
+model.testHaveNamingSubshapes(CompSolid_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-19.49406233194174, -69.37451616542793, -72.71146724766345, -69.37451616542793)
+SketchLine_2 = Sketch_1.addLine(-72.71146724766345, -69.37451616542793, -72.71146724766345, -28.67067780808921)
+SketchLine_3 = Sketch_1.addLine(-72.71146724766345, -28.67067780808921, -19.49406233194174, -28.67067780808921)
+SketchLine_4 = Sketch_1.addLine(-19.49406233194174, -28.67067780808921, -19.49406233194174, -69.37451616542793)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(16.67888107989752, -75.92151145213565, 19.40636912075787, -34.81908596556777)
+SketchPoint_1 = Sketch_1.addPoint(0.6128545881206371, -78.63973361497078)
+SketchCircle_1 = Sketch_1.addCircle(51.0302184611028, -58.25492948210744, 14.6764214847306)
+SketchCircle_2 = Sketch_1.addCircle(57.27434431552349, -55.3477547099222, 30.40870102508203)
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "PartSet/Origin")])
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_5")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_2_2")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchLine_6 = Sketch_2.addLine(73.69205241424749, 19.68979803478298, 29.86213888681927, 19.68979803478298)
+SketchLine_7 = Sketch_2.addLine(29.86213888681927, 19.68979803478298, 29.86213888681927, 46.16063196348271)
+SketchLine_8 = Sketch_2.addLine(29.86213888681927, 46.16063196348271, 73.69205241424749, 46.16063196348271)
+SketchLine_9 = Sketch_2.addLine(73.69205241424749, 46.16063196348271, 73.69205241424749, 19.68979803478298)
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_7.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_8.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_9.result())
+model.do()
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_6r-SketchLine_7r-SketchLine_8r-SketchLine_9r")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("FACE", "Face_2_1")], model.selection("EDGE", "Sketch_2/Edge-SketchLine_6"), 120, 2)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "AngularCopy_1_1_1"), model.selection("FACE", "AngularCopy_1_1_2")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_2_1/Front"), 5, True)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("FACE", "Plane_1")])
+Compound_1_objects = [model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_1"),
+ model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"),
+ model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"),
+ model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"),
+ model.selection("VERTEX", "Vertex_1_1"),
+ model.selection("EDGE", "Edge_1_1"),
+ model.selection("WIRE", "Wire_1_1"),
+ model.selection("FACE", "Face_1_1"),
+ model.selection("SHELL", "Shell_1_1"),
+ model.selection("SOLID", "Translation_1_1"),
+ model.selection("COMPSOLID", "Partition_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.do()
+
+model.checkBooleansResult(Compound_1, model, 1, [11], [3], [22], [92], [186])
+
+model.end()
+
+assert(model.checkPythonDump())
# Test results
assert (len(anEdgeFeature.results()) == aNumOfLines)
+# Test edge building on edge of another result
+aSession.startOperation()
+aBox = aPart.addFeature("Box")
+aBox.string("CreationMethod").setValue("BoxByDimensions")
+aBox.real("dx").setValue(50)
+aBox.real("dy").setValue(50)
+aBox.real("dz").setValue(50)
+aSession.finishOperation()
+aBoxResult = aBox.firstResult()
+aBoxShape = aBoxResult.shape()
+
+# Create edges
+aSession.startOperation()
+anEdgeFeature2 = aPart.addFeature("Edge")
+aBaseObjectsList = anEdgeFeature2.selectionList("base_objects")
+aShapeExplorer = GeomAPI_ShapeExplorer(aBoxShape, GeomAPI_Shape.EDGE)
+aShapes = []
+while aShapeExplorer.more():
+ # keep unique shapes only
+ aCurrent = aShapeExplorer.current()
+ isNewShape = True
+ for s in aShapes:
+ if s.isSame(aCurrent):
+ isNewShape = False
+ break
+ if isNewShape:
+ aShapes.append(aCurrent)
+ aShapeExplorer.next()
+
+for s in aShapes:
+ aBaseObjectsList.append(aBoxResult, s)
+aSession.finishOperation()
+
+# Test results
+assert (len(anEdgeFeature2.results()) == 12)
+
from salome.shaper import model
assert(model.checkPythonDump())
aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
aPart = aPartResult.partDoc()
+# =============================================================================
+# Test 1. Create face from edges of sketch
+# =============================================================================
+
# Create a sketch
aSession.startOperation()
aSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
# Test results
assert (len(aFaceFeature.results()) > 0)
+# =============================================================================
+# Test 2. Create face from edges of solid
+# =============================================================================
+
+# Cylinder
+aSession.startOperation()
+aCylinder = aPart.addFeature("Cylinder")
+aCylinder.string("CreationMethod").setValue("Cylinder")
+aCylinder.selection("base_point").selectSubShape("VERTEX", "PartSet/Origin")
+aCylinder.selection("axis").selectSubShape("EDGE", "PartSet/OZ")
+aCylinder.real("radius").setValue(5)
+aCylinder.real("height").setValue(10)
+aSession.finishOperation()
+aCylinderResult = aCylinder.firstResult()
+aCylinderShape = aCylinderResult.shape()
+
+# Create face
+aSession.startOperation()
+aFaceFeature2 = aPart.addFeature("Face")
+aBaseObjectsList = aFaceFeature2.selectionList("base_objects")
+aBaseObjectsList.append("Cylinder_1_1/Face_1&Cylinder_1_1/Face_2", "EDGE")
+aSession.finishOperation()
+assert (len(aFaceFeature2.results()) > 0)
+
+# =============================================================================
+# Test 3. Create face from face of solid
+# =============================================================================
+
+aSession.startOperation()
+aFaceFeature3 = aPart.addFeature("Face")
+aBaseObjectsList = aFaceFeature3.selectionList("base_objects")
+aBaseObjectsList.append("Cylinder_1_1/Face_1", "FACE")
+aSession.finishOperation()
+assert (len(aFaceFeature3.results()) > 0)
+
+# =============================================================================
+# Test 4. Verify error is reported if selection of face feature is mixed (edges and face)
+# =============================================================================
+
+aSession.startOperation()
+aFaceFeature4 = aPart.addFeature("Face")
+aBaseObjectsList = aFaceFeature4.selectionList("base_objects")
+aShapeExplorer = GeomAPI_ShapeExplorer(aSketchShape, GeomAPI_Shape.EDGE)
+while aShapeExplorer.more():
+ aBaseObjectsList.append(aSketchResult, aShapeExplorer.current())
+ aShapeExplorer.next()
+aBaseObjectsList.append("Cylinder_1_1/Face_3", "FACE")
+aSession.finishOperation()
+assert (len(aFaceFeature4.results()) == 0)
+# remove failed feature
+aSession.startOperation()
+aPart.removeFeature(aFaceFeature4)
+aSession.finishOperation()
+
from salome.shaper import model
assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+# Initialization of the test
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+
+# Get document
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+
+# Create a part
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+# Create first edge in a sketch
+aSession.startOperation()
+aSketch1 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch1.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch1.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch1.attribute("Norm"))
+aNorm.setValue(0, 0, 1)
+# an arc
+anArc = aSketch1.addFeature("SketchArc")
+anArcCenter = geomDataAPI_Point2D(anArc.attribute("center_point"))
+anArcCenter.setValue(1, 1)
+anArcStartPoint = geomDataAPI_Point2D(anArc.attribute("start_point"))
+anArcStartPoint.setValue(20, 5)
+anArcEndPoint = geomDataAPI_Point2D(anArc.attribute("end_point"))
+anArcEndPoint.setValue(5, 20)
+aSession.finishOperation()
+aSketch1Result = aSketch1.firstResult()
+
+# Create second edge in another sketch
+aSession.startOperation()
+aSketch2 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch2.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch2.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch2.attribute("Norm"))
+aNorm.setValue(0, 0.7071067811865475, 0.7071067811865475)
+# a line
+aLine = aSketch2.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+aLineStartPoint.setValue(0, 0)
+aLineEndPoint = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+aLineEndPoint.setValue(20, 20)
+aSession.finishOperation()
+aSketch2Result = aSketch2.firstResult()
+# an edge
+aSession.startOperation()
+anEdge = aPart.addFeature("Edge")
+aBaseObjectsList = anEdge.selectionList("base_objects")
+aBaseObjectsList.append(aSketch2Result, aLine.lastResult().shape())
+aSession.finishOperation()
+
+# Create filling
+aSession.startOperation()
+aFillingFeature = aPart.addFeature("Filling")
+aBaseObjectsList = aFillingFeature.selectionList("base_objects")
+aBaseObjectsList.append(aSketch1Result, anArc.lastResult().shape())
+aSession.finishOperation()
+
+# =============================================================================
+# Test 1. Filling on one edge is failed (no result is built)
+# =============================================================================
+assert(len(aFillingFeature.results()) == 0)
+
+# =============================================================================
+# Test 2. Add another edge, filling should be completed
+# =============================================================================
+aSession.startOperation()
+aBaseObjectsList.append(anEdge.lastResult(), None)
+aSession.finishOperation()
+assert(len(aFillingFeature.results()) > 0)
+
+# =============================================================================
+# Test 3. Change parameters one-by-one and check validity of result
+# =============================================================================
+aSession.startOperation()
+aFillingFeature.string("advanced_options").setValue("true")
+aSession.finishOperation()
+orientations = ["auto_correct", "curve_info", "edge_orient"]
+tolerances = [0.0001, 0.001]
+for ori in orientations:
+ for minDeg in range(2, 4):
+ for maxDeg in range(5, 7):
+ for nbIter in range(0, 3, 2):
+ for tol2d in tolerances:
+ for tol3d in tolerances:
+ for approx in [False, True]:
+ aSession.startOperation()
+ aFillingFeature.string("orientation").setValue(ori)
+ aFillingFeature.integer("min_degree").setValue(minDeg)
+ aFillingFeature.integer("max_degree").setValue(maxDeg)
+ aFillingFeature.integer("nb_iter").setValue(nbIter)
+ aFillingFeature.real("tol_2d").setValue(tol2d)
+ aFillingFeature.real("tol_3d").setValue(tol3d)
+ aFillingFeature.boolean("approximation").setValue(approx)
+ aSession.finishOperation()
+ assert(len(aFillingFeature.results()) > 0), "Filling feature failed with parameters:\n orientation={}\n min deg={}\n max deg={}\n nb iter={}\n tol 2d={}\n tol 3d={}\n approximation={}".format(ori, minDeg, maxDeg, nbIter, tol2d, tol3d, approx)
+
+# =============================================================================
+# Test 4. Discard parameters to default and add one more edge
+# =============================================================================
+aSession.startOperation()
+aFillingFeature.string("advanced_options").setValue("")
+aSession.finishOperation()
+# new arc
+aSession.startOperation()
+anArc2 = aSketch1.addFeature("SketchArc")
+anArc2Center = geomDataAPI_Point2D(anArc2.attribute("center_point"))
+anArc2Center.setValue(0, -5)
+anArc2StartPoint = geomDataAPI_Point2D(anArc2.attribute("start_point"))
+anArc2StartPoint.setValue(-20, -5)
+anArc2EndPoint = geomDataAPI_Point2D(anArc2.attribute("end_point"))
+anArc2EndPoint.setValue(20, -5)
+aSession.finishOperation()
+aSketch1Result = aSketch1.firstResult()
+# update filling
+aSession.startOperation()
+aPart.setCurrentFeature(aFillingFeature, True)
+aBaseObjectsList.append(aSketch1Result, anArc2.lastResult().shape())
+aSession.finishOperation()
+assert(len(aFillingFeature.results()) > 0)
+
+from salome.shaper import model
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+# Initialization of the test
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+
+# Get document
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+
+# Create a part
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+# Create first wire in a sketch
+aSession.startOperation()
+aSketch1 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch1.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch1.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch1.attribute("Norm"))
+aNorm.setValue(0, 0, 1)
+# arc 1
+anArc1 = aSketch1.addFeature("SketchArc")
+anArcCenter = geomDataAPI_Point2D(anArc1.attribute("center_point"))
+anArcCenter.setValue(1, 1)
+anArcStartPoint = geomDataAPI_Point2D(anArc1.attribute("start_point"))
+anArcStartPoint.setValue(20, 5)
+anArcEndPoint = geomDataAPI_Point2D(anArc1.attribute("end_point"))
+anArcEndPoint.setValue(5, 20)
+# arc 2
+anArc2 = aSketch1.addFeature("SketchArc")
+anArcCenter = geomDataAPI_Point2D(anArc2.attribute("center_point"))
+anArcCenter.setValue(12.5, 12.5)
+anArcStartPoint = geomDataAPI_Point2D(anArc2.attribute("start_point"))
+anArcStartPoint.setValue(5, 20)
+anArcEndPoint = geomDataAPI_Point2D(anArc2.attribute("end_point"))
+anArcEndPoint.setValue(20, 5)
+aSession.finishOperation()
+aSketch1Result = aSketch1.firstResult()
+# a wire
+aSession.startOperation()
+aWire1 = aPart.addFeature("Wire")
+aBaseObjectsList = aWire1.selectionList("base_objects")
+aBaseObjectsList.append(aSketch1Result, anArc1.lastResult().shape())
+aBaseObjectsList.append(aSketch1Result, anArc2.lastResult().shape())
+aSession.finishOperation()
+
+# Create second wire in another sketch
+aSession.startOperation()
+aSketch2 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch2.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch2.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch2.attribute("Norm"))
+aNorm.setValue(0, 0.7071067811865475, 0.7071067811865475)
+# line 1
+aLine1 = aSketch2.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aLine1.attribute("StartPoint"))
+aLineStartPoint.setValue(30, 0)
+aLineEndPoint = geomDataAPI_Point2D(aLine1.attribute("EndPoint"))
+aLineEndPoint.setValue(20, 20)
+# line 2
+aLine2 = aSketch2.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aLine2.attribute("StartPoint"))
+aLineStartPoint.setValue(20, 20)
+aLineEndPoint = geomDataAPI_Point2D(aLine2.attribute("EndPoint"))
+aLineEndPoint.setValue(20, 0)
+aSession.finishOperation()
+aSketch2Result = aSketch2.firstResult()
+# a wire
+aSession.startOperation()
+aWire2 = aPart.addFeature("Wire")
+aBaseObjectsList = aWire2.selectionList("base_objects")
+aBaseObjectsList.append(aSketch2Result, aLine1.lastResult().shape())
+aBaseObjectsList.append(aSketch2Result, aLine2.lastResult().shape())
+aSession.finishOperation()
+
+# Create filling
+aSession.startOperation()
+aFillingFeature = aPart.addFeature("Filling")
+aBaseObjectsList = aFillingFeature.selectionList("base_objects")
+aBaseObjectsList.append(aWire1.lastResult(), None)
+aSession.finishOperation()
+
+# =============================================================================
+# Test 1. Filling on one wire is failed (no result is built)
+# =============================================================================
+assert(len(aFillingFeature.results()) == 0)
+
+# =============================================================================
+# Test 2. Add another wire, filling should be completed
+# =============================================================================
+aSession.startOperation()
+aBaseObjectsList.append(aWire2.lastResult(), None)
+aSession.finishOperation()
+assert(len(aFillingFeature.results()) > 0)
+
+# =============================================================================
+# Test 3. Change parameters one-by-one and check validity of result
+# =============================================================================
+aSession.startOperation()
+aFillingFeature.string("advanced_options").setValue("true")
+aSession.finishOperation()
+orientations = ["auto_correct", "curve_info", "edge_orient"]
+tolerances = [0.0001, 0.001]
+for ori in orientations:
+ for minDeg in range(2, 4):
+ for maxDeg in range(5, 7):
+ for nbIter in range(0, 3, 2):
+ for tol2d in tolerances:
+ for tol3d in tolerances:
+ for approx in [False, True]:
+ aSession.startOperation()
+ aFillingFeature.string("orientation").setValue(ori)
+ aFillingFeature.integer("min_degree").setValue(minDeg)
+ aFillingFeature.integer("max_degree").setValue(maxDeg)
+ aFillingFeature.integer("nb_iter").setValue(nbIter)
+ aFillingFeature.real("tol_2d").setValue(tol2d)
+ aFillingFeature.real("tol_3d").setValue(tol3d)
+ aFillingFeature.boolean("approximation").setValue(approx)
+ aSession.finishOperation()
+ assert(len(aFillingFeature.results()) > 0), "Filling feature failed with parameters:\n orientation={}\n min deg={}\n max deg={}\n nb iter={}\n tol 2d={}\n tol 3d={}\n approximation={}".format(ori, minDeg, maxDeg, nbIter, tol2d, tol3d, approx)
+
+from salome.shaper import model
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+# Initialization of the test
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+
+# Get document
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+
+# Create a part
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+# Create first edge in a sketch
+aSession.startOperation()
+aSketch1 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch1.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch1.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch1.attribute("Norm"))
+aNorm.setValue(0, 0, 1)
+# an arc
+anArc = aSketch1.addFeature("SketchArc")
+anArcCenter = geomDataAPI_Point2D(anArc.attribute("center_point"))
+anArcCenter.setValue(1, 1)
+anArcStartPoint = geomDataAPI_Point2D(anArc.attribute("start_point"))
+anArcStartPoint.setValue(20, 5)
+anArcEndPoint = geomDataAPI_Point2D(anArc.attribute("end_point"))
+anArcEndPoint.setValue(5, 20)
+aSession.finishOperation()
+aSketch1Result = aSketch1.firstResult()
+
+# Create a wire in another sketch
+aSession.startOperation()
+aSketch2 = featureToCompositeFeature(aPart.addFeature("Sketch"))
+anOrigin = geomDataAPI_Point(aSketch2.attribute("Origin"))
+anOrigin.setValue(0, 0, 0)
+aDirX = geomDataAPI_Dir(aSketch2.attribute("DirX"))
+aDirX.setValue(1, 0, 0)
+aNorm = geomDataAPI_Dir(aSketch2.attribute("Norm"))
+aNorm.setValue(0, 0.7071067811865475, 0.7071067811865475)
+# line 1
+aLine1 = aSketch2.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aLine1.attribute("StartPoint"))
+aLineStartPoint.setValue(0, 0)
+aLineEndPoint = geomDataAPI_Point2D(aLine1.attribute("EndPoint"))
+aLineEndPoint.setValue(10, 10)
+# line 2
+aLine2 = aSketch2.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aLine2.attribute("StartPoint"))
+aLineStartPoint.setValue(10, 10)
+aLineEndPoint = geomDataAPI_Point2D(aLine2.attribute("EndPoint"))
+aLineEndPoint.setValue(30, 0)
+aSession.finishOperation()
+aSketch2Result = aSketch2.firstResult()
+# a wire
+aSession.startOperation()
+aWire = aPart.addFeature("Wire")
+aBaseObjectsList = aWire.selectionList("base_objects")
+aBaseObjectsList.append(aSketch2Result, aLine1.lastResult().shape())
+aBaseObjectsList.append(aSketch2Result, aLine2.lastResult().shape())
+aSession.finishOperation()
+
+# Create filling
+aSession.startOperation()
+aFillingFeature = aPart.addFeature("Filling")
+aBaseObjectsList = aFillingFeature.selectionList("base_objects")
+aBaseObjectsList.append(aSketch1Result, anArc.lastResult().shape())
+aSession.finishOperation()
+
+# =============================================================================
+# Test 1. Filling on one edge is failed (no result is built)
+# =============================================================================
+assert(len(aFillingFeature.results()) == 0)
+
+# =============================================================================
+# Test 2. Add a wire, filling should be completed
+# =============================================================================
+aSession.startOperation()
+aBaseObjectsList.append(aWire.lastResult(), None)
+aSession.finishOperation()
+assert(len(aFillingFeature.results()) > 0)
+
+# =============================================================================
+# Test 3. Change parameters one-by-one and check validity of result
+# =============================================================================
+aSession.startOperation()
+aFillingFeature.string("advanced_options").setValue("true")
+aSession.finishOperation()
+orientations = ["auto_correct", "curve_info", "edge_orient"]
+tolerances = [0.0001, 0.001]
+for ori in orientations:
+ for minDeg in range(2, 4):
+ for maxDeg in range(5, 7):
+ for nbIter in range(0, 3, 2):
+ for tol2d in tolerances:
+ for tol3d in tolerances:
+ for approx in [False, True]:
+ aSession.startOperation()
+ aFillingFeature.string("orientation").setValue(ori)
+ aFillingFeature.integer("min_degree").setValue(minDeg)
+ aFillingFeature.integer("max_degree").setValue(maxDeg)
+ aFillingFeature.integer("nb_iter").setValue(nbIter)
+ aFillingFeature.real("tol_2d").setValue(tol2d)
+ aFillingFeature.real("tol_3d").setValue(tol3d)
+ aFillingFeature.boolean("approximation").setValue(approx)
+ aSession.finishOperation()
+ assert(len(aFillingFeature.results()) > 0), "Filling feature failed with parameters:\n orientation={}\n min deg={}\n max deg={}\n nb iter={}\n tol 2d={}\n tol 3d={}\n approximation={}".format(ori, minDeg, maxDeg, nbIter, tol2d, tol3d, approx)
+
+# =============================================================================
+# Test 4. Discard parameters to default and add one more edge
+# =============================================================================
+aSession.startOperation()
+aFillingFeature.string("advanced_options").setValue("")
+aSession.finishOperation()
+# new arc
+aSession.startOperation()
+anArc2 = aSketch1.addFeature("SketchArc")
+anArc2Center = geomDataAPI_Point2D(anArc2.attribute("center_point"))
+anArc2Center.setValue(0, -5)
+anArc2StartPoint = geomDataAPI_Point2D(anArc2.attribute("start_point"))
+anArc2StartPoint.setValue(-20, -5)
+anArc2EndPoint = geomDataAPI_Point2D(anArc2.attribute("end_point"))
+anArc2EndPoint.setValue(20, -5)
+aSession.finishOperation()
+aSketch1Result = aSketch1.firstResult()
+# an edge
+aSession.startOperation()
+aPart.setCurrentFeature(aWire, True)
+anEdge = aPart.addFeature("Edge")
+anEdgeObjectsList = anEdge.selectionList("base_objects")
+anEdgeObjectsList.append(aSketch1Result, anArc2.lastResult().shape())
+aSession.finishOperation()
+# update filling
+aSession.startOperation()
+aPart.setCurrentFeature(aFillingFeature, True)
+aBaseObjectsList.append(anEdge.lastResult(), None)
+aSession.finishOperation()
+assert(len(aFillingFeature.results()) > 0)
+
+from salome.shaper import model
+assert(model.checkPythonDump())
# Test results
assert (len(aShellFeature.results()) > 0)
+# Test shell building on set of faces from another result
+
+# Cylinder
+aSession.startOperation()
+aCylinder = aPart.addFeature("Cylinder")
+aCylinder.string("CreationMethod").setValue("Cylinder")
+aCylinder.selection("base_point").selectSubShape("VERTEX", "PartSet/Origin")
+aCylinder.selection("axis").selectSubShape("EDGE", "PartSet/OZ")
+aCylinder.real("radius").setValue(25)
+aCylinder.real("height").setValue(50)
+aSession.finishOperation()
+aCylinderResult = aCylinder.firstResult()
+aCylinderShape = aCylinderResult.shape()
+
+# Create shell
+aSession.startOperation()
+aShellFeature2 = aPart.addFeature("Shell")
+aBaseObjectsList = aShellFeature2.selectionList("base_objects")
+aBaseObjectsList.append("Cylinder_1_1/Face_1", "FACE")
+aBaseObjectsList.append("Cylinder_1_1/Face_3", "FACE")
+aSession.finishOperation()
+
+# Test results
+assert (len(aShellFeature2.results()) > 0)
+
from salome.shaper import model
assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(40, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 40)
+SketchLine_3 = Sketch_1.addLine(0, 40, 40, 40)
+SketchLine_4 = Sketch_1.addLine(40, 40, 40, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")])
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchLine_5 = Sketch_2.addLine(20, 0, 0, 0)
+SketchLine_6 = Sketch_2.addLine(0, 0, 0, 20)
+SketchLine_7 = Sketch_2.addLine(0, 20, 20, 20)
+SketchLine_8 = Sketch_2.addLine(20, 20, 20, 0)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), False)
+SketchLine_9 = SketchProjection_2.createdFeature()
+SketchConstraintMiddle_1 = Sketch_2.setMiddlePoint(SketchLine_5.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_9).startPoint(), SketchLine_5.endPoint())
+SketchConstraintEqual_2 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result())
+SketchLine_10 = Sketch_2.addLine(20, 20, 20, 40)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_2.addLine(20, 40, 0, 40)
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchLine_12 = Sketch_2.addLine(0, 40, 0, 20)
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_12.endPoint())
+SketchConstraintVertical_5 = Sketch_2.setVertical(SketchLine_10.result())
+SketchConstraintHorizontal_5 = Sketch_2.setHorizontal(SketchLine_11.result())
+SketchConstraintVertical_6 = Sketch_2.setVertical(SketchLine_12.result())
+SketchConstraintEqual_3 = Sketch_2.setEqual(SketchLine_6.result(), SketchLine_12.result())
+model.do()
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("FACE", "Face_2_1")], model.selection("EDGE", "PartSet/OZ"), 270, 2)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "AngularCopy_1_1_1"), model.selection("FACE", "AngularCopy_1_1_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_7f-SketchLine_10f-SketchLine_11f-SketchLine_12f")], model.selection(), 40, 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_13 = Sketch_3.addLine(40, 0, 20, 0)
+SketchLine_14 = Sketch_3.addLine(20, 0, 20, 40)
+SketchLine_15 = Sketch_3.addLine(20, 40, 40, 40)
+SketchLine_16 = Sketch_3.addLine(40, 40, 40, 0)
+SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchLine_16.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchConstraintHorizontal_6 = Sketch_3.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_7 = Sketch_3.setVertical(SketchLine_14.result())
+SketchConstraintHorizontal_7 = Sketch_3.setHorizontal(SketchLine_15.result())
+SketchConstraintVertical_8 = Sketch_3.setVertical(SketchLine_16.result())
+SketchProjection_3 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_5s-SketchLine_15s-SketchLine_8e-SketchLine_14e"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates())
+SketchProjection_4 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_11s-SketchLine_10e"), False)
+SketchPoint_3 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchAPI_Point(SketchPoint_3).coordinates())
+SketchProjection_5 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_2e"), False)
+SketchPoint_4 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_21 = Sketch_3.setCoincident(SketchLine_13.startPoint(), SketchAPI_Point(SketchPoint_4).coordinates())
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r")], model.selection(), 20, 0)
+Box_1 = model.addBox(Part_1_doc, 20, 20, 20)
+model.do()
+
+def createSolidStepByStep(theSelection, theExpected):
+ Solid = model.addSolid(Part_1_doc, [theSelection[0]])
+ aList = []
+ for selection, expected in zip(theSelection, theExpected):
+ aList.append(selection)
+ Solid.setBase(aList)
+ if expected:
+ assert(len(Solid.results()) > 0), "FAILED: Solid is not built"
+ else:
+ assert(len(Solid.results()) == 0), "FAILED: Solid should not be built"
+ # remove solid if it is not built
+ if len(Solid.results()) == 0:
+ Part_1_doc.removeFeature(Solid.feature())
+ return None
+ return Solid
+
+# =============================================================================
+# Test 1. Build solid from faces applicable for compsolid
+# =============================================================================
+boundaries1 = [model.selection("FACE", "Face_1_1"),
+ model.selection("SHELL", "Shell_1_1"),
+ model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_2"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/To_Face_1"),
+ model.selection("FACE", "Box_1_1/Front")]
+expectSolid1 = [False, False, False, False, False, False, False, True, False]
+Solid_1 = createSolidStepByStep(boundaries1, expectSolid1)
+assert(Solid_1 is None)
+
+# =============================================================================
+# Test 2. Build correct solid
+# =============================================================================
+boundaries2 = [model.selection("FACE", "Face_1_1"),
+ model.selection("SHELL", "Shell_1_1"),
+ model.selection("FACE", "Sketch_3/Face-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16r"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_1_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_3"),
+ model.selection("FACE", "Extrusion_2_1/Generated_Face_4"),
+ model.selection("FACE", "Extrusion_2_1/To_Face_1"),
+ model.selection("FACE", "Box_1_1/Front")]
+expectSolid2 = [False, False, False, False, False, False, False, False, True]
+Solid_2 = createSolidStepByStep(boundaries2, expectSolid2)
+
+model.checkBooleansResult(Solid_2, model, 1, [0], [1], [10], [44], [88])
+model.testHaveNamingSubshapes(Solid_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
aPart = aPartResult.partDoc()
+# =============================================================================
+# Test 1. Create wire from edges of sketch
+# =============================================================================
+
# Create a sketch
aSession.startOperation()
aSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
from salome.shaper import model
+# =============================================================================
+# Test 2. Complete contour by selecting only one edge
+# =============================================================================
+
model.begin()
partSet = model.moduleDocument()
Part_1 = model.addPart(partSet)
Wire_1.addContour()
model.end()
+# =============================================================================
+# Test 3. Create wire from edges of solid
+# =============================================================================
+
+# Box
+aSession.startOperation()
+aBox = aPart.addFeature("Box")
+aBox.string("CreationMethod").setValue("BoxByDimensions")
+aBox.real("dx").setValue(20)
+aBox.real("dy").setValue(20)
+aBox.real("dz").setValue(20)
+aSession.finishOperation()
+aBoxResult = aBox.firstResult()
+aBoxShape = aBoxResult.shape()
+
+# Wire
+aSession.startOperation()
+aWireFeature2 = aPart.addFeature("Wire")
+aBaseObjectsList = aWireFeature2.selectionList("base_objects")
+aBaseObjectsList.append("Box_1_1/Front&Box_1_1/Bottom", "EDGE")
+aBaseObjectsList.append("Box_1_1/Front&Box_1_1/Right", "EDGE")
+aBaseObjectsList.append("Box_1_1/Right&Box_1_1/Top", "EDGE")
+aBaseObjectsList.append("Box_1_1/Back&Box_1_1/Top", "EDGE")
+aBaseObjectsList.append("Box_1_1/Back&Box_1_1/Left", "EDGE")
+aBaseObjectsList.append("Box_1_1/Left&Box_1_1/Bottom", "EDGE")
+aSession.finishOperation()
+
+# Test results
+assert (len(aWireFeature2.results()) == 1)
+
assert(model.checkPythonDump())
--- /dev/null
+<!--
+Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+-->
+
+<source>
+ <multi_selector id="base_objects"
+ label="Objects:"
+ tooltip="Select any kind of objects."
+ type_choice="vertices edges wires faces shells solids compsolids compounds"
+ concealment="true">
+ </multi_selector>
+</source>
--- /dev/null
+<!--
+Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+-->
+
+<source>
+ <multi_selector id="base_objects"
+ label="Solids and CompSolids:"
+ tooltip="Select solids or compsolids."
+ type_choice="faces shells solids compsolids"
+ concealment="true">
+ <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="face,shell,solid,compsolid"/>
+ </multi_selector>
+</source>
<multi_selector id="base_objects"
label="Segments and wires:"
tooltip="Select edges on sketch, edges or wires objects."
- type_choice="edges wires"
+ type_choice="edges wires faces"
concealment="true">
- <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire"/>
+ <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire,face"/>
</multi_selector>
<validator id="BuildPlugin_ValidatorBaseForFace" parameters="base_objects"/>
</source>
--- /dev/null
+<!--
+Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+-->
+
+<source>
+ <multi_selector id="base_objects"
+ label="Segments and wires:"
+ tooltip="Select edges or wires."
+ type_choice="edges wires"
+ concealment="false">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="BuildPlugin_ValidatorFillingSelection"/>
+ </multi_selector>
+ <optionalbox id="advanced_options" title="Advanced options">
+ <switch id="orientation" label="Orientation">
+ <case id="auto_correct" title="Auto-correct edges orientation"/>
+ <case id="curve_info" title="Use curve information"/>
+ <case id="edge_orient" title="Use edges orientation"/>
+ </switch>
+ <integervalue id="min_degree" label="Min deg" min="1" default="2">
+ <validator id="GeomValidators_LessOrEqual" parameters="max_degree"/>
+ </integervalue>
+ <integervalue id="max_degree" label="Max deg" min="1" default="5">
+ <validator id="GeomValidators_GreaterOrEqual" parameters="min_degree"/>
+ </integervalue>
+ <integervalue id="nb_iter" label="Nb iter" min="0" default="0"/>
+ <doublevalue id="tol_2d" label="Tol 2D" min="0" default="0.0001" step="0.0001"/>
+ <doublevalue id="tol_3d" label="Tol 3D" min="0" default="0.0001" step="0.0001"/>
+ <boolvalue id="approximation" label="Approximation"/>
+ </optionalbox>
+</source>
<feature id="Shell" title="Shell" tooltip ="Create a shell from faces or shells objects" icon="icons/Build/feature_shell.png">
<source path="shell_widget.xml"/>
</feature>
+ <feature id="Solid" title="Solid" tooltip ="Create a solid from faces or shells" icon="icons/Build/feature_solid.png">
+ <source path="solid_widget.xml"/>
+ </feature>
+ <feature id="CompSolid" title="CompSolid" tooltip ="Create a compsolid from solids or another compsolids" icon="icons/Build/feature_compsolid.png">
+ <source path="compsolid_widget.xml"/>
+ </feature>
+ <feature id="Compound" title="Compound" tooltip ="Create a compound of objects" icon="icons/Build/feature_compound.png">
+ <source path="compound_widget.xml"/>
+ </feature>
</group>
<group id="Modify">
<feature id="SubShapes" title="Sub-Shapes" tooltip ="Allows to add or to remove sub-shapes of the selected shape" icon="icons/Build/feature_subshapes.png">
<source path="subshapes_widget.xml"/>
</feature>
</group>
- </workbench>
+ <group id="Advanced">
+ <feature id="Filling" title="Filling" tooltip="Create face from list of edges" icon="icons/Build/feature_filling.png">
+ <source path="filling_widget.xml"/>
+ </feature>
+ </group>
+ </workbench>
</plugin>
<multi_selector id="base_objects"
label="Faces and shells:"
tooltip="Select faces or shells objects."
- type_choice="objects"
+ type_choice="faces shells"
concealment="true">
- <validator id="GeomValidators_ShapeType" parameters="face,shell"/>
+ <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="face,shell"/>
</multi_selector>
</source>
--- /dev/null
+<!--
+Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+-->
+
+<source>
+ <multi_selector id="base_objects"
+ label="Faces and shells:"
+ tooltip="Select faces or shells."
+ type_choice="faces shells"
+ concealment="true">
+ <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="face,shell"/>
+ </multi_selector>
+</source>
//**********************************************************************************
void CollectionPlugin_WidgetField::onShapeTypeChanged(int theType)
{
- activateSelectionAndFilters(theType == 5? false:true);
+ updateSelectionModesAndFilters(theType == 5? false:true);
AttributeSelectionListPtr aSelList =
myFeature->data()->selectionList(CollectionPlugin_Field::SELECTED_ID());
Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Right&Box_1_1/Top"), model.selection("VERTEX", "Box_1_1/Front&Box_1_1/Left&Box_1_1/Top"), model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Left&Box_1_1/Bottom"))
Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Left&Box_1_1/Top")])
Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
-Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Box_1_1"))
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Partition_1_1"))
Remove_SubShapes_1.setSubShapesToKeep([model.selection("SOLID", "Partition_1_1_2")])
model.do()
# move group
# Tests
IF(${HAVE_SALOME})
- INCLUDE(UnitTest)
-
- ADD_UNIT_TESTS(
- TestExportToGEOM.py
- )
+ ENABLE_TESTING()
+ ADD_SUBDIRECTORY(Test)
ENDIF(${HAVE_SALOME})
--- /dev/null
+# Copyright (C) 2013-2016 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(tests.set)
+
+SET(COMPONENT_NAME SHAPER)
+
+SET(SALOME_SHAPER_INSTALL_TESTS "${SHAPER_INSTALL_PYTHON_FILES}/test")
+SET(TEST_INSTALL_DIRECTORY ${SALOME_SHAPER_INSTALL_TESTS})
+
+# make test
+SET(SALOME_INSTALL_LIBS "lib/salome")
+# Adding KERNEL and GUI libraries to environment so that Salome launches correctly
+if (WIN32)
+ SALOME_ACCUMULATE_ENVIRONMENT(PATH NOCHECK ${KERNEL_ROOT_DIR}/${SALOME_INSTALL_LIBS})
+ SALOME_ACCUMULATE_ENVIRONMENT(PATH NOCHECK ${GUI_ROOT_DIR}/${SALOME_INSTALL_LIBS})
+else()
+ SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${KERNEL_ROOT_DIR}/${SALOME_INSTALL_LIBS})
+ SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${GUI_ROOT_DIR}/${SALOME_INSTALL_LIBS})
+endif()
+SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
+
+
+# -B ${CMAKE_SOURCE_DIR}/doc/salome/examples/testme.py
+FOREACH(tfile ${TEST_NAMES})
+ SET(TEST_NAME ${COMPONENT_NAME}_${tfile})
+ ADD_TEST(NAME ${TEST_NAME}
+ COMMAND ${PYTHON_EXECUTABLE} -B ${CMAKE_CURRENT_SOURCE_DIR}/testme.py ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py)
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES ENVIRONMENT "${tests_env}")
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+ENDFOREACH()
+
+# salome test
+FOREACH(tfile ${TEST_NAMES})
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py
+ DESTINATION ${TEST_INSTALL_DIRECTORY})
+ENDFOREACH()
+
+INSTALL(FILES CTestTestfileInstall.cmake
+ DESTINATION ${TEST_INSTALL_DIRECTORY}
+ RENAME CTestTestfile.cmake)
+
+INSTALL(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
\ No newline at end of file
--- /dev/null
+# Copyright (C) 2016 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(tests.set)
+
+SET(COMPONENT_NAME SHAPER)
+SET(SALOME_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/salome_test_driver.py")
+SET(TIMEOUT 300)
+
+
+FOREACH(tfile ${TEST_NAMES} ${EXAMPLE_NAMES})
+ SET(TEST_NAME ${COMPONENT_NAME}_${tfile})
+ ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+ENDFOREACH()
## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
##
+import salome
from salome.shaper import model
-model.begin()
-partSet = model.moduleDocument()
-Part_1 = model.addPart(partSet)
-Part_1_doc = Part_1.document()
-Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
-SketchLine_1 = Sketch_1.addLine(0, 0, 0, 50)
-SketchLine_2 = Sketch_1.addLine(0, 50, 50, 50)
-SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
-SketchLine_3 = Sketch_1.addLine(50, 50, 50, 0)
-SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
-SketchLine_4 = Sketch_1.addLine(50, 0, 0, 0)
-SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
-SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
-SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.startPoint())
-SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result())
-SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_4.result(), 50)
-SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_1.result(), 50)
-SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_1.result(), SketchLine_3.result())
-SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_2.result(), SketchLine_4.result())
-SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_4.result())
-model.do()
-Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 50, 0)
-model.end()
-
-model.exportToGEOM(Part_1_doc)
+from salome.geom import geomBuilder
+
+import os
+import tempfile
+
+salome.salome_init(0,1)
+geompy = geomBuilder.New(salome.myStudy)
+
+## Get the last object published in the GEOM section of the object browser
+def getLastGEOMShape():
+ sb = salome.myStudy.NewBuilder()
+ comp = salome.myStudy.FindComponent("GEOM")
+ obj = None
+ if comp:
+ iterator = salome.myStudy.NewChildIterator( comp )
+ sobj = None
+ while iterator.More():
+ sobj = iterator.Value()
+ iterator.Next()
+ if sobj:
+ obj = sobj.GetObject()
+ else:
+ raise Exception("GEOM component not found.")
+ return obj
+
+## Get the sub-object i of an object in the object browser
+# Numerotation starts at 1
+def getSubObject(obj, i):
+ ok, sub_sobj = salome.ObjectToSObject(obj).FindSubObject(i)
+ if not ok:
+ raise Exception("No child found at %i for %s"%(i, obj.GetName()))
+ sub_obj = sub_sobj.GetObject()
+ return sub_obj
+
+def dumpShaper(fileName):
+ model.begin()
+ dump=model.moduleDocument().addFeature("Dump")
+ dump.string("file_path").setValue(fileName)
+ dump.string("file_format").setValue("py")
+ model.do()
+ model.end()
+ pass
+
+def getTmpFileName(ext):
+ tempdir = tempfile.gettempdir()
+ tmp_file = tempfile.NamedTemporaryFile(suffix=".%s"%ext, prefix='shaper_', dir=tempdir, delete=False)
+ tmp_filename = tmp_file.name
+ return tmp_filename
+
+# Create 2 boxes
+# Create a group of faces
+# Create a field of faces
+# exportToGEOM
+# Check the result
+# Check the dump
+def testSeveralExportsToGEOM():
+
+ model.begin()
+ partSet = model.moduleDocument()
+ Part_1 = model.addPart(partSet)
+ Part_1_doc = Part_1.document()
+ Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+ Box_2 = model.addBox(Part_1_doc, 20, 20, 20)
+ Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), -10)
+ Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1")])
+ Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Partition_1_1_1/Modified_Face_2_2"), model.selection("FACE", "Box_2_1/Top")])
+ model.do()
+ model.end()
+
+ # First export to GEOM
+ model.exportToGEOM(Part_1_doc)
+
+ # Check that the GEOM object has 1 compsolid and 2 solids
+ geomObject_1 = getLastGEOMShape()
+ assert geompy.NumberOfSubShapes(geomObject_1, geompy.ShapeType["COMPSOLID"]) == 1
+ assert geompy.NumberOfSolids(geomObject_1) == 2
+
+ # Check that the group has 2 faces
+ geomGroup_1 = getSubObject(geomObject_1, 1)
+ assert geompy.NumberOfFaces(geomGroup_1) == 2
+
+ # Add a third box
+ Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+ Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OX"), 20)
+
+ # Second export to GEOM
+ model.exportToGEOM(Part_1_doc)
+
+ # Check that the GEOM object has 3 solids
+ geomObject_2 = getLastGEOMShape()
+ assert geompy.NumberOfSolids(geomObject_2) == 3
+
+ # Dump the salome study (only CORBA modules, SHAPER dump is not in it)
+ tempdir = tempfile.gettempdir()
+ dumpFileGeomBase = "dump_test_geom"
+ dumpFileGeom = os.path.join(tempdir, "%s.py"%dumpFileGeomBase)
+ salome.myStudy.DumpStudy(tempdir, dumpFileGeomBase, True, False)
+
+ # Dump SHAPER
+ dumpFileShaper = os.path.join(tempdir, "dump_test_shaper.py")
+ dumpShaper(dumpFileShaper)
+
+ # Load SHAPER dump
+ execfile(dumpFileShaper)
+
+ # Load GEOM dump
+ execfile(dumpFileGeom)
+
+ # Clean files
+ files = [dumpFileGeom, dumpFileShaper]
+ for f in files:
+ os.remove(f)
+
+ pass
+
+
+
+if __name__ == '__main__':
+ testSeveralExportsToGEOM()
\ No newline at end of file
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+# -*- coding: utf-8 -*-
+
+import os
+import tempfile
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+from salome.shaper import model
+
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+
+## Get the last object published in the GEOM section of the object browser
+def getLastGEOMShape():
+ sb = salome.myStudy.NewBuilder()
+ comp = salome.myStudy.FindComponent("GEOM")
+ obj = None
+ if comp:
+ iterator = salome.myStudy.NewChildIterator( comp )
+ sobj = None
+ while iterator.More():
+ sobj = iterator.Value()
+ iterator.Next()
+ if sobj:
+ obj = sobj.GetObject()
+ else:
+ raise Exception("GEOM component not found.")
+ return obj
+
+## Get the sub-object i of an object in the object browser
+# Numerotation starts at 1
+def getSubObject(obj, i):
+ ok, sub_sobj = salome.ObjectToSObject(obj).FindSubObject(i)
+ if not ok:
+ raise Exception("No child found at %i for %s"%(i, obj.GetName()))
+ sub_obj = sub_sobj.GetObject()
+ return sub_obj
+
+def dumpShaper(fileName):
+ model.begin()
+ dump=model.moduleDocument().addFeature("Dump")
+ dump.string("file_path").setValue(fileName)
+ dump.string("file_format").setValue("py")
+ model.do()
+ model.end()
+ pass
+
+def getTmpFileName(ext):
+ tempdir = tempfile.gettempdir()
+ tmp_file = tempfile.NamedTemporaryFile(suffix=".%s"%ext, prefix='shaper_', dir=tempdir, delete=False)
+ tmp_filename = tmp_file.name
+ return tmp_filename
+
+def testGroupsAndFieldsExportToGEOM():
+ model.begin()
+ partSet = model.moduleDocument()
+ Part_1 = model.addPart(partSet)
+ Part_1_doc = Part_1.document()
+ Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+ Box_2 = model.addBox(Part_1_doc, 20, 20, 20)
+ Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), -10)
+ Translation_1.result().setName("Translation_1_1")
+ Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Translation_1_1"), model.selection("SOLID", "Box_2_1")])
+ Partition_1.result().setName("Partition_1_1")
+ Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+ Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OX"), 20)
+ Translation_2.result().setName("Translation_2_1")
+ Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Partition_1_1_1/Modified_Face_2_2"), model.selection("FACE", "Box_2_1/Top"), model.selection("FACE", "Translation_2_1/Translated_Face_1")])
+ Group_1.result().setName("faces_top")
+ Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Partition_1_1_1/Modified_Face_2_5&Partition_1_1_1/Modified_Face_2_3"), model.selection("EDGE", "Partition_1_1_2/Modified_Face_2_2&Partition_1_1_2/Modified_Face_2_1"), model.selection("EDGE", "Translation_2_1/Translated_Face_4&Translation_2_1/Translated_Face_2")])
+ Group_2.result().setName("edges_x")
+ Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_5&Partition_1_1_1/Modified_Face_2_3"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_4&Translation_2_1/Translated_Face_2"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_3&Translation_2_1/Translated_Face_2"), model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_4&Partition_1_1_1/Modified_Face_2_3"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_3&Partition_1_1_2/Modified_Face_2_1&Box_2_1/Right"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_1&Box_2_1/Front&Box_2_1/Right"), model.selection("VERTEX", "Partition_1_1_1/Modified_Face_2_4&Partition_1_1_1/Modified_Face_2_3&Partition_1_1_1/Modified_Face_2_1"), model.selection("VERTEX", "Translation_2_1/Translated_Face_6&Translation_2_1/Translated_Face_3&Translation_2_1/Translated_Face_2")])
+ Group_3.result().setName("vertices_bottom")
+ Group_4 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Partition_1_1_1"), model.selection("SOLID", "Translation_2_1")])
+ Group_4.result().setName("solids_small")
+ Field_1 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], [model.selection("SOLID", "Partition_1_1_1"), model.selection("SOLID", "Partition_1_1_2"), model.selection("SOLID", "Translation_2_1")])
+ Field_1.result().setName("Field_solids")
+ Field_1.addStep(0, 0, [[0], [1], [2], [3]])
+ Field_2 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], [model.selection("FACE", "Partition_1_1_1/Modified_Face_2_3"), model.selection("FACE", "Partition_1_1_2/Modified_Face_2_1"), model.selection("FACE", "Translation_2_1/Translated_Face_2"), model.selection("FACE", "Partition_1_1_1/Modified_Face_2_2"), model.selection("FACE", "Box_2_1/Top"), model.selection("FACE", "Translation_2_1/Translated_Face_1")])
+ Field_2.result().setName("Field_faces")
+ Field_2.addStep(0, 0, [[0], [1], [1], [1], [2], [2], [2]])
+ Field_3 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], [model.selection("EDGE", "Partition_1_1_1/Modified_Face_2_5&Partition_1_1_1/Modified_Face_2_3"), model.selection("EDGE", "Partition_1_1_2/Modified_Face_2_2&Partition_1_1_2/Modified_Face_2_1"), model.selection("EDGE", "Translation_2_1/Translated_Face_4&Translation_2_1/Translated_Face_2"), model.selection("EDGE", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_3"), model.selection("EDGE", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_2"), model.selection("EDGE", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_1"), model.selection("EDGE", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_2"), model.selection("EDGE", "Partition_1_1_2/Modified_Face_2_3&Box_2_1/Top"), model.selection("EDGE", "Box_2_1/Front&Box_2_1/Top"), model.selection("EDGE", "Partition_1_1_2/Modified_Face_2_2&Box_2_1/Top"), model.selection("EDGE", "Box_2_1/Top&Box_2_1/Right")])
+ Field_3.result().setName("Field_edges")
+ Field_3.addStep(0, 0, [[0], [1], [1], [1], [2], [2], [2], [2], [3], [3], [3], [3]])
+ Field_4 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], [model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_5&Partition_1_1_1/Modified_Face_2_3"), model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_4&Partition_1_1_1/Modified_Face_2_3"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_4&Translation_2_1/Translated_Face_2"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_3&Translation_2_1/Translated_Face_2"), model.selection("VERTEX", "Translation_2_1/Translated_Face_6&Translation_2_1/Translated_Face_3&Translation_2_1/Translated_Face_2"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_1&Box_2_1/Front&Box_2_1/Right"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_3&Partition_1_1_2/Modified_Face_2_1&Box_2_1/Right"), model.selection("VERTEX", "Partition_1_1_1/Modified_Face_2_4&Partition_1_1_1/Modified_Face_2_3&Partition_1_1_1/Modified_Face_2_1"), model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_2&Partition_1_1_1/Modified_Face_2_4"), model.selection("VERTEX", "Translation_1_1/Translated_Face_6&Partition_1_1_1/Modified_Face_2_5&Partition_1_1_1/Modified_Face_2_2"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_4&Translation_2_1/Translated_Face_1"), model.selection("VERTEX", "Translation_2_1/Translated_Face_5&Translation_2_1/Translated_Face_3&Translation_2_1/Translated_Face_1"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_2&Partition_1_1_2/Modified_Face_2_3&Box_2_1/Top"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_3&Box_2_1/Top&Box_2_1/Right"), model.selection("VERTEX", "Partition_1_1_2/Modified_Face_2_2&Box_2_1/Front&Box_2_1/Top"), model.selection("VERTEX", "Box_2_1/Front&Box_2_1/Top&Box_2_1/Right")])
+ Field_4.result().setName("Field_vertices")
+ Field_4.addStep(0, 0, [[0], [1], [1], [1], [1], [1], [1], [1], [1], [2], [2], [2], [2], [3], [3], [3], [3]])
+ model.exportToGEOM(Part_1_doc)
+ model.do()
+ model.end()
+
+# check the groups content by the coordinates of a point on its sub-shapes
+def checkGroupByCoords(group, coords, tolerance=1e-7):
+ for coord in coords:
+ p = geompy.MakeVertex(*coord)
+ assert geompy.MinDistance(group, p) < tolerance
+ pass
+
+## Check the result imported in GEOM
+def checkResultInGEOM():
+ geomObject_1 = getLastGEOMShape()
+
+ group_1_GEOM = getSubObject(geomObject_1, 1)
+ assert group_1_GEOM.GetName() == 'faces_top'
+ assert geompy.NumberOfFaces(group_1_GEOM) == 3
+
+ # coordinates of the barycenters of the faces of Group_1
+ coords_1 = [[-5, 5, 10], [10, 10, 20], [25, 5, 10]]
+ checkGroupByCoords(group_1_GEOM, coords_1)
+
+ group_2_GEOM = getSubObject(geomObject_1, 2)
+ assert group_2_GEOM.GetName() == 'edges_x'
+ assert geompy.NumberOfEdges(group_2_GEOM) == 3
+
+ # coordinates of the barycenters of the edges of Group_2
+ coords_2 = [[-5, 0, 0], [10, 0, 0], [25, 0, 0]]
+ checkGroupByCoords(group_2_GEOM, coords_2)
+
+ group_3_GEOM = getSubObject(geomObject_1, 3)
+ assert group_3_GEOM.GetName() == 'vertices_bottom'
+ assert geompy.NumberOfSubShapes(group_3_GEOM, geompy.ShapeType["VERTEX"]) == 8
+
+ # coordinates of the points of of Group_3
+ coords_3 = [[-10, 0, 0], [-10, 10, 0], [0, 10, 0], [0, 20, 0], [20, 20, 0], [20, 10, 0], [30, 10, 0], [30, 0, 0]]
+ checkGroupByCoords(group_3_GEOM, coords_3)
+
+ group_4_GEOM = getSubObject(geomObject_1, 4)
+ assert group_4_GEOM.GetName() == 'solids_small'
+ assert geompy.NumberOfSolids(group_4_GEOM) == 2
+
+ # coordinates of the barycenters of the solids of Group_4
+ coords_4 = [[-5, 5, 5], [25, 5, 5]]
+ checkGroupByCoords(group_4_GEOM, coords_4)
+
+ field_1_GEOM = getSubObject(geomObject_1, 5)
+ assert field_1_GEOM.GetName() == 'Field_solids'
+ assert field_1_GEOM.GetStep(0).GetValues() == [1.0, 2.0, 3.0]
+
+ field_2_GEOM = getSubObject(geomObject_1, 6)
+ assert field_2_GEOM.GetName() == 'Field_faces'
+ assert field_2_GEOM.GetStep(0).GetValues() == [0.0, 0.0, 2.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0]
+
+ field_3_GEOM = getSubObject(geomObject_1, 7)
+ assert field_3_GEOM.GetName() == 'Field_edges'
+ assert field_3_GEOM.GetStep(0).GetValues() == [0.0, 2.0, 0.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 2.0, 1.0, 0.0, 0.0, 0.0]
+
+ field_4_GEOM = getSubObject(geomObject_1, 8)
+ assert field_4_GEOM.GetName() == 'Field_vertices'
+ assert field_4_GEOM.GetStep(0).GetValues() == [2.0, 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.0, 3.0, 3.0, 1.0, 1.0, 3.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0, 2.0, 1.0]
+
+ pass
+
+def checkDump():
+ # Dump the salome study (only CORBA modules, SHAPER dump is not in it)
+ tempdir = tempfile.gettempdir()
+ dumpFileGeomBase = "dump_test_geom"
+ dumpFileGeom = os.path.join(tempdir, "%s.py"%dumpFileGeomBase)
+ salome.myStudy.DumpStudy(tempdir, dumpFileGeomBase, True, False)
+
+ # Dump SHAPER
+ dumpFileShaper = os.path.join(tempdir, "dump_test_shaper.py")
+ dumpShaper(dumpFileShaper)
+
+ # Load SHAPER dump
+ execfile(dumpFileShaper)
+
+ # Load GEOM dump
+ execfile(dumpFileGeom)
+
+ # Clean files
+ files = [dumpFileGeom, dumpFileShaper]
+ for f in files:
+ os.remove(f)
+
+ pass
+
+if __name__ == '__main__':
+ # create 3 boxes with groups and fields
+ testGroupsAndFieldsExportToGEOM()
+ # check the result in GEOM
+ checkResultInGEOM()
+ # check that dump produces no error and can be reloaded
+ checkDump()
+ # check the result of the dump
+ checkResultInGEOM()
--- /dev/null
+# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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
+#
+
+#!/usr/bin/env python
+
+import unittest, sys, os
+
+class SalomeSession(object):
+ def __init__(self, script):
+ import runSalome
+ run_script = "runSalome.py"
+ if sys.platform == 'win32':
+ module_dir = os.getenv("KERNEL_ROOT_DIR")
+ if module_dir: run_script = os.path.join(module_dir, "bin", "salome", run_script)
+ pass
+ sys.argv = [run_script]
+ sys.argv += ["--terminal"]
+ sys.argv += ["--modules=SHAPER,GEOM"]
+ sys.argv += ["%s" % script]
+ if sys.platform == 'win32':
+ main_module_path = sys.modules['__main__'].__file__
+ sys.modules['__main__'].__file__ = ''
+ clt, d = runSalome.main()
+ if sys.platform == 'win32':
+ sys.modules['__main__'].__file__ = main_module_path
+ return
+
+ def __del__(self):
+ port = os.getenv('NSPORT')
+ import killSalomeWithPort
+ killSalomeWithPort.killMyPort(port)
+ return
+ pass
+
+class MyTest(unittest.TestCase):
+ def testFunction(self):
+ SalomeSession(sys.argv[1])
+ pass
+
+unittest.main(argv=sys.argv[:1])
--- /dev/null
+# Copyright (C) 2016 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
+#
+
+SET(TEST_NAMES
+ TestExportToGEOM
+ TestExportToGEOMAllGroupsAndFields
+)
## @package Plugins
# ExportFeature class definition
-import EventsAPI
import ModelAPI
-import GeomAPI
-import GeomAlgoAPI
+import ExchangeAPI
import salome
from salome.geom import geomBuilder
-def getObjectIndex(theName):
- aStudy = salome.myStudy
- aId = 0
- aObj = aStudy.FindObjectByName(theName, "GEOM")
- while len(aObj) != 0:
- aId = aId + 1
- aName = theName + '_' + str(aId)
- aObj = aStudy.FindObjectByName(aName, "GEOM")
- return aId
+from salome.shaper import model
+
+import os
+
+def getTmpFileName(ext):
+ import tempfile
+ tempdir = tempfile.gettempdir()
+ tmp_file = tempfile.NamedTemporaryFile(suffix=".%s"%ext, prefix='shaper_', dir=tempdir, delete=False)
+ tmp_filename = tmp_file.name
+ if os.name == "nt":
+ tmp_filename.replace("\\", "/")
+ return tmp_filename
## @ingroup Plugins
# Feature to export all shapes and groups into the GEOM module
## The constructor.
def __init__(self):
ModelAPI.ModelAPI_Feature.__init__(self)
- ## Shape that will be exported (the compound if there are several exported bodies)
- self.shape = None
- ## BRep representation of the exported shape (a stream that will be sent to GEOM and converted to GEOM object)
- self.brep = None
+ pass
@staticmethod
## Export kind. Static.
def getKind(self):
return ExportFeature.ID()
- ## This feature is action: has no property pannel and executes immideately.
+ ## This feature is action: has no property pannel and executes immediately.
def isAction(self):
return True
def initAttributes(self):
pass
- ## Exports all bodies
- def exportBodies(self):
- global ShapeIndex
- kResultBodyType = "Bodies"
- aPartSize = self.Part.size(kResultBodyType)
- if aPartSize == 0:
- EventsAPI.Events_InfoMessage("ExportFeature","No results in the active document").send()
+ ## Export the results, groups and fields via XAO
+ def exportViaXAO(self):
+ tmpXAOFile = getTmpFileName("xao")
+ self.tmpXAOFile = tmpXAOFile
+ #print "Export to %s"%tmpXAOFile
+ exportXAO = ExchangeAPI.exportToXAO(self.Part, tmpXAOFile, "automatic_shaper_export_to_XAO")
+ if not os.path.exists(tmpXAOFile) or os.stat(tmpXAOFile).st_size == 0:
+ exportXAO.feature().setError("Error in exportToXAO. No XAO file has been created.")
return
-
- anObjList = [self.Part.object(kResultBodyType, idx) for idx in xrange(aPartSize)]
- aShapesList = GeomAlgoAPI.ShapeList()
- aName = ""
- for idx, anObject in enumerate(anObjList):
- aResult = ModelAPI.modelAPI_Result(anObject)
- aBodyResult = ModelAPI.modelAPI_ResultBody(aResult)
- if not aBodyResult:
- continue
- aShape = aBodyResult.shape()
- if aShape is not None and not aShape.isNull():
- aShapesList.append(aShape)
- if len(aShapesList) == 1:
- aName = aBodyResult.data().name()
-
- # issue 1045: create compound if there are more than one shape
- if len(aShapesList) > 1:
- self.shape = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.compound(aShapesList)
- aName = "ShaperResults"
- elif len(aShapesList) == 1:
- self.shape = aShapesList[0]
-
- # so, only one shape is always in the result
- aDump = self.shape.getShapeStream()
- # Load shape to SALOME Geom
- aBrep = self.geompy.RestoreShape(aDump)
-
- # Make unique name
- aId = getObjectIndex(aName)
- if aId != 0:
- aName = aName + '_' + str(aId)
-
- self.geompy.addToStudy(aBrep, aName)
- self.brep = aBrep
-
- ## Exports all groups
- def exportGroups(self):
- # iterate all features to find groups
- aFeaturesNum = self.Part.size("Features")
- groupIndex = 0
- for anIndex in range(0, aFeaturesNum):
- aFeature = self.Part.object("Features", anIndex)
- aSelectionList = aFeature.data().selectionList("group_list")
- # if a group has been found
- if aSelectionList:
- aFeature = ModelAPI.objectToFeature(aFeature)
- if aFeature.firstResult() is not None:
- aName = aFeature.firstResult().data().name()
- groupIndex = groupIndex + 1
- self.createGroupFromList(aSelectionList, aName)
-
- ## Returns a type of the shape in the old GEOM representation
- def shapeType(self, shape):
- if shape.isVertex():
- return "VERTEX"
- elif shape.isEdge():
- return "EDGE"
- elif shape.isFace():
- return "FACE"
-
- return "SOLID"
-
- ## Creates a group by given list of selected objects and the name
- # @param theSelectionList: list of selected objects
- # @param theGroupName: name of the group to create
- def createGroupFromList(self, theSelectionList, theGroupName):
- # iterate on all selected entities of the group
- # and get the corresponding ID
- aSelectionNum = theSelectionList.size()
- Ids = []
- groupType = ""
- for aSelIndex in range(0, aSelectionNum):
- aSelection = theSelectionList.value(aSelIndex)
- # issue 1326: bodies that are already concealed did not exported, so groups should not be invalid
- aContext = ModelAPI.modelAPI_Result(aSelection.context())
- # chcking of concealment removed because of #1799, remark #13 "aContext.isConcealed()"
- if aContext is None or aContext.isDisabled():
- continue
-
- anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, aSelection.value())
- if anID == 0:
- #it may be a compound of objects if movement of the group to the end
- # splits the original element to several (issue 1146)
- anExp = GeomAPI.GeomAPI_ShapeExplorer(aSelection.value(), GeomAPI.GeomAPI_Shape.SHAPE)
- while anExp.more():
- anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, anExp.current())
- if anID != 0:
- Ids.append(anID)
- groupType = self.shapeType(anExp.current())
- anExp.next()
- else:
- Ids.append(anID)
- groupType = self.shapeType(aSelection.value())
-
- if len(Ids) <> 0:
- aGroup = self.geompy.CreateGroup(self.brep, self.geompy.ShapeType[groupType])
- self.geompy.UnionIDs(aGroup,Ids)
- self.geompy.addToStudyInFather(self.brep, aGroup, theGroupName)
-
- ## Exports all fields
- def exportFields(self):
- # iterate all features to find fields
- aFeaturesNum = self.Part.size("Features")
- fieldIndex = 0
- for anIndex in range(0, aFeaturesNum):
- aFeature = self.Part.object("Features", anIndex)
- aSelectionList = aFeature.data().selectionList("selected")
- # if a field has been found
- if aSelectionList:
- aFeature = ModelAPI.objectToFeature(aFeature)
- if aFeature.firstResult() is not None:
- aName = aFeature.firstResult().data().name()
- fieldIndex = fieldIndex + 1
- self.createFieldFromFeature(aFeature, aName)
-
- ## Returns a type of the shape type in the old GEOM representation
- def selectionDim(self, theSelectionType):
- selType=theSelectionType.lower() # more or less independed approach
- if selType== "vertex":
- return 0
- if selType== "edge":
- return 1
- if selType== "face":
- return 2
- if selType== "solid":
- return 3
- return -1
-
- ## Returns a type of the shape type in the GeomAPI_Shape representation
- def geomAPISelectionDim(self, theSelectionType):
- selType=theSelectionType.lower() # more or less independed approach
- if selType== "vertex":
- return GeomAPI.GeomAPI_Shape.VERTEX
- if selType== "edge":
- return GeomAPI.GeomAPI_Shape.EDGE
- if selType== "face":
- return GeomAPI.GeomAPI_Shape.FACE
- if selType== "solid":
- return GeomAPI.GeomAPI_Shape.SOLID
- return GeomAPI.GeomAPI_Shape.SHAPE
-
- ## Creates a field by the field feature and the name
- # @param theField: the field feature
- # @param theFieldName: name of the field to create
- def createFieldFromFeature(self, theField, theFieldName):
- # iterate on all selected entities of the field
- # and get the corresponding ID
- aTables = theField.tables("values")
- aSelection = theField.selectionList("selected")
-
- # set component names
- aComps = theField.stringArray("components_names")
- aCompNames = []
- aCompNum = aComps.size()
- for aCompIndex in range(0, aCompNum):
- aCompNames.append(aComps.value(aCompIndex))
-
- #if len(Ids) <> 0:
- aDim = self.selectionDim(aSelection.selectionType())
- aResField = self.geompy.CreateField(self.brep, theFieldName, aTables.type(), aDim, aCompNames)
- #self.geompy.UnionIDs(theField,Ids)
- self.geompy.addToStudyInFather(self.brep, aResField, theFieldName)
-
- # set default values to all not filled sub-shapes (fields in GEOM support only full set of subs)
- Ids={}
- anExp = GeomAPI.GeomAPI_ShapeExplorer(self.shape, self.geomAPISelectionDim(aSelection.selectionType()))
- while anExp.more():
- anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, anExp.current())
- if anID != 0:
- Ids[anID]=anExp.current()
- anExp.next()
-
- SelectedIds={}
- for aSelIndex in range(aSelection.size()):
- selShape = aSelection.value(aSelIndex).value()
- # searching for this shape in Ids
- for a in Ids.items():
- if (a[1].isSame(selShape)):
- SelectedIds[a[0]] = aSelIndex
-
- # values here are in the same order as in field
- listOfValues = Ids.items()
- listOfValues.sort()
- # set steps
- aStepsNum = aTables.tables()
- for aStepIndex in range(0, aStepsNum):
- aStamp = theField.intArray("stamps").value(aStepIndex)
- aValues = []
- for aValId in listOfValues:
- aRow = 0 # default value if not from selection
- if SelectedIds.has_key(aValId[0]): # take the value from the table
- aRow = SelectedIds[aValId[0]] + 1 # plus one to avoid default string
- aCols = aTables.columns()
- for aCol in range(0, aCols):
- aVal = aTables.valueStr(aRow, aCol, aStepIndex)
- if aTables.type() == 0: # bool
- if aVal == "True":
- aVal = True
- else:
- aVal = False
- elif aTables.type() == 1: # int
- aVal = int(aVal)
- elif aTables.type() == 2: # double
- aVal = float(aVal)
- aValues.append(aVal)
- aStep = aResField.addStep(aStepIndex + 1, aStamp, aValues)
- if aStep:
- self.geompy.addToStudyInFather( aResField, aStep, aStep.GetName() )
+ imported, shape, subShapes, groups, fields = self.geompy.ImportXAO(tmpXAOFile)
+ self.geompy.addToStudy( shape, shape.GetName() )
+ # add sub-shapes and groups to the object browser
+ for obj in subShapes + groups:
+ name = obj.GetName()
+ self.geompy.addToStudyInFather(shape, obj, name)
+ # add fields to the object browser
+ for field in fields:
+ name = field.GetName()
+ self.geompy.addToStudyInFather(shape, field, name)
+ # add steps to the object browser
+ steps = field.getSteps()
+ for i_step in steps:
+ step = field.getStep(i_step)
+ i_stamp = step.GetStamp()
+ step_name = "Step %i %i"%(i_step, i_stamp)
+ self.geompy.addToStudyInFather( field, step, step_name )
+ # Remove the temporary file
+ os.remove(tmpXAOFile)
+ pass
## Exports all shapes and groups into the GEOM module.
def execute(self):
salome.salome_init(0,1)
self.geompy = geomBuilder.New(salome.myStudy)
- # Export bodies and groups
- self.exportBodies()
- self.exportGroups()
- self.exportFields()
+ self.exportViaXAO()
+
pass
#include "ExchangeAPI_Export.h"
//--------------------------------------------------------------------------------------
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
#include <ModelHighAPI_Tools.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Services.h>
//--------------------------------------------------------------------------------------
-void exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
+
+ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+/// Constructor with values for XAO export.
+ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::string & theFilePath,
+ const std::string & theAuthor,
+ const std::string & theGeometryName)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+ fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
+ fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
+ fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
+ fillAttribute(theGeometryName,
+ theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
+ fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
+ execute();
+ apply(); // finish operation to make sure the export is done on the current state of the history
+}
+
+/// Constructor with values for export in other formats than XAO.
+ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::string & theFilePath,
+ const std::list<ModelHighAPI_Selection> & theSelectionList,
+ const std::string & theFileFormat)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+ fillAttribute("Regular", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
+ fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
+ fillAttribute(theSelectionList,
+ theFeature->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()));
+ fillAttribute(theFileFormat, theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
+ execute();
+ apply(); // finish operation to make sure the export is done on the current state of the history
+}
+
+ExchangeAPI_Export::~ExchangeAPI_Export()
+{
+}
+
+
+void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const
+{
+
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.";
+
+ std::string exportType = aBase->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID())->value();
+
+ if (exportType == "XAO") {
+ std::string tmpXAOFile =
+ aBase->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value();
+ theDumper << "exportToXAO(" << aDocName << ", '" << tmpXAOFile << "'" ;
+ std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
+ if (! theAuthor.empty())
+ theDumper << ", '" << theAuthor << "'";
+ std::string theGeometryName =
+ aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
+ if (! theGeometryName.empty())
+ theDumper << ", '" << theGeometryName << "'";
+ theDumper << ")" << std::endl;
+ }
+ else {
+ theDumper << "exportToFile(" << aDocName << ", " <<
+ aBase->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()) << ", " <<
+ aBase->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()) ;
+ std::string theFileFormat =
+ aBase->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID())->value();
+ if (! theFileFormat.empty())
+ theDumper << ", '" << theFileFormat << "'";
+ theDumper << ")" << std::endl;
+ }
+}
+
+ExportPtr exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
const std::string & theFilePath,
const std::list<ModelHighAPI_Selection> & theSelectionList,
const std::string & theFileFormat)
{
+ apply(); // finish previous operation to make sure all previous operations are done
std::shared_ptr<ModelAPI_Feature> aFeature =
thePart->addFeature(ExchangePlugin_ExportFeature::ID());
- fillAttribute("Regular", aFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
- fillAttribute(theFilePath, aFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
- fillAttribute(theSelectionList,
- aFeature->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()));
- fillAttribute(theFileFormat, aFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
- aFeature->execute();
+ return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectionList, theFileFormat));
}
-void exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
+ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
const std::string & theFilePath,
const std::string & theAuthor,
const std::string & theGeometryName)
{
+ apply(); // finish previous operation to make sure all previous operations are done
std::shared_ptr<ModelAPI_Feature> aFeature =
thePart->addFeature(ExchangePlugin_ExportFeature::ID());
- fillAttribute("XAO", aFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
- fillAttribute(theFilePath, aFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
- fillAttribute(theAuthor, aFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
- fillAttribute(theGeometryName,
- aFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
- fillAttribute("XAO", aFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
- aFeature->execute();
+ return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theAuthor, theGeometryName));
}
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
class ModelHighAPI_Selection;
//--------------------------------------------------------------------------------------
+
+
+/// \class ExchangeAPI_Export
+/// \ingroup CPPHighAPI
+/// \brief Interface for Export feature.
+class ExchangeAPI_Export: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ EXCHANGEAPI_EXPORT
+ explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values for XAO export.
+ EXCHANGEAPI_EXPORT
+ explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::string & theFilePath,
+ const std::string & theAuthor = std::string(),
+ const std::string & theGeometryName = std::string());
+
+ /// Constructor with values for export in other formats than XAO.
+ EXCHANGEAPI_EXPORT
+ explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::string & theFilePath,
+ const std::list<ModelHighAPI_Selection> & theSelectionList,
+ const std::string & theFileFormat = std::string());
+
+ /// Destructor.
+ EXCHANGEAPI_EXPORT
+ virtual ~ExchangeAPI_Export();
+
+ INTERFACE_7(ExchangePlugin_ExportFeature::ID(),
+ exportType, ExchangePlugin_ExportFeature::EXPORT_TYPE_ID(),
+ ModelAPI_AttributeString, /** ExportType */,
+ filePath, ExchangePlugin_ExportFeature::FILE_PATH_ID(),
+ ModelAPI_AttributeString, /** file path */,
+ xaoFilePath, ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID(),
+ ModelAPI_AttributeString, /** xao_file_path */,
+ fileFormat, ExchangePlugin_ExportFeature::FILE_FORMAT_ID(),
+ ModelAPI_AttributeString, /** file format */,
+ selectionList, ExchangePlugin_ExportFeature::SELECTION_LIST_ID(),
+ ModelAPI_AttributeString, /** selection list */,
+ xaoAuthor, ExchangePlugin_ExportFeature::XAO_AUTHOR_ID(),
+ ModelAPI_AttributeString, /** xao author */,
+ xaoGeometryName, ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID(),
+ ModelAPI_AttributeString, /** xao geometry name */)
+
+ /// Dump wrapped feature
+ EXCHANGEAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Export object
+typedef std::shared_ptr<ExchangeAPI_Export> ExportPtr;
+
/**\ingroup CPPHighAPI
* \brief Export to file
*/
EXCHANGEAPI_EXPORT
-void exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
+ExportPtr exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
const std::string & theFilePath,
const std::list<ModelHighAPI_Selection> & theSelectionList,
const std::string & theFileFormat = std::string());
* \brief Export XAO
*/
EXCHANGEAPI_EXPORT
-void exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
+ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
const std::string & theFilePath,
const std::string & theAuthor = std::string(),
const std::string & theGeometryName = std::string());
INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Exchange)
INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
-ADD_UNIT_TESTS(TestImport.py TestExport.py)
+ADD_UNIT_TESTS(TestImport.py
+ TestExport.py
+ Test2290.py)
SET(DATA_FILES
solid.brep
// make shape for export from all results
std::list<GeomShapePtr> aShapes;
+ std::list<ResultBodyPtr> aResults;
int aBodyCount = document()->size(ModelAPI_ResultBody::group());
for (int aBodyIndex = 0; aBodyIndex < aBodyCount; ++aBodyIndex) {
ResultBodyPtr aResultBody =
if (!aResultBody.get())
continue;
aShapes.push_back(aResultBody->shape());
+ aResults.push_back(aResultBody);
}
GeomShapePtr aShape = (aShapes.size() == 1)
? *aShapes.begin()
}
// geometry name
-
std::string aGeometryName = string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
+ if (aGeometryName.empty() && aBodyCount == 1) {
+ // get the name from the first result
+ ResultBodyPtr aResultBody = *aResults.begin();
+ aGeometryName = aResultBody->data()->name();
+ }
+
aXao.getGeometry()->setName(aGeometryName);
// groups
AttributeSelectionPtr aSelection = aSelectionList->value(aSelectionIndex);
// complex conversion of reference id to element index
- int aReferenceID = aSelection->Id();
+ // gives bad id in case the selection is done from python script
+ // => using GeomAlgoAPI_CompoundBuilder::id instead
+ // int aReferenceID_old = aSelection->Id();
+
+ int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
+
std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
int anElementID =
aXao.getGeometry()->getElementIndexByReference(aGroupDimension, aReferenceString);
AttributeSelectionPtr aSelection = aSelectionList->value(aRow - 1);
// complex conversion of reference id to element index
- int aReferenceID = aSelection->Id();
+ // gives bad id in case the selection is done from python script
+ // => using GeomAlgoAPI_CompoundBuilder::id instead
+ //int aReferenceID_old = aSelection->Id();
+
+ int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
+
std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
anElementID =
aXao.getGeometry()->getElementIndexByReference(aFieldDimension, aReferenceString);
/// Computes or recomputes the results
EXCHANGEPLUGIN_EXPORT virtual void execute();
- /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true.
- EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+ /// Reimplemented from ModelAPI_Feature::isMacro(). Returns false.
+ // Not a macro. Otherwise, the feature will be deleted after being executed
+ EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return false; }
/// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+ /// Do not put in history.
+ /// Since it is not a macro, it is not deleted, but we don't want to see it.
+ bool isInHistory() { return false; }
+
protected:
/// Performs export of the file
EXCHANGEPLUGIN_EXPORT void exportFile(const std::string& theFileName,
std::string ExchangePlugin_Tools::selectionType2xaoDimension(const std::string& theType)
{
- if (theType == "Vertices" || theType == "vertex")
+ if (theType == "Vertices" || theType == "vertex" || theType == "VERTEX")
return "vertex";
- else if (theType == "Edges" || theType == "edge")
+ else if (theType == "Edges" || theType == "edge" || theType == "EDGE")
return "edge";
- else if (theType == "Faces" || theType == "face")
+ else if (theType == "Faces" || theType == "face" || theType == "FACE")
return "face";
- else if (theType == "Solids" || theType == "solid")
+ else if (theType == "Solids" || theType == "solid" || theType == "SOLID")
return "solid";
- else if (theType == "Part" || theType == "part")
+ else if (theType == "Part" || theType == "part" || theType == "PART")
return "part";
return std::string();
<element index="1"/>
</group>
</groups>
- <fields count="0"/>
+ <fields count="1">
+ <field name="Field_1" type="double" dimension="face">
+ <components count="2">
+ <component column="0" name="temperatue"/>
+ <component column="1" name="porosity"/>
+ </components>
+ <steps count="1">
+ <step number="0" stamp="10">
+ <element index="0">
+ <value component="0">2</value>
+ <value component="1">5</value>
+ </element>
+ <element index="1">
+ <value component="0">3</value>
+ <value component="1">6</value>
+ </element>
+ <element index="2">
+ <value component="0">1</value>
+ <value component="1">4</value>
+ </element>
+ <element index="3">
+ <value component="0">1</value>
+ <value component="1">4</value>
+ </element>
+ <element index="4">
+ <value component="0">1</value>
+ <value component="1">4</value>
+ </element>
+ <element index="5">
+ <value component="0">1</value>
+ <value component="1">4</value>
+ </element>
+ </step>
+ </steps>
+ </field>
+ </fields>
</XAO>
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 5, 10, 10)
+Box_2 = model.addBox(Part_1_doc, 10, 50, 8)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Box_1_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Partition_1_1_3/Modified_Face_2_3"), model.selection("FACE", "Partition_1_1_1/Modified_Face_2_3")])
+model.do()
+# test export to XAO
+anExportFeature = Part_1_doc.addFeature("Export")
+anExportFeature.string("xao_file_path").setValue("Data/export2290.xao")
+anExportFeature.string("file_format").setValue("XAO")
+anExportFeature.string("ExportType").setValue("XAO")
+anExportFeature.string("xao_author").setValue("me")
+anExportFeature.string("xao_geometry_name").setValue("mygeom")
+model.end()
aSession.finishOperation()
# Check exported file
-# import filecmp
-# assert filecmp.cmp("Data/export.xao", "Data/export_ref.xao")
+ import filecmp
+ assert filecmp.cmp("Data/export.xao", "Data/export_ref.xao")
if __name__ == '__main__':
#=========================================================================
FeaturesAPI_Boolean.h
FeaturesAPI_Extrusion.h
FeaturesAPI_ExtrusionBoolean.h
+ FeaturesAPI_Fillet.h
FeaturesAPI_Intersection.h
FeaturesAPI_MultiRotation.h
FeaturesAPI_MultiTranslation.h
FeaturesAPI_Boolean.cpp
FeaturesAPI_Extrusion.cpp
FeaturesAPI_ExtrusionBoolean.cpp
+ FeaturesAPI_Fillet.cpp
FeaturesAPI_Intersection.cpp
FeaturesAPI_MultiRotation.cpp
FeaturesAPI_MultiTranslation.cpp
%shared_ptr(FeaturesAPI_ExtrusionBoolean)
%shared_ptr(FeaturesAPI_ExtrusionCut)
%shared_ptr(FeaturesAPI_ExtrusionFuse)
+%shared_ptr(FeaturesAPI_Fillet)
%shared_ptr(FeaturesAPI_Intersection)
%shared_ptr(FeaturesAPI_MultiRotation)
%shared_ptr(FeaturesAPI_MultiTranslation)
%include "FeaturesAPI_Boolean.h"
%include "FeaturesAPI_Extrusion.h"
%include "FeaturesAPI_ExtrusionBoolean.h"
+%include "FeaturesAPI_Fillet.h"
%include "FeaturesAPI_Intersection.h"
%include "FeaturesAPI_MultiRotation.h"
%include "FeaturesAPI_MultiTranslation.h"
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "FeaturesAPI_Fillet.h"
+
+#include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+////#include <ModelHighAPI_Reference.h>
+#include <ModelHighAPI_Tools.h>
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+ : ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius)
+ : ModelHighAPI_Interface(theFeature)
+{
+ if (initialize()) {
+ fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS(), mycreationMethod);
+ fillAttribute(theBaseObjects, mybaseObjects);
+ fillAttribute(theRadius, myradius);
+
+ execIfBaseNotEmpty();
+ }
+}
+
+FeaturesAPI_Fillet::FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius1,
+ const ModelHighAPI_Double& theRadius2)
+ : ModelHighAPI_Interface(theFeature)
+{
+ if (initialize()) {
+ fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS(), mycreationMethod);
+ fillAttribute(theBaseObjects, mybaseObjects);
+ fillAttribute(theRadius1, mystartRadius);
+ fillAttribute(theRadius2, myendRadius);
+
+ execIfBaseNotEmpty();
+ }
+}
+
+FeaturesAPI_Fillet::~FeaturesAPI_Fillet()
+{
+}
+
+//==================================================================================================
+void FeaturesAPI_Fillet::setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects)
+{
+ mybaseObjects->clear();
+ fillAttribute(theBaseObjects, mybaseObjects);
+
+ execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::setRadius(const ModelHighAPI_Double& theRadius)
+{
+ fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS(), mycreationMethod);
+ fillAttribute(theRadius, myradius);
+
+ execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::setRadius(const ModelHighAPI_Double& theRadius1,
+ const ModelHighAPI_Double& theRadius2)
+{
+ fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS(), mycreationMethod);
+ fillAttribute(theRadius1, mystartRadius);
+ fillAttribute(theRadius2, myendRadius);
+
+ execIfBaseNotEmpty();
+}
+
+void FeaturesAPI_Fillet::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ AttributeSelectionListPtr anAttrObjects =
+ aBase->selectionList(FeaturesPlugin_Fillet::OBJECT_LIST_ID());
+
+ theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrObjects;
+
+ std::string aCreationMethod = aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value();
+
+ if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS()) {
+ AttributeDoublePtr anAttrRadius = aBase->real(FeaturesPlugin_Fillet::RADIUS_ID());
+ theDumper << ", " << anAttrRadius;
+ } else if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS()) {
+ AttributeDoublePtr anAttrRadius1 = aBase->real(FeaturesPlugin_Fillet::START_RADIUS_ID());
+ AttributeDoublePtr anAttrRadius2 = aBase->real(FeaturesPlugin_Fillet::END_RADIUS_ID());
+ theDumper << ", " << anAttrRadius1 << ", " << anAttrRadius2;
+ }
+
+ theDumper << ")" << std::endl;
+}
+
+void FeaturesAPI_Fillet::execIfBaseNotEmpty()
+{
+ if (mybaseObjects->size() > 0)
+ execute();
+}
+
+
+//==================================================================================================
+
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
+ return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius));
+}
+
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius1,
+ const ModelHighAPI_Double& theRadius2)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
+ return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius1, theRadius2));
+}
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef FeaturesAPI_Fillet_H_
+#define FeaturesAPI_Fillet_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_Fillet.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Double;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_Fillet
+/// \ingroup CPPHighAPI
+/// \brief Interface for Fillet feature.
+class FeaturesAPI_Fillet: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius);
+
+ /// Constructor with values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_Fillet(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius1,
+ const ModelHighAPI_Double& theRadius2);
+
+ /// Destructor.
+ FEATURESAPI_EXPORT
+ virtual ~FeaturesAPI_Fillet();
+
+ INTERFACE_5(FeaturesPlugin_Fillet::ID(),
+ creationMethod, FeaturesPlugin_Fillet::CREATION_METHOD(),
+ ModelAPI_AttributeString,
+ /** Creation method */,
+ baseObjects, FeaturesPlugin_Fillet::OBJECT_LIST_ID(),
+ ModelAPI_AttributeSelectionList,
+ /** Base objects */,
+ radius, FeaturesPlugin_Fillet::RADIUS_ID(),
+ ModelAPI_AttributeDouble,
+ /** Value of the fixed radius fillet */,
+ startRadius, FeaturesPlugin_Fillet::START_RADIUS_ID(),
+ ModelAPI_AttributeDouble,
+ /** Start radius of the varying radius fillet */,
+ endRadius, FeaturesPlugin_Fillet::END_RADIUS_ID(),
+ ModelAPI_AttributeDouble,
+ /** End radius of the varying radius fillet */)
+
+ /// Modify base objects of the fillet.
+ FEATURESAPI_EXPORT
+ void setBase(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+ /// Modify fillet to have fixed radius
+ FEATURESAPI_EXPORT
+ void setRadius(const ModelHighAPI_Double& theRadius);
+
+ /// Modify fillet to have varying radius
+ FEATURESAPI_EXPORT
+ void setRadius(const ModelHighAPI_Double& theRadius1, const ModelHighAPI_Double& theRadius2);
+
+ /// Dump wrapped feature
+ FEATURESAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+ void execIfBaseNotEmpty();
+};
+
+/// Pointer on Fillet object.
+typedef std::shared_ptr<FeaturesAPI_Fillet> FilletPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Fillet feature.
+FEATURESAPI_EXPORT
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius);
+
+/// \ingroup CPPHighAPI
+/// \brief Create Fillet feature.
+FEATURESAPI_EXPORT
+FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const std::list<ModelHighAPI_Selection>& theBaseObjects,
+ const ModelHighAPI_Double& theRadius1,
+ const ModelHighAPI_Double& theRadius2);
+
+#endif // FeaturesAPI_Fillet_H_
#include "FeaturesAPI_Boolean.h"
#include "FeaturesAPI_Extrusion.h"
#include "FeaturesAPI_ExtrusionBoolean.h"
+ #include "FeaturesAPI_Fillet.h"
#include "FeaturesAPI_Intersection.h"
#include "FeaturesAPI_MultiRotation.h"
#include "FeaturesAPI_MultiTranslation.h"
FeaturesPlugin_Scale.h
FeaturesPlugin_MultiTranslation.h
FeaturesPlugin_MultiRotation.h
+ FeaturesPlugin_Fillet.h
)
SET(PROJECT_SOURCES
FeaturesPlugin_Scale.cpp
FeaturesPlugin_MultiTranslation.cpp
FeaturesPlugin_MultiRotation.cpp
+ FeaturesPlugin_Fillet.cpp
)
SET(XML_RESOURCES
scale_widget.xml
multitranslation_widget.xml
multirotation_widget.xml
+ fillet_widget.xml
)
SET(TEXT_RESOURCES
TestPipe.py
TestRecover.py
TestRecover1798.py
+ TestFillEdgeVertex.py
+ TestFillEdgeEdge.py
+ TestFillEdgeEdgeIntersected.py
+ TestFillEdgeWire.py
+ TestFillEdgeFace.py
+ TestFillEdgeShell.py
+ TestFillEdgeSolid.py
+ TestFillEdgeSolidIntersected.py
+ TestFillWireVertex.py
+ TestFillWireEdge.py
+ TestFillWireWire.py
+ TestFillWireFace.py
+ TestFillWireShell.py
+ TestFillWireSolid.py
+ TestFillFaceVertex.py
+ TestFillFaceEdge.py
+ TestFillFaceEdgeInside.py
+ TestFillFaceEdgePerpendicular.py
+ TestFillFaceWire.py
+ TestFillFaceFace.py
+ TestFillFaceShell.py
+ TestFillFaceSolid.py
+ TestFillCompFaceSolid.py
+ TestFillShellVertex.py
+ TestFillShellEdge.py
+ TestFillShellConstrPlane.py
+ TestFillShellWire.py
+ TestFillShellFace.py
+ TestFillShellShell.py
+ TestFillShellSolid.py
+ TestFillSolid2ConstructionPlanes.py
+ TestFillSolidEdge.py
+ TestFillSolidFace.py
+ TestFillSolidCompFace.py
+ TestFillSolidShell.py
+ TestFillSolidCompShell.py
+ TestPartition2Faces.py
+ TestPartition2Solids.py
+ TestPartition2Wires.py
+ TestPartitionBox4Planes.py
+ TestPartitionEdgeSolid.py
+ TestPartitionFace2Solid.py
+# TestPartitionFaceSolid.py
+ TestPartitionFaceWire.py
+ TestPartitionInclinedFaceSolid.py
+ TestPartitionWireFaceSolid.py
+ TestUnion4CurvedFaces.py
+ TestUnion4Faces.py
Test1922.py
Test1942.py
Test1915.py
Test2255.py
Test2289.py
Test2304.py
+ Test2377.py
)
aCompSolidsObjects[aContextShape].push_back(anObject);
}
} else {
- if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
- anObject->shapeType() == GeomAPI_Shape::FACE) {
+ if(aType != BOOL_FILL
+ && (anObject->shapeType() == GeomAPI_Shape::EDGE
+ || anObject->shapeType() == GeomAPI_Shape::FACE))
+ {
anEdgesAndFaces.push_back(anObject);
- } else {
+ }
+ else
+ {
anObjects.push_back(anObject);
}
}
// It could be a construction plane.
ResultPtr aContext = aToolAttr->context();
aPlanes.push_back(aToolAttr->context()->shape());
- } else if(aTool->shapeType() == GeomAPI_Shape::EDGE ||
- aTool->shapeType() == GeomAPI_Shape::FACE) {
+ }
+ else if(aType != BOOL_FILL
+ && (aTool->shapeType() == GeomAPI_Shape::EDGE
+ || aTool->shapeType() == GeomAPI_Shape::FACE))
+ {
anEdgesAndFaces.push_back(aTool);
} else {
aTools.push_back(aTool);
aMakeShapeList.appendAlgo(aBoolAlgo);
- if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) {
+ if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27
+ || (aType != BOOL_CUT && aType != BOOL_COMMON))
+ {
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
aResultShape = aFillerAlgo->shape();
}
- if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) {
+ if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27
+ || (aType != BOOL_CUT && aType != BOOL_COMMON))
+ {
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
theResultBody->store(theResultShape, false);
} else {
const int aModifyTag = 1;
- const int aDeletedTag = 2;
- /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
- const int aSubsolidsTag = 3;
- const int anEdgesAndFacesTag = 10000;
+ const int aModifyEdgeTag = 2;
+ const int aModifyFaceTag = 3;
+ const int aDeletedTag = 4;
+ /// sub solids will be placed at labels 5, 6, etc. if result is compound of solids
+ const int aSubsolidsTag = 5;
theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
const std::string aModEName = "Modified_Edge";
const std::string aModFName = "Modified_Face";
+ theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::EDGE,
+ aModifyEdgeTag, aModEName, theMapOfShapes, false, theIsStoreAsGenerated, true);
theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
- aModifyTag, aModName, theMapOfShapes, false, theIsStoreAsGenerated, true);
+ aModifyFaceTag, aModFName, theMapOfShapes, false, theIsStoreAsGenerated, true);
theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
GeomAPI_Shape::FACE, aDeletedTag);
std::string aName;
for(ListOfShape::const_iterator
anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
- if((*anIter)->shapeType() == GeomAPI_Shape::EDGE) {
- aTag = anEdgesAndFacesTag;
- aName = aModEName;
- }
- else if((*anIter)->shapeType() == GeomAPI_Shape::FACE) {
- aTag = anEdgesAndFacesTag;
+ if((*anIter)->shapeType() <= GeomAPI_Shape::FACE) {
+ aTag = aModifyFaceTag;
aName = aModFName;
} else {
- aTag = aModifyTag;
- aName = aModName;
+ aTag = aModifyEdgeTag;
+ aName = aModEName;
}
theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "FeaturesPlugin_Fillet.h"
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAlgoAPI_Fillet.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+
+#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+
+// Obtain all sub-shapes from the shape and append them to the list
+static void collectSubs(const GeomShapePtr& theShape,
+ ListOfShape& theSubs,
+ const GeomAPI_Shape::ShapeType theShapeType)
+{
+ GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
+ for (; anExp.more(); anExp.next()) {
+ GeomShapePtr aShape = anExp.current();
+ // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
+ aShape->setOrientation(GeomAPI_Shape::FORWARD);
+ theSubs.push_back(aShape);
+ }
+}
+
+// Extract edges from the list
+static ListOfShape selectEdges(const ListOfShape& theShapes)
+{
+ ListOfShape anEdges;
+ for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
+ if ((*anIt)->isEdge())
+ anEdges.push_back(*anIt);
+ return anEdges;
+}
+
+// If theShape is a compound of single shape, return it
+static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
+{
+ GeomShapePtr aShape = theShape;
+ if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+ int aSubResultsNb = 0;
+ GeomAPI_ShapeIterator anIt(aShape);
+ for(; anIt.more(); anIt.next())
+ ++aSubResultsNb;
+
+ if(aSubResultsNb == 1) {
+ anIt.init(aShape);
+ aShape = anIt.current();
+ }
+ }
+ return aShape;
+}
+
+
+FeaturesPlugin_Fillet::FeaturesPlugin_Fillet()
+{
+}
+
+void FeaturesPlugin_Fillet::initAttributes()
+{
+ data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+ data()->addAttribute(START_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(END_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_RADIUS_ID());
+}
+
+
+void FeaturesPlugin_Fillet::execute()
+{
+ AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
+ if (!aCreationMethod)
+ return;
+
+ GeomAPI_DataMapOfShapeMapOfShapes aSolidsAndSubs;
+
+ // getting objects and sort them accroding to parent solids
+ AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
+ for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
+ AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+ GeomShapePtr anObject = anObjectAttr->value();
+ if (!anObject)
+ return;
+
+ ResultPtr aContext = anObjectAttr->context();
+ ResultCompSolidPtr aCtxOwner = ModelAPI_Tools::compSolidOwner(aContext);
+ GeomShapePtr aParent = aCtxOwner ? aCtxOwner->shape() : aContext->shape();
+ if (!aParent)
+ return;
+
+ ListOfShape anEdgesAndVertices;
+ collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
+ collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
+ for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
+ aEIt != anEdgesAndVertices.end(); ++aEIt)
+ aSolidsAndSubs.add(aParent, *aEIt);
+ }
+
+ bool isFixedRadius = true;
+ double aRadius1 = 0.0, aRadius2 = 0.0;
+ if (aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS())
+ aRadius1 = real(RADIUS_ID())->value();
+ else {
+ aRadius1 = real(START_RADIUS_ID())->value();
+ aRadius2 = real(END_RADIUS_ID())->value();
+ isFixedRadius = false;
+ }
+
+ // Perform fillet operation
+ GeomAlgoAPI_MakeShapeList aMakeShapeList;
+ std::shared_ptr<GeomAlgoAPI_Fillet> aFilletBuilder;
+ int aResultIndex = 0;
+
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator anIt = aSolidsAndSubs.begin();
+ for (; anIt != aSolidsAndSubs.end(); ++anIt) {
+ GeomShapePtr aSolid = anIt.first();
+ ListOfShape aFilletEdgesAndVertices = anIt.second();
+
+ ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
+ if (isFixedRadius)
+ aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1));
+ else
+ aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1, aRadius2));
+ if (isFailed(aFilletBuilder))
+ return;
+
+ GeomShapePtr aResult = unwrapCompound(aFilletBuilder->shape());
+ std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+ document()->createBody(data(), aResultIndex);
+
+ loadNamingDS(aResultBody, aSolid, aFilletEdgesAndVertices, aResult, aFilletBuilder);
+ setResult(aResultBody, aResultIndex);
+ aResultIndex++;
+ }
+ removeResults(aResultIndex);
+}
+
+bool FeaturesPlugin_Fillet::isFailed(
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm)
+{
+ if (!theAlgorithm->isDone()) {
+ static const std::string aFeatureError = "Error: fillet algorithm failed.";
+ setError(aFeatureError);
+ return true;
+ }
+ if (theAlgorithm->shape()->isNull()) {
+ static const std::string aShapeError = "Error: Resulting shape of fillet is Null.";
+ setError(aShapeError);
+ return true;
+ }
+ if (!theAlgorithm->isValid()) {
+ std::string aFeatureError = "Error: Resulting shape of fillet is not valid.";
+ setError(aFeatureError);
+ return true;
+ }
+ return false;
+}
+
+void FeaturesPlugin_Fillet::loadNamingDS(
+ std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+ const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+ const ListOfShape& theFilletShapes,
+ const std::shared_ptr<GeomAPI_Shape> theResultShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
+{
+ //load result
+ if(theBaseShape->isEqual(theResultShape)) {
+ theResultBody->store(theResultShape, false);
+ return;
+ }
+
+ std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfShapes = theMakeShape->mapOfSubShapes();
+
+ const int aDeletedTag = 1;
+ const int aModifyTag = 2;
+ const int aGeneratedTag = 3;
+ /// sub solids will be placed at labels 4, 5, etc. if result is compound of solids
+ const int aSubsolidsTag = 4;
+
+ theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
+ theResultBody->storeGenerated(theBaseShape, theResultShape);
+
+ const std::string aModFaceName = "Modified_Face";
+ const std::string aFilletFaceName = "Fillet_Face";
+
+ // Store modified faces
+ theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), theBaseShape,
+ GeomAPI_Shape::FACE, aModifyTag, aModFaceName, *aMapOfShapes);
+
+ // Store new faces generated from edges and vertices
+ theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape,
+ GeomAPI_Shape::EDGE, aGeneratedTag, aFilletFaceName, *aMapOfShapes);
+ theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape,
+ GeomAPI_Shape::VERTEX, aGeneratedTag, aFilletFaceName, *aMapOfShapes);
+
+ // Deleted shapes
+ theResultBody->loadDeletedShapes(theMakeShape.get(), theBaseShape,
+ GeomAPI_Shape::EDGE, aDeletedTag);
+ theResultBody->loadDeletedShapes(theMakeShape.get(), theBaseShape,
+ GeomAPI_Shape::FACE, aDeletedTag);
+}
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef FeaturesPlugin_Fillet_H_
+#define FeaturesPlugin_Fillet_H_
+
+#include "FeaturesPlugin.h"
+
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+class GeomAPI_DataMapOfShapeMapOfShapes;
+
+/// \class FeaturesPlugin_Fillet
+/// \ingroup Plugins
+/// \brief Feature for applying the Fillet operations on Solids.
+/// Supports fixed radius fillet and varying 2-radius fillet.
+class FeaturesPlugin_Fillet : public ModelAPI_Feature
+{
+public:
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("Fillet");
+ return MY_ID;
+ }
+
+ /// \return the kind of a feature.
+ FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = FeaturesPlugin_Fillet::ID();
+ return MY_KIND;
+ }
+
+ inline static const std::string& CREATION_METHOD()
+ {
+ static std::string MY_CREATION_METHOD("creation_method");
+ return MY_CREATION_METHOD;
+ }
+
+ inline static const std::string CREATION_METHOD_SINGLE_RADIUS()
+ {
+ static std::string MY_SINGLE_RADIUS("fixed_radius");
+ return MY_SINGLE_RADIUS;
+ }
+
+ inline static const std::string CREATION_METHOD_VARYING_RADIUS()
+ {
+ static std::string MY_VARYING_RADIUS("variable_radius");
+ return MY_VARYING_RADIUS;
+ }
+
+ /// Attribute name of main objects.
+ inline static const std::string& OBJECT_LIST_ID()
+ {
+ static const std::string MY_OBJECT_LIST_ID("main_objects");
+ return MY_OBJECT_LIST_ID;
+ }
+
+ /// Attribute name of start radius.
+ inline static const std::string& START_RADIUS_ID()
+ {
+ static const std::string MY_START_RADIUS_ID("radius1");
+ return MY_START_RADIUS_ID;
+ }
+
+ /// Attribute name of end radius.
+ inline static const std::string& END_RADIUS_ID()
+ {
+ static const std::string MY_END_RADIUS_ID("radius2");
+ return MY_END_RADIUS_ID;
+ }
+
+ /// Attribute name of a radius for fillet with fixed radius.
+ inline static const std::string& RADIUS_ID()
+ {
+ return START_RADIUS_ID();
+ }
+
+ /// 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_Fillet();
+
+private:
+ /// Check algorithm is finished correctly and store error otherwise
+ bool isFailed(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
+
+ /// Load Naming data structure of the feature to the document
+ void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+ const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+ const ListOfShape& theFilletShapes,
+ const std::shared_ptr<GeomAPI_Shape> theResultShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+};
+
+#endif
/// Multi-rotation kind.
inline static const std::string& ID()
{
- static const std::string MY_MULTIROTATION_ID("MultiRotation");
+ static const std::string MY_MULTIROTATION_ID("AngularCopy");
return MY_MULTIROTATION_ID;
}
/// Multi-translation kind.
inline static const std::string& ID()
{
- static const std::string MY_MULTITRANSLATION_ID("MultiTranslation");
+ static const std::string MY_MULTITRANSLATION_ID("LinearCopy");
return MY_MULTITRANSLATION_ID;
}
#include <FeaturesPlugin_Extrusion.h>
#include <FeaturesPlugin_ExtrusionCut.h>
#include <FeaturesPlugin_ExtrusionFuse.h>
+#include <FeaturesPlugin_Fillet.h>
#include <FeaturesPlugin_Intersection.h>
#include <FeaturesPlugin_MultiRotation.h>
#include <FeaturesPlugin_MultiTranslation.h>
new FeaturesPlugin_ValidatorUnionArguments);
aFactory->registerValidator("FeaturesPlugin_ValidatorConcealedResult",
new FeaturesPlugin_ValidatorConcealedResult);
+ aFactory->registerValidator("FeaturesPlugin_ValidatorFilletSelection",
+ new FeaturesPlugin_ValidatorFilletSelection);
// register this plugin
ModelAPI_Session::get()->registerPlugin(this);
return FeaturePtr(new FeaturesPlugin_MultiTranslation);
} else if (theFeatureID == FeaturesPlugin_MultiRotation::ID()) {
return FeaturePtr(new FeaturesPlugin_MultiRotation);
+ } else if (theFeatureID == FeaturesPlugin_Fillet::ID()) {
+ return FeaturePtr(new FeaturesPlugin_Fillet);
}
// feature of such kind is not found
aMakeShapeList.appendAlgo(aFillerAlgo);
aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
}
+ // workaround: make copy to name edges correctly
// Store result and naming.
const int aModifyEdgeTag = 1;
const int aDeletedTag = 3;
/// sub solids will be placed at labels 4, 5 etc. if result is compound of solids
const int aSubsolidsTag = 4;
- const std::string aModName = "Modified";
+ const std::string aModEName = "Modified_Edge";
+ const std::string aModFName = "Modified_Face";
std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
aResultBody->storeModified(anObjects.front(), aShape, aSubsolidsTag);
for(ListOfShape::const_iterator anIter = anObjects.begin(); anIter != anObjects.end(); ++anIter) {
aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::EDGE,
- aModifyEdgeTag, aModName, aMapOfShapes);
+ aModifyEdgeTag, aModEName, aMapOfShapes,
+ true, false, true);
aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE,
- aModifyFaceTag, aModName, aMapOfShapes);
- aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
+ aModifyFaceTag, aModFName, aMapOfShapes,
+ true, false, true);
+ //aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
}
setResult(aResultBody);
return false;
}
- int aShapeType = aShape->shapeType();
+ GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
+ std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
- // Fuse operation. Allow to select edges, faces and solids.
- if(aShapeType != GeomAPI_Shape::EDGE &&
- aShapeType != GeomAPI_Shape::FACE &&
- aShapeType != GeomAPI_Shape::SOLID &&
- aShapeType != GeomAPI_Shape::COMPSOLID &&
- aShapeType != GeomAPI_Shape::COMPOUND) {
- theError = "Error: Selected shape has the wrong type.";
- return false;
- }
+ anAllowedTypes.insert(GeomAPI_Shape::EDGE);
+ anAllowedTypes.insert(GeomAPI_Shape::FACE);
+ anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
} else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL) {
- if(aShapeType != GeomAPI_Shape::FACE &&
- aShapeType != GeomAPI_Shape::SOLID &&
- aShapeType != GeomAPI_Shape::COMPSOLID &&
- aShapeType != GeomAPI_Shape::COMPOUND) {
- theError = "Error: Selected shape has the wrong type.";
- return false;
- }
+ anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
+ anAllowedTypes.insert(GeomAPI_Shape::EDGE);
+ anAllowedTypes.insert(GeomAPI_Shape::WIRE);
+ anAllowedTypes.insert(GeomAPI_Shape::FACE);
+ anAllowedTypes.insert(GeomAPI_Shape::SHELL);
+ anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
} else {
- if(aShapeType != GeomAPI_Shape::SOLID &&
- aShapeType != GeomAPI_Shape::COMPSOLID &&
- aShapeType != GeomAPI_Shape::COMPOUND) {
- theError = "Error: Selected shape has the wrong type.";
- return false;
- }
+ anAllowedTypes.insert(GeomAPI_Shape::SOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
+ anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
+ }
+
+ if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
+ || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
+ theError = "Error: Selected shape has the wrong type.";
+ return false;
+ }
+
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!anAttrSelectionList.get()) {
+ theError =
+ "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
+ return false;
+ }
+
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ // Check all selected entities are sub-shapes of single solid
+ GeomShapePtr aBaseSolid;
+ for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+ if(!anAttrSelection.get()) {
+ theError = "Error: Empty attribute selection.";
+ return false;
+ }
+ ResultPtr aContext = anAttrSelection->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty selection context.";
+ return false;
+ }
+
+ ResultCompSolidPtr aContextOwner = ModelAPI_Tools::compSolidOwner(aContext);
+ GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
+
+ if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
+ anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
+ theError = "Error: Not all selected shapes are sub-shapes of solids";
+ return false;
+ }
+
+ if (!aBaseSolid)
+ aBaseSolid = anOwner;
+ else if (!aBaseSolid->isEqual(anOwner)) {
+ theError = "Error: Sub-shapes of different solids have been selected.";
+ return false;
}
}
bool isSameFound = false;
AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
ResultPtr aContext = anAttrSelectionInList->context();
+ if (!aContext.get()) {
+ theError = "Error: selection is invalid.";
+ return false;
+ }
ResultConstructionPtr aConstruction =
std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
Events_InfoMessage& theError) const;
};
+/// \class FeaturesPlugin_ValidatorFilletSelection
+/// \ingroup Validators
+/// \brief Validates selection for fillet operation.
+class FeaturesPlugin_ValidatorFilletSelection: public ModelAPI_AttributeValidator
+{
+public:
+ /// \return True if the attribute is valid. It checks whether the selection
+ /// is acceptable for boolean operation.
+ /// \param[in] theAttribute an attribute to check.
+ /// \param[in] theArguments a filter parameters.
+ /// \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
/// \class FeaturesPlugin_ValidatorPartitionSelection
/// \ingroup Validators
/// \brief Validates selection for partition.
model.do()
Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_6s-SketchLine_5e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_7"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_5s-SketchLine_4e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_11"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_2e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_10"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_8"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_9"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_2s-SketchLine_1e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_13"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_6e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_14"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_2"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_6"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_1"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_4"), model.selection("VERTEX", "Sketch_1/Vertex-SketchPoint_5")])
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("VERTEX", "Vertex_1_1"), model.selection("VERTEX", "Vertex_1_2"), model.selection("VERTEX", "Vertex_1_3"), model.selection("VERTEX", "Vertex_1_4"), model.selection("VERTEX", "Vertex_1_5"), model.selection("VERTEX", "Vertex_1_6"), model.selection("VERTEX", "Vertex_1_7"), model.selection("VERTEX", "Vertex_1_8"), model.selection("VERTEX", "Vertex_1_9"), model.selection("VERTEX", "Vertex_1_10"), model.selection("VERTEX", "Vertex_1_11"), model.selection("VERTEX", "Vertex_1_12"), model.selection("VERTEX", "Vertex_1_13"), model.selection("VERTEX", "Vertex_1_14"), model.selection("VERTEX", "Vertex_1_15"), model.selection("VERTEX", "Vertex_1_16"), model.selection("VERTEX", "Vertex_1_17"), model.selection("VERTEX", "Vertex_1_18")], model.selection("EDGE", "PartSet/OZ"), 100, 0)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Vertex_1_12/To_Vertex_1"), model.selection("VERTEX", "Vertex_1_13/To_Vertex_1"), model.selection("VERTEX", "Vertex_1_3/To_Vertex_1"))
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_1_12/To_Vertex_1"), model.selection("VERTEX", "Extrusion_1_13/To_Vertex_1"), model.selection("VERTEX", "Extrusion_1_3/To_Vertex_1"))
Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchLine_7 = Sketch_2.addLine(-717.0963364993213, -45.06817090071282, -717.0963364993213, -180.9380775505473)
-SketchPoint_13 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_12/To_Vertex_1"))
+SketchPoint_13 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_12/To_Vertex_1"))
SketchPoint_13.setName("SketchPoint_15")
SketchPoint_13.result().setName("SketchPoint_15")
SketchConstraintCoincidence_19 = Sketch_2.setCoincident(SketchLine_7.startPoint(), SketchPoint_13.result())
-SketchPoint_14 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_1/To_Vertex_1"))
+SketchPoint_14 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/To_Vertex_1"))
SketchPoint_14.setName("SketchPoint_16")
SketchPoint_14.result().setName("SketchPoint_16")
SketchConstraintCoincidence_20 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchPoint_14.result())
SketchLine_8 = Sketch_2.addLine(-717.0963364993213, -180.9380775505473, -102.0809741405142, -180.9380775505473)
SketchConstraintCoincidence_21 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
-SketchPoint_15 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_3/To_Vertex_1"))
+SketchPoint_15 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_3/To_Vertex_1"))
SketchPoint_15.setName("SketchPoint_17")
SketchPoint_15.result().setName("SketchPoint_17")
SketchConstraintCoincidence_22 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchPoint_15.result())
SketchLine_9 = Sketch_2.addLine(-102.0809741405142, -180.9380775505473, -102.0809741405142, 193.0685819822336)
SketchConstraintCoincidence_23 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
-SketchPoint_16 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_10/To_Vertex_1"))
+SketchPoint_16 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_10/To_Vertex_1"))
SketchPoint_16.setName("SketchPoint_18")
SketchPoint_16.result().setName("SketchPoint_18")
SketchConstraintCoincidence_24 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchPoint_16.result())
SketchLine_10 = Sketch_2.addLine(-102.0809741405142, 193.0685819822336, -254.8675173043772, 193.0685819822336)
SketchConstraintCoincidence_25 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
-SketchPoint_17 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_5/To_Vertex_1"))
+SketchPoint_17 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_5/To_Vertex_1"))
SketchPoint_17.setName("SketchPoint_19")
SketchPoint_17.result().setName("SketchPoint_19")
SketchConstraintCoincidence_26 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchPoint_17.result())
SketchLine_11 = Sketch_2.addLine(-254.8675173043772, 193.0685819822336, -254.8675173043772, -45.06817090071281)
SketchConstraintCoincidence_27 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
-SketchPoint_18 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_9/To_Vertex_1"))
+SketchPoint_18 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_9/To_Vertex_1"))
SketchPoint_18.setName("SketchPoint_20")
SketchPoint_18.result().setName("SketchPoint_20")
SketchConstraintCoincidence_28 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchPoint_18.result())
SketchConstraintCoincidence_31 = Sketch_2.setCoincident(SketchPoint_13.coordinates(), SketchLine_12.endPoint())
SketchLine_13 = Sketch_2.addLine(-599.2405881202537, -45.06817090071282, -584.124830393487, -180.9380775505472)
SketchConstraintCoincidence_32 = Sketch_2.setCoincident(SketchLine_13.startPoint(), SketchLine_12.result())
-SketchPoint_19 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_13/To_Vertex_1"))
+SketchPoint_19 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_13/To_Vertex_1"))
SketchPoint_19.setName("SketchPoint_21")
SketchPoint_19.result().setName("SketchPoint_21")
SketchConstraintCoincidence_33 = Sketch_2.setCoincident(SketchLine_13.endPoint(), SketchPoint_19.result())
SketchLine_14 = Sketch_2.addLine(-356.1736770691994, -45.06817090071282, -342.6051560379917, -180.9380775505472)
-SketchPoint_20 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_15/To_Vertex_1"))
+SketchPoint_20 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_15/To_Vertex_1"))
SketchPoint_20.setName("SketchPoint_22")
SketchPoint_20.result().setName("SketchPoint_22")
SketchConstraintCoincidence_34 = Sketch_2.setCoincident(SketchLine_14.startPoint(), SketchPoint_20.result())
-SketchPoint_21 = Sketch_2.addPoint(model.selection("VERTEX", "Vertex_1_11/To_Vertex_1"))
+SketchPoint_21 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_11/To_Vertex_1"))
SketchPoint_21.setName("SketchPoint_23")
SketchPoint_21.result().setName("SketchPoint_23")
SketchConstraintCoincidence_35 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchPoint_21.result())
Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_8f-SketchLine_12f-SketchLine_13f-SketchLine_14r")])
Face_3 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_8f-SketchLine_9f-SketchLine_12f-SketchLine_14f-SketchLine_15r")])
Face_4 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_9f-SketchLine_10f-SketchLine_11f-SketchLine_15f")])
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("EDGE", "Vertex_1_1"), model.selection("EDGE", "Vertex_1_2"), model.selection("EDGE", "Vertex_1_3"), model.selection("EDGE", "Vertex_1_4"), model.selection("EDGE", "Vertex_1_5"), model.selection("EDGE", "Vertex_1_6"), model.selection("EDGE", "Vertex_1_7"), model.selection("EDGE", "Vertex_1_8"), model.selection("EDGE", "Vertex_1_9"), model.selection("EDGE", "Vertex_1_10"), model.selection("EDGE", "Vertex_1_11"), model.selection("EDGE", "Vertex_1_12"), model.selection("EDGE", "Vertex_1_13"), model.selection("EDGE", "Vertex_1_14"), model.selection("EDGE", "Vertex_1_15"), model.selection("EDGE", "Vertex_1_16"), model.selection("EDGE", "Vertex_1_17"), model.selection("EDGE", "Vertex_1_18"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_4_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("EDGE", "Extrusion_1_1"), model.selection("EDGE", "Extrusion_1_2"), model.selection("EDGE", "Extrusion_1_3"), model.selection("EDGE", "Extrusion_1_4"), model.selection("EDGE", "Extrusion_1_5"), model.selection("EDGE", "Extrusion_1_6"), model.selection("EDGE", "Extrusion_1_7"), model.selection("EDGE", "Extrusion_1_8"), model.selection("EDGE", "Extrusion_1_9"), model.selection("EDGE", "Extrusion_1_10"), model.selection("EDGE", "Extrusion_1_11"), model.selection("EDGE", "Extrusion_1_12"), model.selection("EDGE", "Extrusion_1_13"), model.selection("EDGE", "Extrusion_1_14"), model.selection("EDGE", "Extrusion_1_15"), model.selection("EDGE", "Extrusion_1_16"), model.selection("EDGE", "Extrusion_1_17"), model.selection("EDGE", "Extrusion_1_18"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_4_1")])
model.end()
PartitionFeature = Partition_1.feature()
assert(len(PartitionFeature.results()) == 1)
Plane_5 = model.addPlane(Part_1_doc, model.selection("EDGE", "PartSet/Axis_4"), model.selection("VERTEX", "PartSet/Point_2"), True)
Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2")])
Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Recover_1_1")], [model.selection("FACE", "Face_1_1")])
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Recover_1_1/Modified_Vertex_2_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_2"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_6_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_4_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_3"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_1_1"), model.selection("VERTEX", "Recover_1_1/Generated_Vertex_4"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_3_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_7_1"), model.selection("VERTEX", "Recover_1_1/Modified_Vertex_5_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_2_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_2"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_6_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_4_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_3"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_1_1"), model.selection("VERTEX", "Intersection_1_1/Generated_Vertex_4"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_3_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_7_1"), model.selection("VERTEX", "Intersection_1_1/Modified_Vertex_5_1")])
Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Intersection_1_1_7"), model.selection("EDGE", "Intersection_1_1_6"), model.selection("EDGE", "Intersection_1_1_3"), model.selection("EDGE", "Intersection_1_1_11"), model.selection("EDGE", "Intersection_1_1_5"), model.selection("EDGE", "Intersection_1_1_1"), model.selection("EDGE", "Intersection_1_1_4"), model.selection("EDGE", "Intersection_1_1_2"), model.selection("EDGE", "Intersection_1_1_10"), model.selection("EDGE", "Intersection_1_1_9"), model.selection("EDGE", "Intersection_1_1_8")])
model.end()
model.do()
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f")], model.selection(), 10, 110)
Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Rotation_1 = model.addRotation(Part_1_doc, [model.selection("COMPOUND", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), 45)
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("COMPOUND", "Intersection_1_1")], model.selection("EDGE", "PartSet/OZ"), 45)
model.end()
assert(model.checkPythonDump())
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_5r")], model.selection(), 100, 0)
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f")], model.selection(), 100, 0)
Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")])
-Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), 50)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Translated_Face_24"), model.selection("FACE", "Extrusion_1_1/Translated_Face_13"), model.selection("FACE", "Extrusion_1_1/Translated_Face_16"), model.selection("FACE", "Extrusion_1_1/Translated_Face_12"), model.selection("FACE", "Extrusion_1_1/Translated_Face_9"), model.selection("FACE", "Extrusion_1_1/Translated_Face_10"), model.selection("FACE", "Extrusion_1_1/Translated_Face_11"), model.selection("FACE", "Extrusion_1_1/Translated_Face_25"), model.selection("FACE", "Extrusion_1_1/Translated_Face_20"), model.selection("FACE", "Extrusion_1_1/Translated_Face_19"), model.selection("FACE", "Extrusion_1_1/Translated_Face_18"), model.selection("FACE", "Extrusion_1_1/Translated_Face_27"), model.selection("FACE", "Extrusion_1_1/Translated_Face_17"), model.selection("FACE", "Extrusion_1_1/Translated_Face_31"), model.selection("FACE", "Extrusion_1_1/Translated_Face_32"), model.selection("FACE", "Extrusion_1_1/Translated_Face_30"), model.selection("FACE", "Extrusion_1_1/Translated_Face_28"), model.selection("FACE", "Extrusion_1_1/Translated_Face_29"), model.selection("FACE", "Extrusion_1_1/Translated_Face_8"), model.selection("FACE", "Extrusion_1_1/Translated_Face_22"), model.selection("FACE", "Extrusion_1_1/Translated_Face_7"), model.selection("FACE", "Extrusion_1_1/Translated_Face_6"), model.selection("FACE", "Extrusion_1_1/Translated_Face_5"), model.selection("FACE", "Extrusion_1_1/Translated_Face_3"), model.selection("FACE", "Extrusion_1_1/Translated_Face_1"), model.selection("FACE", "Extrusion_1_1/Translated_Face_2"), model.selection("FACE", "Extrusion_1_1/Translated_Face_21"), model.selection("FACE", "Extrusion_1_1/Translated_Face_4"), model.selection("FACE", "Extrusion_1_1/Translated_Face_25"), model.selection("FACE", "Extrusion_1_1/Translated_Face_27"), model.selection("FACE", "Extrusion_1_1/Translated_Face_21"), model.selection("FACE", "Extrusion_1_1/Translated_Face_22"), model.selection("FACE", "Extrusion_1_1/Translated_Face_26"), model.selection("FACE", "Extrusion_1_1/Translated_Face_23"), model.selection("FACE", "Extrusion_1_1/Translated_Face_30"), model.selection("FACE", "Extrusion_1_1/Translated_Face_23"), model.selection("FACE", "Extrusion_1_1/Translated_Face_14"), model.selection("FACE", "Extrusion_1_1/Translated_Face_15")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Translation_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OZ"), 50)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Translation_2_1/Translated_Face_24"), model.selection("FACE", "Translation_2_1/Translated_Face_13"), model.selection("FACE", "Translation_2_1/Translated_Face_16"), model.selection("FACE", "Translation_2_1/Translated_Face_12"), model.selection("FACE", "Translation_2_1/Translated_Face_9"), model.selection("FACE", "Translation_2_1/Translated_Face_10"), model.selection("FACE", "Translation_2_1/Translated_Face_11"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_20"), model.selection("FACE", "Translation_2_1/Translated_Face_19"), model.selection("FACE", "Translation_2_1/Translated_Face_18"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_17"), model.selection("FACE", "Translation_2_1/Translated_Face_31"), model.selection("FACE", "Translation_2_1/Translated_Face_32"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_28"), model.selection("FACE", "Translation_2_1/Translated_Face_29"), model.selection("FACE", "Translation_2_1/Translated_Face_8"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_7"), model.selection("FACE", "Translation_2_1/Translated_Face_6"), model.selection("FACE", "Translation_2_1/Translated_Face_5"), model.selection("FACE", "Translation_2_1/Translated_Face_3"), model.selection("FACE", "Translation_2_1/Translated_Face_1"), model.selection("FACE", "Translation_2_1/Translated_Face_2"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_4"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_26"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_14"), model.selection("FACE", "Translation_2_1/Translated_Face_15")])
#Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Translation_2_1_6/Translated_Face_1"), model.selection("FACE", "Translation_2_1_5/Translated_Face_1"), model.selection("FACE", "Translation_2_1_5/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_4"), model.selection("FACE", "Translation_2_1_5/Translated_Face_3"), model.selection("FACE", "Translation_2_1_5/Translated_Face_2"), model.selection("FACE", "Translation_2_1_5/Translated_Face_5"), model.selection("FACE", "Translation_2_1_7/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_5"), model.selection("FACE", "Translation_2_1_4/Translated_Face_1"), model.selection("FACE", "Translation_2_1_2/Translated_Face_2"), model.selection("FACE", "Translation_2_1_5/Translated_Face_5"), model.selection("FACE", "Translation_2_1_2/Translated_Face_1"), model.selection("FACE", "Translation_2_1_4/Translated_Face_5"), model.selection("FACE", "Translation_2_1_2/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_5"), model.selection("FACE", "Translation_2_1_1/Translated_Face_3"), model.selection("FACE", "Translation_2_1_4/Translated_Face_2"), model.selection("FACE", "Translation_2_1_2/Translated_Face_3"), model.selection("FACE", "Translation_2_1_1/Translated_Face_4"), model.selection("FACE", "Translation_2_1_1/Translated_Face_1"), model.selection("FACE", "Translation_2_1_1/Translated_Face_2"), model.selection("FACE", "Translation_2_1_3/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_5"), model.selection("FACE", "Translation_2_1_3/Translated_Face_2"), model.selection("FACE", "Translation_2_1_3/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_1"), model.selection("FACE", "Translation_2_1_7/Translated_Face_3"), model.selection("FACE", "Translation_2_1_7/Translated_Face_5"), model.selection("FACE", "Translation_2_1_7/Translated_Face_4"), model.selection("FACE", "Translation_2_1_7/Translated_Face_1"), model.selection("FACE", "Translation_2_1_7/Translated_Face_2"), model.selection("FACE", "Translation_2_1_6/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_2"), model.selection("FACE", "Translation_2_1_6/Translated_Face_3")])
model.end()
Part_1_doc = Part_1.document()
Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_3")])
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 100, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Wire_1_1/Generated_Face_3"), model.selection("FACE", "Wire_1_1/Generated_Face_2"), model.selection("FACE", "Wire_1_1/Generated_Face_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1")])
model.do()
model.end()
model.do()
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2f"), model.selection("FACE", "Sketch_2/Face-SketchCircle_3_2f")], model.selection(), 10, 0)
Boolean_1 = model.addSmash(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")])
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_2_2/To_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_2/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Boolean_1_1_1/Modified_1"), model.selection("FACE", "_Extrusion_1_1/From_Face_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Extrusion_2_1/To_Face_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_2_2/To_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_2/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Boolean_1_1_1/Modified_Face_1"), model.selection("FACE", "Extrusion_1_1/From_Face_1"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Extrusion_2_1/To_Face_1")])
model.do()
model.end()
model.do()
Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Base_Edge_1")])
-Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Face_1_1/Lateral_Edge_1")])
-Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Face_1_1/Lateral_Edge_1&Face_1_1/Base_Edge_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Base_Edge_1")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Lateral_Edge_1&Revolution_1_1/Base_Edge_1")])
model.end()
# check that resulting group selection is valid
MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Face_5_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_9"), "length_assemblage", 4, model.selection("EDGE", "PartSet/OY"), "length_assemblage", 2)
Recover_1 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_1_1")], model.selection("VERTEX", "Sketch_3/Vertex-SketchPoint_1-SketchLine_12s-SketchLine_11e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_6s-SketchLine_5e"))
-Translation_1.result().setName("Translation_1_1")
MultiTranslation_2 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_1_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 4, model.selection("EDGE", "PartSet/OY"), "length_assemblage", 2)
Recover_2 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "Sketch_3/Vertex-SketchPoint_1-SketchLine_12s-SketchLine_11e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"))
-Translation_2.result().setName("Translation_2_1")
MultiTranslation_3 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_2_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 4)
Recover_3 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
-Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_9s-SketchLine_7e"), model.selection("VERTEX", "Translation_2_1/Translated_Edge_1_4&Translation_2_1/Translated_Edge_1_1"))
-Translation_3.result().setName("Translation_3_1")
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_9s-SketchLine_7e"), model.selection("VERTEX", "LinearCopy_3_1/Translated_Edge_1_4&LinearCopy_3_1/Translated_Edge_1_1"))
MultiTranslation_4 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_3_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 3)
Recover_4 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_9s-SketchLine_7e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_10s"))
-Translation_4.result().setName("Translation_4_1")
MultiTranslation_5 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_4_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 2)
-Partition_2 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Face_1_1"), model.selection("COMPOUND", "Face_5_1"), model.selection("COMPOUND", "Translation_1_1"), model.selection("COMPOUND", "Translation_2_1"), model.selection("COMPOUND", "Translation_3_1"), model.selection("COMPOUND", "Translation_4_1")])
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Partition_1_1"), model.selection("COMPOUND", "LinearCopy_1_1"), model.selection("COMPOUND", "LinearCopy_2_1"), model.selection("COMPOUND", "LinearCopy_3_1"), model.selection("COMPOUND", "LinearCopy_4_1"), model.selection("COMPOUND", "LinearCopy_5_1")])
model.end()
# check that partition constructed correctly
model.do()
Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_2f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 360, 0)
Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], model.selection("EDGE", "PartSet/OY"), 150)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Translated_Vertex_1"), model.selection("VERTEX", "Revolution_1_1/Translated_Vertex_2")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Translation_1_1/Translated_Vertex_1"), model.selection("VERTEX", "Translation_1_1/Translated_Vertex_2")])
model.end()
# check that resulting group selection is valid, names exist and different
Wire_2 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Wire_1_1")])
Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Wire_2_1")])
-Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Wire_1_1"), model.selection("FACE", "Wire_2_1")], model.selection(), 50, 0)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")], model.selection(), 50, 0)
Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
SketchLine_5 = Sketch_2.addLine(49.62901186301215, 25.3130971701971, 39.15939470736273, 25.3130971701971)
SketchLine_6 = Sketch_2.addLine(39.15939470736273, 25.3130971701971, 39.15939470736273, 38.96586914453801)
SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
model.do()
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")], model.selection(), 50, 50, [model.selection("SOLID", "Wire_1_1"), model.selection("SOLID", "Wire_2_1")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6r-SketchLine_7r-SketchLine_8r")], model.selection(), 50, 50, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2")])
model.do()
model.end()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 10, 0)
model.do()
-model.testHaveNamingVertices(Extrusion_1, model, Part_1_doc)
+model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc)
model.end()
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-1.039451114922807, 35.51457975986278, -38.45969125214407, -21.30874785591767)
+SketchLine_2 = Sketch_1.addLine(-38.45969125214407, -21.30874785591767, 46.08233276157804, -21.30874785591767)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(46.08233276157804, -21.30874785591767, -1.039451114922807, 35.51457975986278)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f")], model.selection(), 100, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchCircle_1 = Sketch_2.addCircle(-10.74792845018279, -51.46099937127247, 20.55678647017868)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/OX"), model.selection("FACE", "PartSet/YOZ"), 0, model.selection(), 0)
+model.do()
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Extrusion_2, 1)
+model.testNbSubResults(Extrusion_2, [0])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [3])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [6])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [12])
+model.testResultsVolumes(Extrusion_2, [36480.150452606350881978869438171])
+
+assert(model.checkPythonDump())
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 100, 0)
Boolean_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1_2")], [model.selection("FACE", "PartSet/YOZ")])
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Boolean_1_1_4/Modified_3"), model.selection("FACE", "Boolean_1_1_4/Modified_Face_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Boolean_1_1_4/Modified_2"), model.selection("FACE", "Boolean_1_1_4/Modified_4"), model.selection("FACE", "Boolean_1_1_4/Modified_1"), model.selection("FACE", "Boolean_1_1_4/Modified_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_6"), model.selection("FACE", "Boolean_1_1_3/Modified_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_7"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Boolean_1_1_1/Modified_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_5"), model.selection("FACE", "Boolean_1_1_4/Modified_4"), model.selection("FACE", "Boolean_1_1_1/Modified_2"), model.selection("FACE", "Boolean_1_1_3/Modified_4"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_12"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_11"), model.selection("FACE", "Boolean_1_1_3/Modified_3"), model.selection("FACE", "Boolean_1_1_3/Modified_2"), model.selection("FACE", "Boolean_1_1_3/Modified_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "Boolean_1_1_3/Modified_4"), model.selection("FACE", "Boolean_1_1_4/Modified_Face_1"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "_Extrusion_1_1/To_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "_Extrusion_1_1/From_Face_3"), model.selection("FACE", "_Extrusion_1_1/Generated_Face_1")])
model.do()
+
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
model.end()
from GeomAPI import GeomAPI_Shape
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "5")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "Shift", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), 5)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), "Shift", True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Plane_2")])
+Boolean_2 = model.addFill(Part_1_doc, [model.selection("COMPOUND", "Boolean_1_1")], [model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_2, model, 1, [6], [0], [6], [22], [44])
+model.testHaveNamingSubshapes(Boolean_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-43.24383164005806, 13.92597968069667, 63.17997097242381, 62.8867924528302)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_2 = Sketch_2.addLine(-21.12944291883177, 24.09981691608177, 39.13933236574746, 51.82677414066782)
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchLine_3.result())
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Edge_2 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_2")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("EDGE", "Edge_2_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[3],[0],[0],[3],[6])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(-54.08747895500726, -7.310347750362856, 54.27191756168357, 63.68373962264153)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_2 = Sketch_2.addLine(-42.46271611030479, 53.71965718432511, 14.83075791001449, -51.73354862119014)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Edge_2 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_2")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("EDGE", "Edge_2_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[2],[0],[0],[2],[4])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(-65.15998142235124, 15.60729985486212, 25.76227082728593, 71.65526357039188)
+SketchLine_2 = Sketch_1.addLine(25.76227082728593, 71.65526357039188, 74.75234281567489, -47.08338548621191)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(74.75234281567489, -47.08338548621191, 13.30716777939044, -81.12733381712628)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(13.30716777939044, -81.12733381712628, -65.15998142235124, 15.60729985486212)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"))
+SketchLine_5 = Sketch_2.addLine(-53.77011318694006, -47.84888937635935, 60.89888292381829, 36.13719175945)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_5")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("FACE", "Face_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [3], [0], [0], [3], [6])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchArc_1 = Sketch_1.addArc(28.24683132290313, 24.84281403912743, 0, 50, 56.77054208906745, 0, False)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.endPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.result())
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_1.startPoint(), SketchAPI_Line(SketchLine_1).startPoint(), 50)
+SketchArc_2 = Sketch_1.addArc(38.14157263904823, 16.22495851193372, 56.77054208906745, 0, 34.15529753265601, 40.60522496371553, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 70, 0)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 30, False)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_3 = Sketch_2.addLine(-64.49168769733997, 17.16789081864163, 146.7677170722727, 22.9901626941168)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_3")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("SHELL", "Shell_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [3], [0], [0], [3], [6])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Front"))
+SketchLine_1 = Sketch_1.addLine(4, 10, 7, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "Box_1_1/Front&Box_1_1/Top"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "Box_1_1/Front&Box_1_1/Bottom"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [0], [1], [2])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Cone_1_1/Face_3"), 5, True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_1 = Sketch_1.addLine(-8.679188755740876, 4.967059748203267, 8.679188755740878, -4.967059748203268)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 20)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("SOLID", "Cone_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [3], [0], [0], [3], [6])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Point_1 = model.addPoint(Part_1_doc, 10, 10, 0)
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Point_1")])
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-27.61369370623992, 41.69872643310781, 64.30052615729069, -35.76145957046036)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Point_1"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchAPI_Point(SketchPoint_1).coordinates())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("VERTEX", "Vertex_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[2],[0],[0],[2],[4])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(-67.57764876632801, 2.198838896952097, 88.39332365747461, 44.12336719883891)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_2 = Sketch_2.addLine(-40.60522496371553, -29.75761973875181, -38.84615384615385, 66.99129172714079)
+SketchLine_3 = Sketch_2.addLine(-38.84615384615385, 66.99129172714079, 50.86647314949202, 73.4412191582003)
+SketchConstraintCoincidence_1 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_2.addLine(50.86647314949202, 73.4412191582003, 55.26415094339622, -34.15529753265602)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_2.addLine(55.26415094339622, -34.15529753265602, -40.60522496371553, -29.75761973875181)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_2.startPoint())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_4")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], [model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [3], [0], [0], [3], [6])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(-65.15998142235124, 15.60729985486212, 25.76227082728593, 71.65526357039188)
+SketchLine_2 = Sketch_1.addLine(25.76227082728593, 71.65526357039188, 74.75234281567489, -47.08338548621191)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(74.75234281567489, -47.08338548621191, 13.30716777939044, -81.12733381712628)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(13.30716777939044, -81.12733381712628, -65.15998142235124, 15.60729985486212)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"))
+SketchLine_5 = Sketch_2.addLine(-53.77011318694006, -47.84888937635935, 60.89888292381829, 36.13719175945)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_5")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[2],[0],[2],[8],[16])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch_1.addArc(-31.22351233671988, 15.68505079825835, -49.40058055152394, 17.44412191582002, -17.30100145268062, 27.5029960835475, True)
+SketchLine_1 = Sketch_1.addLine(-17.30100145268062, 27.5029960835475, -6.596516690856308, -20.66908563134978)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint())
+SketchLine_2 = Sketch_1.addLine(-6.596516690856308, -20.66908563134978, -34.74165457184325, -28.87808417997097)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-34.74165457184325, -28.87808417997097, -49.40058055152394, 17.44412191582002)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_3.endPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_1r-SketchLine_2r-SketchLine_3r"))
+SketchLine_4 = Sketch_2.addLine(-17.59187701681758, -17.53169787967194, -23.97073271029336, 4.338664497959301)
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), False)
+SketchLine_5 = SketchProjection_1.createdFeature()
+SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_4.result(), SketchLine_5.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_4")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[1],[5],[10])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-27.76647174128943, 72.31029012920524, 42.2686420251427, 59.94944420697596)
+SketchLine_2 = Sketch_1.addLine(42.2686420251427, 59.94944420697596, 59.0507718766223, 21.43074552356853)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(59.0507718766223, 21.43074552356853, 56.1909608273397, -69.919416180974)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(56.1909608273397, -69.919416180974, -29.91225626113892, -65.09334567012574)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-29.91225626113892, -65.09334567012574, -57.18321726979322, -2.500460309588558)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-57.18321726979322, -2.500460309588558, -27.76647174128943, 72.31029012920524)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_1.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_7 = Sketch_2.addLine(24.33758278426026, -52.48127186534471, 29.40566289183227, 59.45054433956496)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_7")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[1],[6],[13])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "R", "50")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-49.81325699578132, 35.39936274902501, 0, 8.200436015051352)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(0, 8.200436015051352, 49.94978427678259, 33.32234621934526)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, 31.08202242513997, 49.94978427678259, 33.32234621934526, -49.81325699578132, 35.39936274902501, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_2.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "R")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_4 = Sketch_2.addLine(31.79164821526215, 49.99496405877289, 8.200436015051352, 0)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_1e"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchPoint_1.result())
+SketchLine_5 = Sketch_2.addLine(8.200436015051352, 0, 27.24680168984479, -49.85269382803262)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_1"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchArc_2 = Sketch_2.addArc(31.08202242513997, 1.147024884467139e-021, 27.24680168984479, -49.85269382803262, 31.79164821526215, 49.99496405877289, False)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchPoint_2.result(), SketchArc_2.center())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchArc_2.endPoint(), SketchLine_4.startPoint())
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchArc_2.results()[1], "R")
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchArc_1_2f")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_4f-SketchLine_5f-SketchArc_2_2f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Face_2_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [2], [0], [2], [6], [12])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "D", "50")
+model.addParameter(Part_1_doc, "L", "30")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 28.78679656440358, 21.21320343559643, 50)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(21.21320343559643, 50, 0, 71.21320343559643)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_2.result())
+SketchLine_4 = Sketch_1.addLine(0, 71.21320343559643, -21.21320343559642, 50)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-21.21320343559642, 50, 0, 28.78679656440358)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(-21.21320343559642, 50, 21.21320343559643, 50)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_6.result(), "D", True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), "L")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_5.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_3.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchLine_7 = Sketch_2.addLine(50, -39.61510263929618, 50, 43.87280058651025)
+SketchLine_7.setName("SketchLine_8")
+SketchLine_7.result().setName("SketchLine_8")
+SketchLine_7.setAuxiliary(True)
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_7.result())
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_7.result(), "D", True)
+SketchLine_8 = Sketch_2.addLine(57.5, 0, 65, -10.81485284151855)
+SketchLine_8.setName("SketchLine_9")
+SketchLine_8.result().setName("SketchLine_9")
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchLine_9.setName("SketchLine_10")
+SketchLine_9.result().setName("SketchLine_10")
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchLine_9.result())
+SketchLine_10 = Sketch_2.addLine(65, -10.81485284151855, 65, 11.50710132369052)
+SketchLine_10.setName("SketchLine_11")
+SketchLine_10.result().setName("SketchLine_11")
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_2.addLine(65, 11.50710132369052, 50, 11.50710132369052)
+SketchLine_11.setName("SketchLine_12")
+SketchLine_11.result().setName("SketchLine_12")
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_8.startPoint(), SketchLine_7.result(), "L/4", True)
+SketchConstraintDistance_4 = Sketch_2.setDistance(SketchLine_8.endPoint(), SketchLine_7.result(), "L/2", True)
+SketchConstraintDistance_5 = Sketch_2.setDistance(SketchLine_10.endPoint(), SketchLine_7.result(), "L/2", True)
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_11.result())
+SketchConstraintMirror_1_objects = [SketchLine_8.result(), SketchLine_10.result(), SketchLine_11.result()]
+SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_7.result(), SketchConstraintMirror_1_objects)
+[SketchLine_12, SketchLine_13, SketchLine_14] = SketchConstraintMirror_1.mirrored()
+SketchLine_14.setName("SketchLine_15")
+SketchLine_14.result().setName("SketchLine_15")
+SketchLine_13.setName("SketchLine_14")
+SketchLine_13.result().setName("SketchLine_14")
+SketchLine_12.setName("SketchLine_13")
+SketchLine_12.result().setName("SketchLine_13")
+SketchLine_15 = Sketch_2.addLine(42.5, 0, 57.5, 0)
+SketchLine_15.setName("SketchLine_16")
+SketchLine_15.result().setName("SketchLine_16")
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_12).startPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_15.endPoint(), SketchLine_8.startPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_5f-SketchLine_6r")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_3f-SketchLine_4f-SketchLine_6f")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_3_1")], [model.selection("SHELL", "Shell_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [3], [0], [3], [14], [28])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "5")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "Shift", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), 5)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [4], [0], [4], [15], [30])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Point_2 = model.addPoint(Part_1_doc, 22, 33, 0)
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(80.77068214804063, 60.54136429608128, -35.9143686502177, 60.54136429608128)
+SketchLine_2 = Sketch_1.addLine(-35.9143686502177, 60.54136429608128, -35.9143686502177, -37.67343976777939)
+SketchLine_3 = Sketch_1.addLine(-35.9143686502177, -37.67343976777939, 80.77068214804063, -37.67343976777939)
+SketchLine_4 = Sketch_1.addLine(80.77068214804063, -37.67343976777939, 80.77068214804063, 60.54136429608128)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2")])
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Point_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("VERTEX", "Vertex_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[1],[4],[9])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "R", "50")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-49.81325699578132, 35.39936274902501, 0, 8.200436015051352)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(0, 8.200436015051352, 49.94978427678259, 33.32234621934526)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, 31.08202242513997, 49.94978427678259, 33.32234621934526, -49.81325699578132, 35.39936274902501, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_2.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "R")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_4 = Sketch_2.addLine(-42.38833891077762, 73.71572760627062, -18.23994072168525, 7.835320880296757)
+SketchLine_5 = Sketch_2.addLine(-18.23994072168525, 7.835320880296757, 13.89341696052619, 27.33089138697832)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_2.addLine(13.89341696052619, 27.33089138697832, 39.39985877388298, 9.747860956493145)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_2.addLine(39.39985877388298, 9.747860956493145, 38.20105433548567, 71.93732104572752)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(38.20105433548567, 71.93732104572752, -42.38833891077762, 73.71572760627062)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchLine_8.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchArc_1_2f")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [5], [0], [5], [21], [42])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchArc_1 = Sketch_1.addArc(28.24683132290313, 24.84281403912743, 0, 50, 56.77054208906745, 0, False)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.endPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.result())
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_1.startPoint(), SketchAPI_Line(SketchLine_1).startPoint(), 50)
+SketchArc_2 = Sketch_1.addArc(38.14157263904823, 16.22495851193372, 56.77054208906745, 0, 34.15529753265601, 40.60522496371553, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 70, 0)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("FACE", "PartSet/XOZ")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[3],[12],[24])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchArc_1 = Sketch_1.addArc(28.24683132290313, 24.84281403912743, 0, 50, 56.77054208906745, 0, False)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.endPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.result())
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_1.startPoint(), SketchAPI_Line(SketchLine_1).startPoint(), 50)
+SketchArc_2 = Sketch_1.addArc(38.14157263904823, 16.22495851193372, 56.77054208906745, 0, 34.15529753265601, 40.60522496371553, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 70, 0)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 30, False)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_3 = Sketch_2.addLine(-64.49168769733997, 17.16789081864163, 146.7677170722727, 22.9901626941168)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_3")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[2],[8],[18])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "D", "50")
+model.addParameter(Part_1_doc, "L", "30")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-6, 29.93619865618197, 18, 47.93619865618197)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchLine_3 = Sketch_1.addLine(18, 47.93619865618197, 0, 71.93619865618197)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_2.result())
+SketchLine_4 = Sketch_1.addLine(0, 71.93619865618197, -24, 53.93619865618197)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-24, 53.93619865618197, -6, 29.93619865618197)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(-24, 53.93619865618197, 18, 47.93619865618197)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_6.result(), "D", True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), "L")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_5.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_5.endPoint(), SketchLine_2.result(), "L/5", True)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchLine_7 = Sketch_2.addLine(50, -39.61510263929618, 50, 43.87280058651025)
+SketchLine_7.setName("SketchLine_8")
+SketchLine_7.result().setName("SketchLine_8")
+SketchLine_7.setAuxiliary(True)
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_7.result())
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_7.result(), "D", True)
+SketchLine_8 = Sketch_2.addLine(50, -3.170182618622045, 80, -14.17077918941143)
+SketchLine_8.setName("SketchLine_9")
+SketchLine_8.result().setName("SketchLine_9")
+SketchLine_9 = Sketch_2.addLine(80, -14.17077918941143, 64.99999999999999, 12.18920647716607)
+SketchLine_9.setName("SketchLine_11")
+SketchLine_9.result().setName("SketchLine_11")
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_8.setName("SketchConstraintCoincidence_9")
+SketchLine_10 = Sketch_2.addLine(64.99999999999999, 12.18920647716607, 50, 12.18920647716607)
+SketchLine_10.setName("SketchLine_12")
+SketchLine_10.result().setName("SketchLine_12")
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_7.result())
+SketchConstraintDistance_4 = Sketch_2.setDistance(SketchLine_8.endPoint(), SketchLine_7.result(), "L", True)
+SketchConstraintDistance_5 = Sketch_2.setDistance(SketchLine_9.endPoint(), SketchLine_7.result(), "L/2", True)
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_10.result())
+SketchConstraintMirror_1_objects = [SketchLine_8.result(), SketchLine_9.result(), SketchLine_10.result()]
+SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_7.result(), SketchConstraintMirror_1_objects)
+[SketchLine_11, SketchLine_12, SketchLine_13] = SketchConstraintMirror_1.mirrored()
+SketchLine_13.setName("SketchLine_15")
+SketchLine_13.result().setName("SketchLine_15")
+SketchLine_12.setName("SketchLine_14")
+SketchLine_12.result().setName("SketchLine_14")
+SketchLine_11.setName("SketchLine_13")
+SketchLine_11.result().setName("SketchLine_13")
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchLine_7.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_5f-SketchLine_6r")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_3f-SketchLine_4f-SketchLine_6f")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13r-SketchLine_14r-SketchLine_15r")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("FACE", "Face_3_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [4], [13], [26])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "D", "50")
+model.addParameter(Part_1_doc, "L", "30")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-10, 32.04672553984553, 15.61552812808831, 47.66225366793383)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchLine_3 = Sketch_1.addLine(15.61552812808831, 47.66225366793383, -4.988916520257207e-021, 73.27778179602213)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_2.result())
+SketchLine_4 = Sketch_1.addLine(-4.988916520257207e-021, 73.27778179602213, -25.61552812810082, 57.66225366792627)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-25.61552812810082, 57.66225366792627, -10, 32.04672553984553)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(-25.61552812810082, 57.66225366792627, 15.61552812808831, 47.66225366793383)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_6.result(), "D", True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), "L")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_5.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_5.endPoint(), SketchLine_2.result(), "L/3", True)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_7 = Sketch_2.addLine(50, 15.56025031353752, 50, -15.54016280334104)
+SketchLine_8 = Sketch_2.addLine(50, -15.54016280334104, 36.52981427174974, 0)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_9 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.result())
+SketchLine_10 = Sketch_2.addLine(36.52981427174974, 0, 50, 15.56025031353752)
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_7.startPoint(), SketchLine_10.endPoint())
+SketchLine_11 = Sketch_2.addLine(50, 15.56025031353752, 73.27778179602213, 0)
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_7.startPoint(), SketchLine_11.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"), False)
+SketchPoint_1 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchPoint_1.result())
+SketchLine_12 = Sketch_2.addLine(73.27778179602213, 0, 50, -15.54016280334104)
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_12.endPoint())
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchAPI_Line(SketchLine_9).startPoint(), SketchLine_7.result(), "D", True)
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_7.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_5f-SketchLine_6r")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_3f-SketchLine_4f-SketchLine_6f")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_7r-SketchLine_8r-SketchLine_10r")])
+Face_4 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_7f-SketchLine_11r-SketchLine_12r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_4_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("SHELL", "Shell_2_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [4], [15], [30])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "5")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "Shift", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), 5)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), "Shift", True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Plane_2")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Boolean_1_1_2"), model.selection("FACE", "Boolean_1_1_1")])
+Boolean_2 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_2, model, 1, [0], [0], [6], [22], [44])
+model.testHaveNamingSubshapes(Boolean_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch_1.addArc(9.761379814097372, -58.25586643592183, 0, 0, -48.40807467084933, -47.99209154562215, False)
+SketchArc_2 = Sketch_1.addArc(-12.6706171814691, -54.29782746957817, -48.40807467084933, -47.99209154562215, 12.46009047944227, -80.47750863283412, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchAPI_Point(SketchPoint_1).coordinates())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_2_2")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 50, 0)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("SHELL", "Extrusion_1_1")])
+Point_2 = model.addPoint(Part_1_doc, 0, 0, 10)
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Point_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("VERTEX", "Vertex_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[2],[9],[18])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "D", "50")
+model.addParameter(Part_1_doc, "L", "30")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 28.78679656440358, 21.21320343559643, 50)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(21.21320343559643, 50, 0, 71.21320343559643)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_2.result())
+SketchLine_4 = Sketch_1.addLine(0, 71.21320343559643, -21.21320343559642, 50)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-21.21320343559642, 50, 0, 28.78679656440358)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(-21.21320343559642, 50, 21.21320343559643, 50)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_6.result(), "D", True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), "L")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_5.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_3.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_7 = Sketch_2.addLine(-14.33356820392057, 60, 15.66643179607943, 60)
+SketchLine_8 = Sketch_2.addLine(15.66643179607943, 60, 15.66643179607943, 30)
+SketchLine_9 = Sketch_2.addLine(15.66643179607943, 30, -14.33356820392057, 30)
+SketchLine_10 = Sketch_2.addLine(-14.33356820392057, 30, -14.33356820392057, 60)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_2 = Sketch_2.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_2 = Sketch_2.setVertical(SketchLine_10.result())
+SketchConstraintLength_2 = Sketch_2.setLength(SketchLine_9.result(), "L")
+SketchConstraintLength_3 = Sketch_2.setLength(SketchLine_8.result(), "L")
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_9.result(), "L", True)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_5f-SketchLine_6r")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_3f-SketchLine_4f-SketchLine_6f")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_10")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], [model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [8], [30], [60])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Cone_1_1")], [model.selection("FACE", "PartSet/YOZ"), model.selection("FACE", "PartSet/XOZ")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[4],[4],[20],[72],[144])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "12")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "L/2", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), "Shift/3")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), "Shift/3", True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Plane_2")])
+Boolean_2 = model.addFill(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("COMPOUND", "Boolean_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_2, model, 1, [2], [2], [14], [60], [120])
+model.testHaveNamingSubshapes(Boolean_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "12")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "L/2", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), "Shift/3")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), "Shift/3", True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Plane_2")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Boolean_1_1_2"), model.selection("FACE", "Boolean_1_1_1")])
+MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], model.selection("EDGE", "PartSet/OZ"), 1, 3)
+Boolean_2 = model.addFill(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("COMPOUND", "LinearCopy_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_2, model, 1, [4], [4], [30], [132], [264])
+model.testHaveNamingSubshapes(Boolean_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Front"))
+SketchLine_1 = Sketch_1.addLine(4, 10, 7, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "Box_1_1/Front&Box_1_1/Top"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "Box_1_1/Front&Box_1_1/Bottom"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [1], [7], [30], [60])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "12")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "L/2", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), "Shift/3")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("FACE", "Face_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [2], [2], [12], [48], [96])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "12")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "L/2", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), "Shift/3")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), "Shift/3", True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("FACE", "Face_1_1")], [model.selection("FACE", "Plane_2")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Boolean_1_1_2"), model.selection("FACE", "Boolean_1_1_1")])
+Boolean_2 = model.addFill(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("SHELL", "Shell_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_2, model, 1, [2], [2], [14], [60], [120])
+model.testHaveNamingSubshapes(Boolean_2, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(-67.57764876632801, 2.198838896952097, 88.39332365747461, 44.12336719883891)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_2 = Sketch_2.addLine(-40.60522496371553, -29.75761973875181, -38.84615384615385, 66.99129172714079)
+SketchLine_3 = Sketch_2.addLine(-38.84615384615385, 66.99129172714079, 50.86647314949202, 73.4412191582003)
+SketchConstraintCoincidence_1 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_2.addLine(50.86647314949202, 73.4412191582003, 55.26415094339622, -34.15529753265602)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_2.addLine(55.26415094339622, -34.15529753265602, -40.60522496371553, -29.75761973875181)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_2.startPoint())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_4")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[0],[6],[12])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "R", "50")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-49.81325699578132, 35.39936274902501, 0, 8.200436015051352)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(0, 8.200436015051352, 49.94978427678259, 33.32234621934526)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, 31.08202242513997, 49.94978427678259, 33.32234621934526, -49.81325699578132, 35.39936274902501, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_2.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "R")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_4 = Sketch_2.addLine(29.74624907439609, 30.07487215963349, 31.08202242513997, 0)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_1"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchPoint_1.result())
+SketchLine_5 = Sketch_2.addLine(31.08202242513997, 0, 45.45797599933665, 0)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_6 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.result())
+SketchLine_7 = Sketch_2.addLine(45.45797599933665, 0, 45.83553599350717, -22.747645239555)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(45.83553599350717, -22.747645239555, 70.40999925541598, 30.039147749218)
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_2.addLine(70.40999925541598, 30.039147749218, 29.74624907439609, 30.07487215963349)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchLine_9.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchArc_1_2f")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchLine_8f-SketchLine_9f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("FACE", "Face_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [0], [6], [12])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "D", "50")
+model.addParameter(Part_1_doc, "L", "30")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 28.78679656440358, 21.21320343559643, 50)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(21.21320343559643, 50, 0, 71.21320343559643)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_2.result())
+SketchLine_4 = Sketch_1.addLine(0, 71.21320343559643, -21.21320343559642, 50)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-21.21320343559642, 50, 0, 28.78679656440358)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(-21.21320343559642, 50, 21.21320343559643, 50)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_6.result(), "D", True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), "L")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_5.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_3.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchLine_7 = Sketch_2.addLine(50, -39.61510263929618, 50, 43.87280058651025)
+SketchLine_7.setName("SketchLine_8")
+SketchLine_7.result().setName("SketchLine_8")
+SketchLine_7.setAuxiliary(True)
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_7.result())
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_7.result(), "D", True)
+SketchLine_8 = Sketch_2.addLine(57.5, 0, 65, -10.81485284151855)
+SketchLine_8.setName("SketchLine_9")
+SketchLine_8.result().setName("SketchLine_9")
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchLine_9.setName("SketchLine_10")
+SketchLine_9.result().setName("SketchLine_10")
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchLine_9.result())
+SketchLine_10 = Sketch_2.addLine(65, -10.81485284151855, 65, 11.50710132369052)
+SketchLine_10.setName("SketchLine_11")
+SketchLine_10.result().setName("SketchLine_11")
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_2.addLine(65, 11.50710132369052, 50, 11.50710132369052)
+SketchLine_11.setName("SketchLine_12")
+SketchLine_11.result().setName("SketchLine_12")
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_8.startPoint(), SketchLine_7.result(), "L/4", True)
+SketchConstraintDistance_4 = Sketch_2.setDistance(SketchLine_8.endPoint(), SketchLine_7.result(), "L/2", True)
+SketchConstraintDistance_5 = Sketch_2.setDistance(SketchLine_10.endPoint(), SketchLine_7.result(), "L/2", True)
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_11.result())
+SketchConstraintMirror_1_objects = [SketchLine_8.result(), SketchLine_10.result(), SketchLine_11.result()]
+SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_7.result(), SketchConstraintMirror_1_objects)
+[SketchLine_12, SketchLine_13, SketchLine_14] = SketchConstraintMirror_1.mirrored()
+SketchLine_14.setName("SketchLine_15")
+SketchLine_14.result().setName("SketchLine_15")
+SketchLine_13.setName("SketchLine_14")
+SketchLine_13.result().setName("SketchLine_14")
+SketchLine_12.setName("SketchLine_13")
+SketchLine_12.result().setName("SketchLine_13")
+SketchLine_15 = Sketch_2.addLine(42.5, 0, 57.5, 0)
+SketchLine_15.setName("SketchLine_16")
+SketchLine_15.result().setName("SketchLine_16")
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_12).startPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_15.endPoint(), SketchLine_8.startPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_5f-SketchLine_6r")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_3f-SketchLine_4f-SketchLine_6f")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+Wire_1 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13r-SketchLine_14r-SketchLine_15r-SketchLine_16f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("SHELL", "Shell_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [0], [10], [20])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "L", "10")
+model.addParameter(Part_1_doc, "Shift", "5")
+Box_1 = model.addBox(Part_1_doc, "L", "L", "L")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), "Shift", True)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 11.4564392373896, -5, 0, -12.5, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(11.4564392373896, -5, 0, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, 5, 0, -12.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "L+Shift/2")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_2.startPoint(), 5)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint(), "Shift", True)
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchLine_2f-SketchLine_3f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [0], [9], [18])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Point_2 = model.addPoint(Part_1_doc, 10, 10, 0)
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Point_1")])
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-27.43492861072797, 41.55044273324706, 64.29883100829633, -35.76346801736826)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Point_1"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchAPI_Point(SketchPoint_1).coordinates())
+SketchLine_2 = Sketch_1.addLine(64.5972559141328, -34.82170453629492, 63.39686648861513, 69.37209759863701)
+SketchLine_3 = Sketch_1.addLine(63.39686648861513, 69.37209759863701, -27.43492861072797, 41.55044273324706)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("VERTEX", "Vertex_1_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1,model,1,[0],[0],[0],[4],[8])
+model.testHaveNamingSubshapes(Boolean_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "R", "50")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-49.81325699578132, 35.39936274902501, 0, 8.200436015051352)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(0, 8.200436015051352, 49.94978427678259, 33.32234621934526)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, 31.08202242513997, 49.94978427678259, 33.32234621934526, -49.81325699578132, 35.39936274902501, False)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_2.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "R")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_4 = Sketch_2.addLine(31.79164821526215, 49.99496405877289, 8.200436015051352, 0)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_1e"), False)
+SketchPoint_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchPoint_1.result())
+SketchLine_5 = Sketch_2.addLine(8.200436015051352, 0, 27.24680168984479, -49.85269382803262)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_1"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchArc_2 = Sketch_2.addArc(31.08202242513997, 1.147024884467139e-021, 27.24680168984479, -49.85269382803262, 31.79164821526215, 49.99496405877289, False)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchPoint_2.result(), SketchArc_2.center())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchArc_2.endPoint(), SketchLine_4.startPoint())
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchArc_2.results()[1], "R")
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchArc_1_2f")])
+Wire_2 = model.addWire(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_4f-SketchLine_5f-SketchArc_2_2f")])
+Boolean_1 = model.addFill(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], [model.selection("WIRE", "Wire_2_1")])
+model.do()
+
+model.checkBooleansResult(Boolean_1, model, 1, [0], [0], [0], [4], [8])
+model.testHaveNamingSubshapes(Boolean_1, model, Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ TestFillet.py
+ Unit test of FeaturesPlugin_Fillet class
+"""
+
+from ModelAPI import *
+
+__updated__ = "2017-11-30"
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+# Create a part for extrusion
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+aPart = aSession.activeDocument()
+
+# Create a box and a cylinder for filleting
+aSession.startOperation()
+aBox = aPart.addFeature("Box")
+aBox.string("CreationMethod").setValue("BoxByDimensions")
+aBox.real("dx").setValue(10)
+aBox.real("dy").setValue(10)
+aBox.real("dz").setValue(10)
+aSession.finishOperation()
+
+# a point to anchor a cylinder
+aSession.startOperation()
+aPoint = aPart.addFeature("Point")
+aPoint.string("creation_method").setValue("by_xyz")
+aPoint.real("x").setValue(20)
+aPoint.real("y").setValue(5)
+aPoint.real("z").setValue(0)
+aSession.finishOperation()
+
+aSession.startOperation()
+aCylinder = aPart.addFeature("Cylinder")
+aCylinder.string("CreationMethod").setValue("Cylinder")
+aCylinder.selection("base_point").selectSubShape("vertex", "Point_1")
+aCylinder.selection("axis").selectSubShape("edge", "PartSet/OZ")
+aCylinder.real("radius").setValue(5)
+aCylinder.real("height").setValue(10)
+aSession.finishOperation()
+
+#=========================================================================
+# Test 1. Create fillet with fixed radius
+#=========================================================================
+aSession.startOperation()
+aFillet1 = aPart.addFeature("Fillet")
+aFillet1.string("creation_method").setValue("fixed_radius")
+anObjects = aFillet1.selectionList("main_objects")
+anObjects.append("Box_1_1/Left&Box_1_1/Top", "edge")
+aFillet1.real("radius1").setValue(3)
+aSession.finishOperation()
+assert(aFillet1.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 2. Change fillet type
+#=========================================================================
+aSession.startOperation()
+aFillet1.string("creation_method").setValue("variable_radius")
+aFillet1.real("radius1").setValue(5)
+aFillet1.real("radius2").setValue(1)
+aSession.finishOperation()
+assert(aFillet1.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 3. Check fillet reports error if selected entities from different solids
+#=========================================================================
+aSession.startOperation()
+aFillet2 = aPart.addFeature("Fillet")
+aFillet2.string("creation_method").setValue("fixed_radius")
+anObjects = aFillet2.selectionList("main_objects")
+anObjects.append("Cylinder_1_1/Face_2", "face")
+anObjects.append("_Box_1_1/Right", "face")
+aFillet2.real("radius1").setValue(2)
+aSession.finishOperation()
+assert(aFillet2.error() != ""), "FAILED: Fillet does not report error"
+
+#=========================================================================
+# Test 4. Fix the error
+#=========================================================================
+aSession.startOperation()
+anObjects.removeLast()
+aSession.finishOperation()
+assert(aFillet2.error() == ""), "FAILED: Fillet reports error \"{}\"".format(aFillet1.error())
+
+#=========================================================================
+# Test 5. Check fillet reports error on smoothly connected edges
+#=========================================================================
+aSession.startOperation()
+aFillet3 = aPart.addFeature("Fillet")
+aFillet3.string("creation_method").setValue("fixed_radius")
+aFillet3.selectionList("main_objects").append("Cylinder_1_1/Modified_Face_1", "face")
+aFillet3.real("radius1").setValue(3)
+aSession.finishOperation()
+assert(aFillet3.lastResult() is None), "FAILED: Fillet should not produce a result"
+
+#=========================================================================
+# Test 6. Remove last fillet feature
+#=========================================================================
+aSession.startOperation()
+aPart.removeFeature(aFillet3)
+aSession.finishOperation()
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(55.40972222222221, 31.70277777777777, -46.71249999999999, 31.70277777777777)
+SketchLine_2 = Sketch_1.addLine(-46.71249999999999, 31.70277777777777, -46.71249999999999, -45.44999999999999)
+SketchLine_3 = Sketch_1.addLine(-46.71249999999999, -45.44999999999999, 55.40972222222221, -45.44999999999999)
+SketchLine_4 = Sketch_1.addLine(55.40972222222221, -45.44999999999999, 55.40972222222221, 31.70277777777777)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(64.38749999999999, 45.44999999999999, 41.86298795836804)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_1_2")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[3],[0],[3],[12],[24])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+from GeomAPI import GeomAPI_Shape
+
+model.begin()
+#Create part
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+#Create Sketch_1 - closed polyline from 5 segments
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(-43.90694444444443, 28.05555555555554, 19.21805555555554, 72.66388888888889)
+SketchLine_2 = Sketch_1.addLine(19.21805555555554, 72.66388888888889, 82.06249999999999, -36.19166666666666)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(82.06249999999999, -36.19166666666666, 19.4986111111111, -81.3611111111111)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(19.4986111111111, -81.3611111111111, -45.87083333333333, -45.44999999999999)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-45.87083333333333, -45.44999999999999, -43.90694444444443, 28.05555555555554)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+model.do()
+#Create Extrusion_1 on Sketch_1
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r-SketchLine_5r")], model.selection(), 100, 0)
+#Create Sketch_2 from 5 segments
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchLine_6 = Sketch_2.addLine(74.07000206783135, -18.10965884648514, 62.37497281453477, -31.70853007124862)
+SketchLine_7 = Sketch_2.addLine(62.37497281453477, -31.70853007124862, 37.35304976096997, -31.43655264675337)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(37.35304976096997, -31.43655264675337, 25.65802050767337, -1.791013376768974)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_2.addLine(25.65802050767337, -1.791013376768974, 69.44638585141178, 6.640286782584385)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchLine_10 = Sketch_2.addLine(69.44638585141178, 6.640286782584385, 74.07000206783135, -18.10965884648514)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_6.startPoint(), SketchLine_10.endPoint())
+model.do()
+#Create Extrusion_2 on Sketch_2
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_6r-SketchLine_7r-SketchLine_8r-SketchLine_9r-SketchLine_10r")], model.selection(), 10, 160)
+#Create Partition on objects Extrusion_1 and Extrusion_2
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[4],[4],[33],[150],[300])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(-59.3375, 27.49444444444443, -20.05972222222222, 71.26111111111109)
+SketchLine_2 = Sketch_1.addLine(-20.05972222222222, 71.26111111111109, 31.5625, 60.31944444444444)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(31.5625, 60.31944444444444, 48.95694444444444, -41.52222222222221)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(48.95694444444444, -41.52222222222221, -7.434722222222216, -63.6861111111111)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-7.434722222222216, -63.6861111111111, -12.20416666666666, 3.0861111111111)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-12.20416666666666, 3.0861111111111, -59.3375, 27.49444444444443)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_1.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchArc_1 = Sketch_2.addArc(-25.27347239223771, 29.23826809458483, -58.42699662355402, 67.59234514649975, 1.894762451441686, -13.56451698932517, False)
+SketchLine_7 = Sketch_2.addLine(-58.42699662355402, 67.59234514649975, 66.71130562210065, 43.53978835123107)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.startPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(66.71130562210065, 43.53978835123107, 30.30743587791019, -67.62202818906478)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_2.addLine(30.30743587791019, -67.62202818906478, 1.894762451441686, -13.56451698932518)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_9.endPoint())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_2/Edge-SketchArc_1_2")])
+Wire_2 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_6")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("WIRE", "Wire_2_1"), model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[2],[0],[0],[22],[44])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 100, 100, 400)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 100, False)
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), 100, False)
+Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 100, False)
+Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 50, False)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2"), model.selection("FACE", "Plane_3"), model.selection("FACE", "Plane_4"), model.selection("SOLID", "Box_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[8],[8],[48],[192],[384])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+Point_1 = model.addPoint(Part_1_doc, 4, 5, 11)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("EDGE", "PartSet/OX"), model.selection("VERTEX", "Point_1"), False)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_1 = Sketch_1.addLine(1.156555510724249, 12.03812858614785, 0.5812800089239156, -4.87167684997945)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cone_1_1"), model.selection("EDGE", "Edge_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[3],[1],[3],[9],[20])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, -23.6272731038225, 7.84836794507966, 9.071298990348682, 0, 10, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.center())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.endPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_2 = Sketch_1.addArc(5.671059039631239, 0, 7.84836794507966, 9.071298990348682, 15, 0, True)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_2.center())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_2.endPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_2.endPoint(), 15, True)
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.endPoint(), 10, True)
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_2.result(), [SketchArc_2.results()[1], SketchArc_1.results()[1]])
+[SketchArc_3, SketchArc_4] = SketchConstraintMirror_1.mirrored()
+SketchConstraintMirror_2_objects = [SketchArc_1.results()[1], SketchArc_2.results()[1], SketchArc_3.results()[1], SketchArc_4.results()[1]]
+SketchConstraintMirror_2 = Sketch_1.addMirror(SketchLine_1.result(), SketchConstraintMirror_2_objects)
+[SketchArc_5, SketchArc_6, SketchArc_7, SketchArc_8] = SketchConstraintMirror_2.mirrored()
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 12, 12)
+
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
+SketchLine_3 = Sketch_2.addLine(7.498934040825037, 4.111344571723496, -7.530337532973568, 4.111344571723496)
+SketchLine_4 = Sketch_2.addLine(-7.530337532973568, 4.111344571723496, -7.530337532973568, -4.489390918751097)
+SketchLine_5 = Sketch_2.addLine(-7.530337532973568, -4.489390918751097, 7.498934040825037, -4.489390918751097)
+SketchLine_6 = Sketch_2.addLine(7.498934040825037, -4.489390918751097, 7.498934040825037, 4.111344571723496)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_2.setVertical(SketchLine_6.result())
+SketchCircle_1 = Sketch_2.addCircle(-0.133117930244568, 0.08984026389066591, 1.099112071963378)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchCircle_1_2r")], model.selection(), model.selection(), 5, model.selection(), 10)
+
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_7 = Sketch_3.addLine(21.55890075100801, 30.21822825485694, -17.43219636481839, 31.63011070278906)
+SketchLine_8 = Sketch_3.addLine(-17.43219636481839, 31.63011070278906, -12.33809712604348, -45.93749869468675)
+SketchConstraintCoincidence_10 = Sketch_3.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_3.addLine(-12.33809712604348, -45.93749869468675, 30.10255255530162, -25.9120009302625)
+SketchConstraintCoincidence_11 = Sketch_3.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchLine_10 = Sketch_3.addLine(30.10255255530162, -25.9120009302625, 21.55890075100801, 30.21822825485694)
+SketchConstraintCoincidence_12 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchLine_7.startPoint(), SketchLine_10.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_3/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_3/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_3/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_3/Edge-SketchLine_10")])
+
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[2],[4],[42],[198],[396])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(29.00299588076832, 85.46917598420691, 38.5336063380206, 85.46917598420691)
+SketchLine_2 = Sketch_1.addLine(38.5336063380206, 85.46917598420691, 51.24108694769031, 59.52473640613128)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(51.24108694769031, 59.52473640613128, 51.24108694769031, 20.87281621838598)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(51.24108694769031, 20.87281621838598, 74.53813473208469, 20.87281621838598)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(74.53813473208469, 20.87281621838598, 74.53813473208469, 7.635857249980032)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(74.53813473208469, 7.635857249980032, 29.00299588076832, 7.635857249980032)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(29.00299588076832, 7.635857249980032, 29.00299588076832, 85.46917598420691)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_7.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_5.result())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_1.result())
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r-SketchLine_5r-SketchLine_6r-SketchLine_7r")], model.selection("EDGE", "PartSet/OZ"), 180, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/To_Face_1"))
+SketchLine_8 = Sketch_2.addLine(61.72045613220821, 51.92790864086226, -64.56856594464165, 51.92790864086226)
+SketchLine_9 = Sketch_2.addLine(-64.56856594464165, 51.92790864086226, -64.56856594464165, -5.323114700643004)
+SketchLine_10 = Sketch_2.addLine(-64.56856594464165, -5.323114700643004, 61.72045613220821, -5.323114700643004)
+SketchLine_11 = Sketch_2.addLine(61.72045613220821, -5.323114700643004, 61.72045613220821, 51.92790864086226)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_8.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_9.result())
+SketchConstraintHorizontal_5 = Sketch_2.setHorizontal(SketchLine_10.result())
+SketchConstraintVertical_5 = Sketch_2.setVertical(SketchLine_11.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_11"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_10"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_9")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Revolution_1_1"), model.selection("FACE", "Face_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[4],[1],[16],[82],[164])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch_1.addArc(-27.59408640325028, 19.28272273466096, -69.22045455254333, 36.34312971236017, -20.39867310978187, 63.6903576534723, True)
+SketchLine_1 = Sketch_1.addLine(-20.39867310978187, 63.6903576534723, 50.06261173489778, 52.27344552622073)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint())
+SketchLine_2 = Sketch_1.addLine(50.06261173489778, 52.27344552622073, 61.51017441860466, -50.20639534883721)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(61.51017441860466, -50.20639534883721, -40.37063953488371, -58.72093023255813)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-40.37063953488371, -58.72093023255813, -8.587370006050145, 0.9678324888285939)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(-8.587370006050145, 0.9678324888285939, -69.22045455254333, 36.34312971236017)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_5.endPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchLine_1.result(), SketchArc_1.results()[1])
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_2 = Sketch_2.addArc(25.75044090453202, 23.87245760846999, -31.39978593836629, 46.7325483456293, 20.55274339063303, 85.20528827247816, True)
+SketchLine_6 = Sketch_2.addLine(20.55274339063303, 85.20528827247816, 74.86874397491491, -32.65992894423484)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_2.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_2.addLine(74.86874397491491, -32.65992894423484, 9.995513504597909, -67.56790534016733)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(9.995513504597909, -67.56790534016733, -36.0335881148175, -7.328477046301525)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_2.addLine(-36.0335881148175, -7.328477046301525, -31.39978593836629, 46.7325483456293)
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchArc_2.startPoint(), SketchLine_9.endPoint())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_2/Edge-SketchArc_2_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_8")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[6],[0],[5],[39],[78])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-18.11540697674418, -21.53002906976744, 69.96519983648402)
+SketchCircle_2 = Sketch_1.addCircle(-18.11540697674418, -21.53002906976744, 31.60961705559024)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchCircle_2.center())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f-SketchCircle_2_2r")], model.selection(), 100, 0)
+Point_2 = model.addPoint(Part_1_doc, 100, 40, 80)
+Point_3 = model.addPoint(Part_1_doc, 100, -40, 80)
+Point_4 = model.addPoint(Part_1_doc, 20, 40, -80)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("VERTEX", "Point_2"), model.selection("VERTEX", "Point_3"))
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_1 = Sketch_2.addLine(98.50650093667804, 100.9440062780326, 111.3990833103819, -44.73923695837706)
+SketchLine_2 = Sketch_2.addLine(111.3990833103819, -44.73923695837706, -130.2032518739455, -87.67357443122384)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_2.addLine(-130.2032518739455, -87.67357443122384, -102.5665996005733, 115.6113578178721)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_2.addLine(-102.5665996005733, 115.6113578178721, 98.50650093667804, 100.9440062780326)
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_3")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("FACE", "Face_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[3],[2],[10],[30],[60])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Torus_1 = model.addTorus(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 15, 3)
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchLine_1 = Sketch_1.addLine(-6.378039652249388, 16.497623739925, 8.984305600666083, -24.54329369827008)
+SketchLine_2 = Sketch_1.addLine(8.984305600666083, -24.54329369827008, 36.73713621773835, -5.929982231235201)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(36.73713621773835, -5.929982231235201, 19.18554250372658, 21.11854572580065)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(19.18554250372658, 21.11854572580065, -6.378039652249388, 16.497623739925)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+SketchCircle_1 = Sketch_1.addCircle(14.49765103937751, 9.678507230150521, 3.831444106492329)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_5 = Sketch_2.addLine(-15.11211565655763, 11.99814589971457, -14.79635576556081, -11.77064279967296)
+SketchLine_6 = Sketch_2.addLine(-14.79635576556081, -11.77064279967296, -3.043616368139293, -11.46189011940212)
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_2.addLine(-3.043616368139293, -11.46189011940212, -3.922197168000547, 15.83568871823551)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(-3.922197168000547, 15.83568871823551, -15.11211565655763, 11.99814589971457)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchLine_8.endPoint())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_7")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("SOLID", "Torus_1_1"), model.selection("WIRE", "Wire_1_1")])
+model.do()
+
+model.checkBooleansResult(Partition_1,model,1,[3],[1],[4],[22],[46])
+model.testHaveNamingSubshapes(Partition_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 14.26163338647443, -11.82948087533604, 14.26163338647443, 11.82948087533609, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(14.26163338647443, -11.82948087533604, 14.26163338647443, 11.82948087533609)
+SketchLine_1.setAuxiliary(True)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchArc_1_2")])
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("EDGE", "PartSet/OY"), 200, 0)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "PartSet/XOZ"), model.selection("FACE", "Revolution_1_1")])
+Union_1 = model.addUnion(Part_1_doc, [model.selection("FACE", "Partition_1_1_1"), model.selection("FACE", "Partition_1_1_2")])
+model.do()
+
+model.checkBooleansResult(Union_1,model,1,[0],[0],[1],[4],[8])
+model.testHaveNamingSubshapes(Union_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-44.48110465116279, 12.33139534883721, -38.60901162790698, 48.15116279069767)
+SketchLine_2 = Sketch_1.addLine(-38.60901162790698, 48.15116279069767, 16.88226744186047, 78.68604651162791)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(16.88226744186047, 78.68604651162791, 48.29796511627906, 10.86337209302326)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(48.29796511627906, 10.86337209302326, 31.85610465116278, -38.16860465116279)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(31.85610465116278, -38.16860465116279, -44.48110465116279, 12.33139534883721)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_1.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r-SketchLine_5r"))
+SketchLine_6 = Sketch_2.addLine(31.85610465116278, -38.16860465116279, -40.43276493886778, -56.03425756438362)
+SketchProjection_1 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_5s-SketchLine_4e"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.startPoint(), SketchPoint_1.result())
+SketchLine_7 = Sketch_2.addLine(-40.43276493886778, -56.03425756438362, -115.5003601973775, -26.06900348999911)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_2.addLine(-115.5003601973775, -26.06900348999911, -106.2327558444751, 34.47934494896344)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_2.addLine(-106.2327558444751, 34.47934494896344, -44.48110465116279, 12.33139534883721)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_5e"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchPoint_2.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_7"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_8")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "PartSet/YOZ")])
+Union_1 = model.addUnion(Part_1_doc, [model.selection("FACE", "Partition_1_1_1"), model.selection("FACE", "Partition_1_1_3"), model.selection("FACE", "Partition_1_1_4")])
+model.do()
+
+model.checkBooleansResult(Union_1,model,1,[2],[0],[2],[13],[26])
+#model.testHaveNamingSubshapes(Union_1,model,Part_1_doc)
+
+model.end()
+
+assert(model.checkPythonDump())
label="Main objects"
icon=""
tooltip="Select objects"
- type_choice="solids compsolids edges faces"
+ type_choice="vertices edges wires faces shells solids compsolids"
use_choice="false"
concealment="true">
<validator id="PartSet_DifferentObjects"/>
label="Tool objects"
icon=""
tooltip="Select tools"
- type_choice="solids compsolids edges faces"
+ type_choice="vertices edges wires faces shells solids compsolids"
use_choice="false"
concealment="true" >
<validator id="PartSet_DifferentObjects"/>
--- /dev/null
+<!--
+Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+-->
+
+<source>
+ <toolbox id="creation_method">
+ <box id="fixed_radius"
+ title="Fixed radius"
+ tooltip="Fillet with fixed radius"
+ icon="icons/Features/fillet_fixed_radius.png">
+ <multi_selector id="main_objects"
+ label="Faces or/and edges"
+ icon=""
+ tooltip="Select objects"
+ type_choice="edges faces"
+ use_choice="false"
+ concealment="true">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+ </multi_selector>
+ <doublevalue id="radius1"
+ label="Radius"
+ tooltip="Fillet radius."
+ min="0"
+ default="2">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </box>
+ <box id="variable_radius"
+ title="Varying radius"
+ tooltip="Fillet with varying radius"
+ icon="icons/Features/fillet_var_radius.png">
+ <multi_selector id="main_objects"
+ label="Faces or/and edges"
+ icon=""
+ tooltip="Select objects"
+ type_choice="edges faces"
+ use_choice="false"
+ concealment="true">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+ </multi_selector>
+ <doublevalue id="radius1"
+ label="Start radius"
+ tooltip="Fillet radius at start point."
+ min="0"
+ default="2">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ <doublevalue id="radius2"
+ label="End radius"
+ tooltip="Fillet radius at end point."
+ min="0"
+ default="2">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </box>
+ </toolbox>
+</source>
<source path="recover_widget.xml"/>
</feature>
</group>
+ <group id="Fillet">
+ <feature id="Fillet" title="Fillet" tooltip="Perform fillet on face or edge" icon="icons/Features/fillet.png" auto_preview="true">
+ <source path="fillet_widget.xml"/>
+ </feature>
+ </group>
</workbench>
<workbench id="Part">
<group id="Movement">
<feature id="Symmetry" title="Symmetry" tooltip="Perform symmetry with respect to a point, an axis or a plane" icon="icons/Features/symmetry.png">
<source path="symmetry_widget.xml"/>
</feature>
- <feature id="MultiTranslation" title="MultiTranslation" tooltip="Perform multi-translation objects" icon="icons/Features/multitranslation.png">
+ <feature id="LinearCopy" title="Linear copy" tooltip="Perform copy and translate" icon="icons/Features/multitranslation.png">
<source path="multitranslation_widget.xml"/>
</feature>
- <feature id="MultiRotation" title="MultiRotation" tooltip="Perform multi-rotation objects" icon="icons/Features/multirotation.png">
+ <feature id="AngularCopy" title="Angular Copy" tooltip="Perform copy and rotate" icon="icons/Features/multirotation.png">
<source path="multirotation_widget.xml"/>
</feature>
</group>
#include <NCollection_Map.hxx>
#include <TopoDS_Shape.hxx>
-#define MY_MAP implPtr<NCollection_DataMap<TopoDS_Shape, NCollection_Map<TopoDS_Shape> > >()
+typedef NCollection_DataMap<TopoDS_Shape, NCollection_Map<TopoDS_Shape> > MAP;
+#define MY_MAP implPtr<MAP>()
//=================================================================================================
GeomAPI_DataMapOfShapeMapOfShapes::GeomAPI_DataMapOfShapeMapOfShapes()
{
return MY_MAP->Size();
}
+
+
+//=================================================================================================
+// iterator implementation
+//=================================================================================================
+
+class IteratorImpl : public GeomAPI_DataMapOfShapeMapOfShapes::iterator
+{
+public:
+ IteratorImpl() {}
+
+ IteratorImpl(const MAP::Iterator& theIterator)
+ : myIterator(theIterator)
+ {}
+
+ IteratorImpl(const std::shared_ptr<IteratorImpl>& theIterator)
+ {
+ mySelf = theIterator;
+ }
+
+ bool operator==(const std::shared_ptr<IteratorImpl>& theOther) const
+ {
+ if (theOther)
+ return theOther->myIterator.IsEqual(myIterator);
+
+ // theOther is end iterator => check the current iterator is not at the end
+ return !myIterator.More();
+ }
+
+ virtual iterator& operator++()
+ {
+ myIterator.Next();
+ return *this;
+ }
+ virtual iterator operator++(int)
+ {
+ std::shared_ptr<IteratorImpl> aSelf = std::dynamic_pointer_cast<IteratorImpl>(mySelf);
+ std::shared_ptr<IteratorImpl> aCopy(new IteratorImpl(aSelf->myIterator));
+ myIterator.Next();
+ return IteratorImpl(aCopy);
+ }
+
+ virtual key_type first() const
+ {
+ if (mySelf)
+ return iterator::first();
+
+ GeomShapePtr aShape(new GeomAPI_Shape);
+ aShape->setImpl(new TopoDS_Shape(myIterator.Key()));
+ return aShape;
+ }
+
+ virtual mapped_type second() const
+ {
+ if (mySelf)
+ return iterator::second();
+
+ ListOfShape anItems;
+ const NCollection_Map<TopoDS_Shape>& aMap = myIterator.Value();
+ for(NCollection_Map<TopoDS_Shape>::Iterator anIt(aMap); anIt.More(); anIt.Next()) {
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+ aShape->setImpl(new TopoDS_Shape(anIt.Value()));
+ anItems.push_back(aShape);
+ }
+ return anItems;
+ }
+
+private:
+ MAP::Iterator myIterator;
+};
+
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::iterator()
+{
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::iterator(
+ const GeomAPI_DataMapOfShapeMapOfShapes::iterator& theOther)
+ : mySelf(theOther.mySelf)
+{
+}
+
+const GeomAPI_DataMapOfShapeMapOfShapes::iterator&
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator=(
+ const GeomAPI_DataMapOfShapeMapOfShapes::iterator& theOther)
+{
+ mySelf = theOther.mySelf;
+ return *this;
+}
+
+bool GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator==(const iterator& theOther) const
+{
+ std::shared_ptr<IteratorImpl> aSelf = std::dynamic_pointer_cast<IteratorImpl>(mySelf);
+ std::shared_ptr<IteratorImpl> aSelfOther =
+ std::dynamic_pointer_cast<IteratorImpl>(theOther.mySelf);
+
+ return aSelf ? aSelf->operator==(aSelfOther)
+ : (aSelfOther ? aSelfOther->operator==(aSelf) : true);
+}
+
+bool GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator!=(const iterator& theOther) const
+{
+ return !operator==(theOther);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator&
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator++()
+{
+ mySelf->operator++();
+ return *this;
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator::operator++(int)
+{
+ return ++(*mySelf);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::key_type
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator::first() const
+{
+ return mySelf->first();
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator::mapped_type
+ GeomAPI_DataMapOfShapeMapOfShapes::iterator::second() const
+{
+ return mySelf->second();
+}
+
+
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator GeomAPI_DataMapOfShapeMapOfShapes::begin()
+{
+ MAP::Iterator anIt(*MY_MAP);
+ std::shared_ptr<IteratorImpl> anIter(new IteratorImpl(anIt));
+ return IteratorImpl(anIter);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::const_iterator GeomAPI_DataMapOfShapeMapOfShapes::begin() const
+{
+ MAP::Iterator anIt(*MY_MAP);
+ std::shared_ptr<IteratorImpl> anIter(new IteratorImpl(anIt));
+ return IteratorImpl(anIter);
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::iterator GeomAPI_DataMapOfShapeMapOfShapes::end()
+{
+ return IteratorImpl(std::shared_ptr<IteratorImpl>());
+}
+
+GeomAPI_DataMapOfShapeMapOfShapes::const_iterator GeomAPI_DataMapOfShapeMapOfShapes::end() const
+{
+ return IteratorImpl(std::shared_ptr<IteratorImpl>());
+}
/// \return size of map.
GEOMAPI_EXPORT int size() const;
+
+public:
+ class iterator
+ {
+ public:
+ typedef GeomShapePtr key_type;
+ typedef ListOfShape mapped_type;
+ typedef std::pair<GeomShapePtr, ListOfShape> value_type;
+
+ public:
+ GEOMAPI_EXPORT iterator();
+ GEOMAPI_EXPORT iterator(const iterator&);
+ GEOMAPI_EXPORT const iterator& operator=(const iterator&);
+
+ GEOMAPI_EXPORT bool operator==(const iterator&) const;
+ GEOMAPI_EXPORT bool operator!=(const iterator&) const;
+
+ GEOMAPI_EXPORT virtual iterator& operator++();
+ GEOMAPI_EXPORT virtual iterator operator++(int);
+
+ GEOMAPI_EXPORT virtual key_type first() const;
+ GEOMAPI_EXPORT virtual mapped_type second() const;
+
+ protected:
+ std::shared_ptr<iterator> mySelf;
+ };
+
+ typedef iterator const_iterator;
+
+ GEOMAPI_EXPORT iterator begin();
+ GEOMAPI_EXPORT const_iterator begin() const;
+
+ GEOMAPI_EXPORT iterator end();
+ GEOMAPI_EXPORT const_iterator end() const;
};
#endif
return !aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE;
}
+bool GeomAPI_Shape::isWire() const
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ return !aShape.IsNull() && aShape.ShapeType() == TopAbs_WIRE;
+}
+
bool GeomAPI_Shape::isFace() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
}
}
+void GeomAPI_Shape::reverse()
+{
+ MY_SHAPE->Reverse();
+}
+
bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape,
const bool theCheckOrientation) const
{
GEOMAPI_EXPORT
virtual bool isEdge() const;
+ /// Returns whether the shape is a wire
+ GEOMAPI_EXPORT
+ virtual bool isWire() const;
+
/// Returns whether the shape is a face
GEOMAPI_EXPORT
virtual bool isFace() const;
/// Sets the shape orientation.
GEOMAPI_EXPORT virtual void setOrientation(const Orientation theOrientation);
+ /// Reverse shape
+ GEOMAPI_EXPORT virtual void reverse();
+
/// \return true if passed shape is a sub-shape of this shape.
/// \param theShape shape to search.
/// \param theCheckOrientation if false, returns true even if orientation of shape differs
this->setImpl(aWire);
}
+
+//==================================================================================================
+GeomAPI_Wire::GeomAPI_Wire(const std::shared_ptr<GeomAPI_Shape>& theShape)
+{
+ if (!theShape->isNull() && theShape->isWire()) {
+ setImpl(new TopoDS_Shape(theShape->impl<TopoDS_Shape>()));
+ }
+}
public:
/// Makes an undefined Wire.
GEOMAPI_EXPORT GeomAPI_Wire();
+
+ /// Creation of wire by the wire-shape
+ GEOMAPI_EXPORT GeomAPI_Wire(const std::shared_ptr<GeomAPI_Shape>& theShape);
};
-#endif
+typedef std::shared_ptr<GeomAPI_Wire> GeomWirePtr;
+#endif
GeomAlgoAPI_Scale.h
GeomAlgoAPI_Circ2dBuilder.h
GeomAlgoAPI_UnifySameDomain.h
+ GeomAlgoAPI_Fillet.h
+ GeomAlgoAPI_SortListOfShapes.h
+ GeomAlgoAPI_Filling.h
)
SET(PROJECT_SOURCES
GeomAlgoAPI_Scale.cpp
GeomAlgoAPI_Circ2dBuilder.cpp
GeomAlgoAPI_UnifySameDomain.cpp
+ GeomAlgoAPI_Fillet.cpp
+ GeomAlgoAPI_SortListOfShapes.cpp
+ GeomAlgoAPI_Filling.cpp
)
SET(PROJECT_LIBRARIES
${CAS_TKBRep}
${CAS_TKCAF}
${CAS_TKCAF}
+ ${CAS_TKFillet}
${CAS_TKLCAF}
${CAS_TKPrim}
${CAS_TKSTEP}
%include "GeomAlgoAPI_ShapeAPI.h"
%include "GeomAlgoAPI_Copy.h"
%include "GeomAlgoAPI_Symmetry.h"
+%include "GeomAlgoAPI_Box.h"
%typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_Fillet.h"
+
+#include <BRepFilletAPI_MakeFillet.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theFilletRadius)
+{
+ build(theBaseSolid, theFilletEdges, theFilletRadius);
+}
+
+//=================================================================================================
+GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theStartRadius,
+ const double theEndRadius)
+{
+ if (theEndRadius < 0.)
+ return;
+ build(theBaseSolid, theFilletEdges, theStartRadius, theEndRadius);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Fillet::build(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theStartRadius,
+ const double theEndRadius)
+{
+ if (!theBaseSolid || theFilletEdges.empty() || theStartRadius < 0.)
+ return;
+
+ // create fillet builder
+ BRepFilletAPI_MakeFillet* aFilletBuilder =
+ new BRepFilletAPI_MakeFillet(theBaseSolid->impl<TopoDS_Shape>());
+ setImpl(aFilletBuilder);
+ setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+ // assign filleting edges
+ for (ListOfShape::const_iterator anIt = theFilletEdges.begin();
+ anIt != theFilletEdges.end(); ++anIt) {
+ if ((*anIt)->isEdge())
+ aFilletBuilder->Add( (*anIt)->impl<TopoDS_Edge>() );
+ }
+
+ // assign fillet radii for each contour of filleting edges
+ bool isFixedRadius = theEndRadius < 0.;
+ int aNbContours = aFilletBuilder->NbContours();
+ for (int ind = 1; ind <= aNbContours; ++ind) {
+ if (isFixedRadius)
+ aFilletBuilder->SetRadius(theStartRadius, ind, 1);
+ else
+ aFilletBuilder->SetRadius(theStartRadius, theEndRadius, ind, 1);
+ }
+
+ // build and get result
+ aFilletBuilder->Build();
+ if (!aFilletBuilder->IsDone())
+ return;
+ const TopoDS_Shape& aResult = aFilletBuilder->Shape();
+
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aResult));
+ setShape(aShape);
+ setDone(true);
+}
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_Fillet_H_
+#define GeomAlgoAPI_Fillet_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Fillet
+/// \ingroup DataAlgo
+/// \brief Perform fillet
+class GeomAlgoAPI_Fillet : public GeomAlgoAPI_MakeShape
+{
+public:
+ /// Run fillet operation with fixed radius.
+ /// \param theBaseSolid a changing solid
+ /// \param theFilletEdges list of edges the fillet is performed on
+ /// \param theFilletRadius radius of the fillet
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theFilletRadius);
+
+ /// Run fillet operation with variable radius.
+ /// \param theBaseSolid a changing solid
+ /// \param theFilletEdges list of edges the fillet is performed on
+ /// \param theStartRadius start radius of the fillet
+ /// \param theEndRadius end radius of the fillet
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theStartRadius,
+ const double theEndRadius);
+
+private:
+ /// Perform fillet operation.
+ /// If theEndRadius is less than 0., the fixed radius fillet will be built.
+ /// \param theBaseSolid a changing solid
+ /// \param theFilletEdges list of edges the fillet is performed on
+ /// \param theStartRadius start radius of the fillet
+ /// \param theEndRadius end radius of the fillet
+ void build(const GeomShapePtr& theBaseSolid,
+ const ListOfShape& theFilletEdges,
+ const double theStartRadius,
+ const double theEndRadius = -1.0);
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_Filling.h"
+
+#include <BRep_Tool.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomAPI_PointsToBSplineSurface.hxx>
+#include <GeomFill_AppSurf.hxx>
+#include <GeomFill_Line.hxx>
+#include <GeomFill_SectionGenerator.hxx>
+#include <Precision.hxx>
+#include <ShapeFix_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+
+static void edgesToCurves(const std::list<GeomEdgePtr>& theEdges,
+ std::list<Handle(Geom_Curve)>& theCurves)
+{
+ for (std::list<GeomEdgePtr>::const_iterator anIt = theEdges.begin();
+ anIt != theEdges.end(); ++anIt) {
+ const TopoDS_Edge& anEdge = (*anIt)->impl<TopoDS_Edge>();
+ if (BRep_Tool::Degenerated(anEdge))
+ continue;
+
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+
+ aCurve = new Geom_TrimmedCurve(aCurve, aFirst, aLast);
+ if (anEdge.Orientation() == TopAbs_REVERSED)
+ aCurve->Reverse();
+
+ theCurves.push_back(aCurve);
+ }
+}
+
+
+GeomAlgoAPI_Filling::GeomAlgoAPI_Filling(const int theMinDegree,
+ const int theMaxDegree,
+ const int theNbIter,
+ const double theTol2D,
+ const double theTol3D)
+ : myMinDegree(theMinDegree),
+ myMaxDegree(theMaxDegree),
+ myNbIter(theNbIter),
+ myTol2D(theTol2D),
+ myTol3D(theTol3D)
+{
+}
+
+void GeomAlgoAPI_Filling::add(const GeomEdgePtr theEdge)
+{
+ myConstraints.push_back(theEdge);
+}
+
+void GeomAlgoAPI_Filling::build(bool isApproximate)
+{
+ if (myConstraints.size() <= 1) // not enough edges
+ return;
+
+ if (isApproximate)
+ buildByControlPoints();
+ else
+ buildByEdges();
+}
+
+void GeomAlgoAPI_Filling::buildByEdges()
+{
+ GeomFill_SectionGenerator aSection;
+
+ // obtain section curves
+ std::list<Handle(Geom_Curve)> aCurves;
+ edgesToCurves(myConstraints, aCurves);
+ for (std::list<Handle(Geom_Curve)>::iterator anIt = aCurves.begin();
+ anIt != aCurves.end(); ++anIt)
+ aSection.AddCurve(*anIt);
+
+ // a 'tolerance' is used to compare 2 knots
+ aSection.Perform(Precision::PConfusion());
+ Handle(GeomFill_Line) aLine = new GeomFill_Line((int)aCurves.size());
+
+ // perform filling by sections
+ GeomFill_AppSurf anAppSurf(myMinDegree, myMaxDegree, myTol3D, myTol2D, myNbIter);
+ anAppSurf.Perform(aLine, aSection);
+ if (!anAppSurf.IsDone())
+ return;
+
+ // build calculated surface
+ Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots;
+ anAppSurf.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
+ Handle(Geom_BSplineSurface) GBS = new Geom_BSplineSurface(
+ anAppSurf.SurfPoles(), anAppSurf.SurfWeights(), anAppSurf.SurfUKnots(), anAppSurf.SurfVKnots(),
+ anAppSurf.SurfUMults(), anAppSurf.SurfVMults(), anAppSurf.UDegree(), anAppSurf.VDegree());
+
+ if (GBS.IsNull())
+ return;
+
+ // store result
+ TopoDS_Face aFace = BRepBuilderAPI_MakeFace(GBS, Precision::Confusion());
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aFace));
+ setShape(aShape);
+ setDone(true);
+}
+
+static Handle(Geom_Curve) removeTrim(const Handle(Geom_Curve)& theCurve)
+{
+ Handle(Geom_Curve) aCurve = theCurve;
+ Handle(Geom_TrimmedCurve) aTC = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+ while (!aTC.IsNull()) {
+ aCurve = aTC->BasisCurve();
+ aTC = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+ }
+ return aCurve;
+}
+
+void GeomAlgoAPI_Filling::buildByControlPoints()
+{
+ // obtain section curves
+ std::list<Handle(Geom_Curve)> aCurves;
+ edgesToCurves(myConstraints, aCurves);
+
+ // compute maximal number of poles in B-spline curves
+ int aMaxPoles = 0;
+ std::list<Handle(Geom_Curve)>::iterator anIt = aCurves.begin();
+ for (; anIt != aCurves.end(); ++anIt) {
+ Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(removeTrim(*anIt));
+ if (!aBC.IsNull())
+ aMaxPoles = Max(aMaxPoles, aBC->NbPoles());
+ }
+
+ // prepare array of points for creation bspline surface
+ // size of this array: by U parameter - number of curves,
+ // by V parameter - determ using MaxNbPoles but it's
+ // value must be between 21(min) and 101(max)
+ int aNbSections = (int) aCurves.size();
+ int aNbPntInSection = Max(21, 2 * aMaxPoles - 1);
+ TColgp_Array2OfPnt aPoints(1, aNbSections, 1, aNbPntInSection);
+ anIt = aCurves.begin();
+ for (int i = 1; anIt != aCurves.end(); ++i, ++anIt) {
+ Handle(Geom_Curve) aC = *anIt;
+ double fp = aC->FirstParameter();
+ double lp = aC->LastParameter();
+ double dp = (lp - fp) / (aNbPntInSection - 1);
+
+ gp_Pnt aPnt;
+ for (int j = 0; j < aNbPntInSection; j++) {
+ aC->D0(fp + dp * j, aPnt);
+ aPoints.SetValue(i, j+1, aPnt);
+ }
+ }
+
+ // convert a grid of points to B-spline surface
+ GeomAPI_PointsToBSplineSurface aPTB(aPoints, myMinDegree, myMaxDegree, GeomAbs_C2, myTol3D);
+ Handle(Geom_BSplineSurface) aBS = aPTB.Surface();
+ if (aBS.IsNull())
+ return;
+
+ // fix face orientation
+ TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aBS, Precision::Confusion());
+ Handle(ShapeFix_Face) aFix = new ShapeFix_Face(aFace);
+ aFix->Perform();
+ aFix->FixOrientation();
+ aFace = aFix->Face();
+
+ // store result
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aFace));
+ setShape(aShape);
+ setDone(true);
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_Filling_H_
+#define GeomAlgoAPI_Filling_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Edge.h>
+
+/// \class GeomAlgoAPI_Filling
+/// \ingroup DataAlgo
+/// \brief Perform building face by the set of edges/wires
+class GeomAlgoAPI_Filling : public GeomAlgoAPI_MakeShape
+{
+public:
+ /// \brief Construct filling operation by the parameters.
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Filling(const int theMinDegree = 2,
+ const int theMaxDegree = 5,
+ const int theNbIter = 0,
+ const double theTol2D = 1.e-4,
+ const double theTol3D = 1.e-4);
+
+ /// \brief Add an edge to constrain filling (the result face should pass through the edge)
+ GEOMALGOAPI_EXPORT void add(const GeomEdgePtr theEdge);
+
+ /// \brief Perform filling operation
+ /// \param isApproximate approximate curves before building a face
+ GEOMALGOAPI_EXPORT void build(bool isApproximate = false);
+
+private:
+ /// \brief Perform filling using the given edges
+ void buildByEdges();
+
+ /// \brief Perform filling by a set of points calculated on each edge
+ void buildByControlPoints();
+
+private:
+ int myMinDegree;
+ int myMaxDegree;
+ int myNbIter;
+ double myTol2D;
+ double myTol3D;
+ std::list<GeomEdgePtr> myConstraints;
+};
+
+#endif
#ifdef USE_OCCT_720
aVolumeMaker->SetAvoidInternalShapes(true);
#endif
- aVolumeMaker->SetGlue(BOPAlgo_GlueShift);
+ aVolumeMaker->SetGlue(BOPAlgo_GlueOff);
// building and getting result
aVolumeMaker->Perform();
void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape,
const bool theIsMakeCompSolids)
{
- BOPAlgo_PaveFiller aPaveFiller;
+ BOPAlgo_PaveFiller* aPaveFiller = new BOPAlgo_PaveFiller;
BOPCol_ListOfShape aListOfShape;
for(ListOfShape::const_iterator
anIt = theListOfShape.cbegin(); anIt != theListOfShape.cend(); anIt++) {
aListOfShape.Append(aShape);
}
}
- aPaveFiller.SetArguments(aListOfShape);
- aPaveFiller.Perform();
+ aPaveFiller->SetArguments(aListOfShape);
+ aPaveFiller->Perform();
#ifdef USE_OCCT_720
- if (aPaveFiller.HasErrors())
+ if (aPaveFiller->HasErrors())
return;
#else
- Standard_Integer iErr = aPaveFiller.ErrorStatus();
+ Standard_Integer iErr = aPaveFiller->ErrorStatus();
if(iErr) {
return;
}
this->setImpl(aBuilder);
this->setBuilderType(OCCT_BOPAlgo_Builder);
aBuilder->SetArguments(aListOfShape);
- aBuilder->PerformWithFiller(aPaveFiller);
+ aBuilder->PerformWithFiller(*aPaveFiller);
#ifdef USE_OCCT_720
if (aBuilder->HasErrors())
return;
GeomShapePtr aBasePlane;
const bool isBoundingShapesSet = theFromShape.get() || theToShape.get();
BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
- if(theDirection.get()) {
+ if ((aBaseShape.ShapeType() == TopAbs_VERTEX || aBaseShape.ShapeType() == TopAbs_EDGE)
+ && theDirection.get())
+ {
aBaseDir = theDirection;
aDirVec = theDirection->impl<gp_Dir>();
} else {
- if(aBaseShape.ShapeType() == TopAbs_VERTEX
- || aBaseShape.ShapeType() == TopAbs_EDGE
- || aFindPlane.Found() == Standard_False) {
+ if(aFindPlane.Found() == Standard_False) {
return;
}
#include <GeomAPI_Face.h>
#include <GeomAPI_Pln.h>
#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Wire.h>
#include <Bnd_Box.hxx>
#include <BOPTools.hxx>
#include <BRep_Builder.hxx>
#include <BRepAdaptor_Curve.hxx>
+#include <BRepAlgo.hxx>
#include <BRepAlgo_FaceRestrictor.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_FindPlane.hxx>
aCentreOfMassPoint.Z()-aPoint.Z()));
return aDir;
}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
+ const std::shared_ptr<GeomAPI_Wire>& theWire)
+{
+ GeomEdgePtr anEdge;
+ if (theWire) {
+ const TopoDS_Wire& aWire = theWire->impl<TopoDS_Wire>();
+ TopoDS_Edge aNewEdge = BRepAlgo::ConcatenateWireC0(aWire);
+ anEdge = GeomEdgePtr(new GeomAPI_Edge);
+ anEdge->setImpl(new TopoDS_Edge(aNewEdge));
+ }
+ return anEdge;
+}
class GeomAPI_PlanarEdges;
class GeomAPI_Pln;
class GeomAPI_Pnt;
+class GeomAPI_Wire;
class GeomDataAPI_Point2D;
class ModelAPI_Object;
GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Dir> buildDirFromAxisAndShape(
const std::shared_ptr<GeomAPI_Shape> theBaseShape,
const std::shared_ptr<GeomAPI_Ax1> theAxis);
+
+ /// \brief Reapproximate a wire to build a single edge
+ GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Edge> wireToEdge(
+ const std::shared_ptr<GeomAPI_Wire>& theWire);
};
#endif
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_SortListOfShapes.h"
+
+#include <Bnd_Box.hxx>
+#include <Bnd_Box2d.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepTools.hxx>
+#include <gp_Pnt.hxx>
+#include <Precision.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+
+#include <algorithm>
+#include <map>
+
+class CompareShapes
+{
+ std::map<TopoDS_TShape*, Bnd_Box> myShapes;
+ std::map<TopoDS_TShape*, Bnd_Box2d> myUVBounds;
+
+ bool compareEdges(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS)
+ {
+ const TopoDS_Edge& aLHSEdge = TopoDS::Edge(theLHS->impl<TopoDS_Shape>());
+ const TopoDS_Edge& aRHSEdge = TopoDS::Edge(theRHS->impl<TopoDS_Shape>());
+
+ double aLF, aLE, aRF, aRE;
+ Handle(Geom_Curve) aLHSCurve = BRep_Tool::Curve(aLHSEdge, aLF, aLE);
+ Handle(Geom_Curve) aRHSCurve = BRep_Tool::Curve(aRHSEdge, aRF, aRE);
+
+ if (aLHSCurve == aRHSCurve) {
+ // compare by first parameter
+ if (isLessWithTol(aLF, aRF, Precision::PConfusion()))
+ return true;
+ else if (isLessWithTol(aRF, aLF, Precision::PConfusion()))
+ return false;
+ // compare by last parameter
+ return isLessWithTol(aLE, aRE, Precision::PConfusion());
+ }
+ // different underlying curves => compare bounding boxe
+ return compareByBoundingBox(theLHS, theRHS);
+ }
+
+ bool compareFaces(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS)
+ {
+ const TopoDS_Face& aLHSFace = TopoDS::Face(theLHS->impl<TopoDS_Shape>());
+ const TopoDS_Face& aRHSFace = TopoDS::Face(theRHS->impl<TopoDS_Shape>());
+
+ Handle(Geom_Surface) aLHSSurf = BRep_Tool::Surface(aLHSFace);
+ Handle(Geom_Surface) aRHSSurf = BRep_Tool::Surface(aRHSFace);
+
+ if (aLHSSurf == aRHSSurf) {
+ // compare parametric space for faces on the same surface
+ Bnd_Box2d aLHSBox = boundingBoxUV(aLHSFace);
+ Bnd_Box2d aRHSBox = boundingBoxUV(aRHSFace);
+
+ double aLHSBB[4], aRHSBB[4];
+ aLHSBox.Get(aLHSBB[0], aLHSBB[1], aLHSBB[2], aLHSBB[3]);
+ aRHSBox.Get(aRHSBB[0], aRHSBB[1], aRHSBB[2], aRHSBB[3]);
+ for (int anIndex = 0; anIndex < 4; ++anIndex) {
+ if (isLessWithTol(aLHSBB[anIndex], aRHSBB[anIndex], Precision::PConfusion()))
+ return true;
+ else if (isLessWithTol(aRHSBB[anIndex], aLHSBB[anIndex], Precision::PConfusion()))
+ return false;
+ }
+ // equal parametric boxes
+ return false;
+ }
+ // different underlying surfaces => compare bounding boxes
+ return compareByBoundingBox(theLHS, theRHS);
+ }
+
+ bool compareByBoundingBox(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS)
+ {
+ Bnd_Box aLHSBox = boundingBox(theLHS);
+ Bnd_Box aRHSBox = boundingBox(theRHS);
+
+ gp_Pnt aLHSMin = aLHSBox.CornerMin();
+ gp_Pnt aLHSMax = aLHSBox.CornerMax();
+
+ gp_Pnt aRHSMin = aRHSBox.CornerMin();
+ gp_Pnt aRHSMax = aRHSBox.CornerMax();
+
+ if (isLess(aLHSMin, aRHSMin))
+ return true;
+ else if (isLess(aRHSMin, aLHSMin))
+ return false;
+
+ return isLess(aLHSMax, aRHSMax);
+ }
+
+ bool isLessWithTol(const double theLHS, const double theRHS, const double theTolerance)
+ {
+ return theLHS + theTolerance < theRHS;
+ }
+
+ bool isLess(const gp_Pnt& theLHS, const gp_Pnt& theRHS)
+ {
+ for (int anIndex = 1; anIndex <= 3; ++anIndex) {
+ if (isLessWithTol(theLHS.Coord(anIndex), theRHS.Coord(anIndex), Precision::Confusion()))
+ return true;
+ else if (isLessWithTol(theRHS.Coord(anIndex), theLHS.Coord(anIndex), Precision::Confusion()))
+ return false;
+ }
+ // equal points
+ return false;
+ }
+
+ Bnd_Box boundingBox(const GeomShapePtr& theShape)
+ {
+ const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+ TopoDS_TShape* aS = aShape.TShape().get();
+ std::map<TopoDS_TShape*, Bnd_Box>::iterator aFound = myShapes.find(aS);
+ if (aFound == myShapes.end()) {
+ Bnd_Box aBB;
+ BRepBndLib::Add(aShape, aBB);
+ myShapes[aS] = aBB;
+ aFound = myShapes.find(aS);
+ }
+ return aFound->second;
+ }
+
+ Bnd_Box2d boundingBoxUV(const TopoDS_Face& theFace)
+ {
+ TopoDS_TShape* aFacePtr = theFace.TShape().get();
+ std::map<TopoDS_TShape*, Bnd_Box2d>::iterator aFound = myUVBounds.find(aFacePtr);
+ if (aFound == myUVBounds.end()) {
+ Bnd_Box2d aBB;
+ BRepTools::AddUVBounds(theFace, aBB);
+ myUVBounds[aFacePtr] = aBB;
+ aFound = myUVBounds.find(aFacePtr);
+ }
+ return aFound->second;
+ }
+
+public:
+ // Verify theLHS is less than theRHS
+ bool operator() (const GeomShapePtr& theLHS, const GeomShapePtr& theRHS)
+ {
+ if (theLHS->shapeType() == theRHS->shapeType()) {
+ // edges and faces are compared by geometric properties
+ if (theLHS->shapeType() == GeomAPI_Shape::EDGE)
+ return compareEdges(theLHS, theRHS);
+ else if (theLHS->shapeType() == GeomAPI_Shape::FACE)
+ return compareFaces(theLHS, theRHS);
+ // all other comparisons are made by bounding boxes
+ return compareByBoundingBox(theLHS, theRHS);
+ }
+
+ // shapes of different types are compared by the type
+ return theLHS->shapeType() < theRHS->shapeType();
+ }
+};
+
+
+void GeomAlgoAPI_SortListOfShapes::sort(ListOfShape& theShapes)
+{
+ CompareShapes aComparator;
+ theShapes.sort(aComparator);
+}
--- /dev/null
+// Copyright (C) 2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_SortListOfShapes_H_
+#define GeomAlgoAPI_SortListOfShapes_H_
+
+#include "GeomAlgoAPI.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_SortListOfShapes
+/// \ingroup DataAlgo
+/// \brief Performs sorting of shapes according to geometric properties.
+class GeomAlgoAPI_SortListOfShapes
+{
+ public:
+ /// \brief Sorts list of shapes in accordance with their geometric properties.
+ /// \param[in/out] theShapes list of shapes.
+ GEOMALGOAPI_EXPORT static void sort(ListOfShape& theShapes);
+};
+
+#endif
GeomValidators_Different.h
GeomValidators_IntersectionSelection.h
GeomValidators_MinObjectsSelected.h
+ GeomValidators_ValueOrder.h
)
SET(PROJECT_SOURCES
GeomValidators_Different.cpp
GeomValidators_IntersectionSelection.cpp
GeomValidators_MinObjectsSelected.cpp
+ GeomValidators_ValueOrder.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomValidators_ValueOrder.h"
+
+#include <Config_PropManager.h>
+#include <Events_InfoMessage.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+static double attributeValue(AttributePtr theAttr)
+{
+ AttributeIntegerPtr anIntAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttr);
+ if (anIntAttr)
+ return (double)anIntAttr->value();
+ AttributeDoublePtr aDoubleAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
+ if (aDoubleAttr)
+ return aDoubleAttr->value();
+ return 0.0;
+}
+
+static bool isGreaterOrEqual(AttributePtr theFirstArg, AttributePtr theSecondArg)
+{
+ if (theFirstArg && theFirstArg->isInitialized() &&
+ theSecondArg && theSecondArg->isInitialized())
+ return attributeValue(theFirstArg) >= attributeValue(theSecondArg);
+ return false;
+}
+
+static bool isLessOrEqual(AttributePtr theFirstArg, AttributePtr theSecondArg)
+{
+ if (theFirstArg && theFirstArg->isInitialized() &&
+ theSecondArg && theSecondArg->isInitialized())
+ return attributeValue(theFirstArg) <= attributeValue(theSecondArg);
+ return false;
+}
+
+// Check the attributes are satisfy theCompare function
+static bool isValidOrder(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError,
+ bool (*theCompare)(AttributePtr, AttributePtr))
+{
+ std::string anAttrType = theAttribute->attributeType();
+ if (anAttrType != ModelAPI_AttributeDouble::typeId() &&
+ anAttrType != ModelAPI_AttributeInteger::typeId()) {
+ theError = "Unsupported attribute type (integer or double applicable)";
+ return false;
+ }
+
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
+ if (!anOwner) {
+ theError = "Attribute without owner";
+ return false;
+ }
+
+ for (std::list<std::string>::const_iterator anIt = theArguments.begin();
+ anIt != theArguments.end(); ++anIt) {
+ // check the argument links to the attribute of the current feature
+ AttributePtr aCurAttr = anOwner->attribute(*anIt);
+ if (!aCurAttr) {
+ theError = "Arguments should be names of attributes of current feature";
+ return false;
+ }
+
+ // compare values
+ if (!(*theCompare)(theAttribute, aCurAttr)) {
+ theError = "Attributes have incorrect order";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+/// Global instance for validators factory
+GeomValidators_GreaterOrEqual MY_GEQ_INSTANCE;
+GeomValidators_LessOrEqual MY_LEQ_INSTANCE;
+
+GeomValidators_GreaterOrEqual::GeomValidators_GreaterOrEqual()
+{
+ // this validator is registered in the factory on this library loading
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+ aFactory->registerValidator("GeomValidators_GreaterOrEqual", this);
+}
+
+bool GeomValidators_GreaterOrEqual::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ return isValidOrder(theAttribute, theArguments, theError, &isGreaterOrEqual);
+}
+
+
+
+GeomValidators_LessOrEqual::GeomValidators_LessOrEqual()
+{
+ // this validator is registered in the factory on this library loading
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+ aFactory->registerValidator("GeomValidators_LessOrEqual", this);
+}
+
+bool GeomValidators_LessOrEqual::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ return isValidOrder(theAttribute, theArguments, theError, &isLessOrEqual);
+}
--- /dev/null
+// Copyright (C) 2017-20xx 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomValidators_ValueOrder_H
+#define GeomValidators_ValueOrder_H
+
+#include <GeomValidators.h>
+#include <ModelAPI_AttributeValidator.h>
+
+/**
+ * Validates that the integer/double attribute is greater or equal to another attribute values
+ */
+class GeomValidators_GreaterOrEqual : public ModelAPI_AttributeValidator
+{
+public:
+ //! Constructor for only one instance per application: will register the validator
+ GeomValidators_GreaterOrEqual();
+ //! returns true if attribute is valid
+ //! \param[in] theAttribute the checked attribute
+ //! \param[in] theArguments arguments of the attribute
+ //! \param[out] theError error message.
+ GEOMVALIDATORS_EXPORT virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+};
+
+/**
+ * Validates that the integer/double attribute is less or equal to another attribute values
+ */
+class GeomValidators_LessOrEqual : public ModelAPI_AttributeValidator
+{
+public:
+ //! Constructor for only one instance per application: will register the validator
+ GeomValidators_LessOrEqual();
+ //! returns true if attribute is valid
+ //! \param[in] theAttribute the checked attribute
+ //! \param[in] theArguments arguments of the attribute
+ //! \param[out] theError error message.
+ GEOMVALIDATORS_EXPORT virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+
+};
+
+#endif
#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
#include <Events_InfoMessage.h>
#include <GeomAPI_Edge.h>
#include <GeomAPI_Vertex.h>
bool isFound = false;
TopExp_Explorer anExp(aNewContext, aNewSub.ShapeType());
for(; anExp.More(); anExp.Next()) {
- if (anExp.Current().IsEqual(aNewSub)) {
+ if (anExp.Current().IsSame(aNewSub)) {
isFound = true;
break;
}
}
}
}
+ // if compsolid is context, try to take sub-solid as context: like in GUI and scripts
+ if (aCont.get() && aShapeToBeSelected.get()) {
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aCont);
+ if (aComp && aComp->numberOfSubs()) {
+ for(int aSubNum = 0; aSubNum < aComp->numberOfSubs(); aSubNum++) {
+ ResultPtr aSub = aComp->subResult(aSubNum);
+ if (aSub && aSub->shape().get() && aSub->shape()->isSubShape(aShapeToBeSelected)) {
+ aCont = aSub;
+ break;
+ }
+ }
+ }
+ }
+ // try to find the latest active result that must be used instead of the selected
+ // to set the active context (like in GUI selection), not concealed one
+ bool aFindNewContext = true;
+ while(aFindNewContext && aCont.get() && aShapeToBeSelected.get()) {
+ aFindNewContext = false;
+ const std::set<AttributePtr>& aRefs = aCont->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
+ for(; !aFindNewContext && aRef != aRefs.end(); aRef++) {
+ if (!aRef->get() || !(*aRef)->owner().get())
+ continue;
+ // concealed attribute only
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (!ModelAPI_Session::get()->validators()->isConcealed(
+ aRefFeat->getKind(), (*aRef)->id()))
+ continue;
+ // search the feature result that contains sub-shape selected
+ std::list<std::shared_ptr<ModelAPI_Result> > aResults;
+
+ // take all sub-results or one result
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aFResults = aRefFeat->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aFResults.begin();
+ for (; aRIter != aFResults.cend(); aRIter++) {
+ // iterate sub-bodies of compsolid
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aRIter);
+ if (aComp.get() && aComp->numberOfSubs() > 0) {
+ int aNumSub = aComp->numberOfSubs();
+ for(int a = 0; a < aNumSub; a++) {
+ aResults.push_back(aComp->subResult(a));
+ }
+ } else {
+ aResults.push_back(*aRIter);
+ }
+ }
+ std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = aResults.begin();
+ for(; aResIter != aResults.end(); aResIter++) {
+ if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled())
+ continue;
+ GeomShapePtr aShape = (*aResIter)->shape();
+ if (aShape.get() && aShape->isSubShape(aShapeToBeSelected, false)) {
+ aCont = *aResIter; // found new context (produced from this) with same subshape
+ //if (!aShape->isSubShape(aShapeToBeSelected, true)) // take context orientation
+ // aShapeToBeSelected->setOrientation();
+ aFindNewContext = true; // continue searching futher
+ break;
+ }
+ }
+ }
+ }
+
if (aCenterType != NOT_CENTER) {
if (!aShapeToBeSelected->isEdge())
continue;
{
std::set<ResultPtr> aResults; // to avoid duplicates, new context, null if deleted
TopTools_ListOfShape aResContShapes;
- TNaming_SameShapeIterator aModifIter(theContShape, theAccessLabel);
- for(; aModifIter.More(); aModifIter.Next()) {
- TDF_Label anObjLab = aModifIter.Label().Father();
- ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
- (theDoc->objects()->object(anObjLab));
- if (!aModifierObj.get()) {
- // #2241: shape may be sub-element of new object, not main (shell created from faces)
- if (!anObjLab.IsRoot())
- aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
- (theDoc->objects()->object(anObjLab.Father()));
- if (!aModifierObj.get())
+ // iterate context and shape, but also if it is sub-shape of main shape, check also it
+ TopTools_ListOfShape aContextList;
+ aContextList.Append(theContShape);
+ if (theContext.get()) {
+ ResultPtr aComposite = ModelAPI_Tools::compSolidOwner(theContext);
+ if (aComposite.get() && aComposite->shape().get() && !aComposite->shape()->isNull())
+ aContextList.Append(aComposite->shape()->impl<TopoDS_Shape>());
+ }
+ for(TopTools_ListOfShape::Iterator aContIter(aContextList); aContIter.More(); aContIter.Next()) {
+ TNaming_SameShapeIterator aModifIter(aContIter.ChangeValue(), theAccessLabel);
+ for(; aModifIter.More(); aModifIter.Next()) {
+ TDF_Label anObjLab = aModifIter.Label().Father();
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (theDoc->objects()->object(anObjLab));
+ if (!aModifierObj.get()) {
+ // #2241: shape may be sub-element of new object, not main (shell created from faces)
+ if (!anObjLab.IsRoot())
+ aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (theDoc->objects()->object(anObjLab.Father()));
+ if (!aModifierObj.get())
+ continue;
+ }
+ FeaturePtr aModifierFeat = theDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
continue;
- }
- FeaturePtr aModifierFeat = theDoc->feature(aModifierObj);
- if (!aModifierFeat.get())
- continue;
- FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
- if (aModifierFeat == aThisFeature || theDoc->objects()->isLater(aModifierFeat, aThisFeature))
- continue; // the modifier feature is later than this, so, should not be used
- FeaturePtr aCurrentModifierFeat = theDoc->feature(theContext);
- if (aCurrentModifierFeat == aModifierFeat ||
- theDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
- continue; // the current modifier is later than the found, so, useless
- Handle(TNaming_NamedShape) aNewNS;
- aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
- if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
- aResults.insert(aModifierObj);
- //TNaming_Iterator aPairIter(aNewNS);
- //aResContShapes.Append(aPairIter.NewShape());
- aResContShapes.Append(aModifierObj->shape()->impl<TopoDS_Shape>());
- } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty
- aResults.insert(ResultPtr());
- } else { // not-precessed modification => don't support it
- continue;
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ if (aModifierFeat == aThisFeature || theDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ continue; // the modifier feature is later than this, so, should not be used
+ FeaturePtr aCurrentModifierFeat = theDoc->feature(theContext);
+ if (aCurrentModifierFeat == aModifierFeat ||
+ theDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
+ continue; // the current modifier is later than the found, so, useless
+ Handle(TNaming_NamedShape) aNewNS;
+ aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aResults.insert(aModifierObj);
+ //TNaming_Iterator aPairIter(aNewNS);
+ //aResContShapes.Append(aPairIter.NewShape());
+ aResContShapes.Append(aModifierObj->shape()->impl<TopoDS_Shape>());
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty
+ aResults.insert(ResultPtr());
+ } else { // not-precessed modification => don't support it
+ continue;
+ }
}
}
if (aResults.empty())
#include <BRep_Tool.hxx>
#include <GeomAPI_Shape.h>
#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_SortListOfShapes.h>
#include <Config_PropManager.h>
// DEB
//#include <TCollection_AsciiString.hxx>
std::map<int, TNaming_Builder*>::iterator aFind = myBuilders.find(theTag);
if (aFind == myBuilders.end()) {
std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
- myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag));
+ myBuilders[theTag] = new TNaming_Builder(
+ theTag == 0 ? aData->shapeLab() : aData->shapeLab().FindChild(theTag));
aFind = myBuilders.find(theTag);
}
return aFind->second;
}
}
+// Keep only the shapes with minimal shape type
+static void keepTopLevelShapes(ListOfShape& theShapes, const TopoDS_Shape& theRoot,
+ const GeomShapePtr& theResultShape = GeomShapePtr())
+{
+ GeomAPI_Shape::ShapeType aKeepShapeType = GeomAPI_Shape::SHAPE;
+ ListOfShape::iterator anIt = theShapes.begin();
+ while (anIt != theShapes.end()) {
+ TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();
+ if (theRoot.IsSame(aNewShape) || (theResultShape &&
+ (!theResultShape->isSubShape(*anIt, false) || theResultShape->isSame(*anIt)))) {
+ ListOfShape::iterator aRemoveIt = anIt++;
+ theShapes.erase(aRemoveIt);
+ } else {
+ GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType();
+ if (aType < aKeepShapeType) {
+ // found a shape with lesser shape type => remove all previous shapes
+ aKeepShapeType = aType;
+ theShapes.erase(theShapes.begin(), anIt);
+ ++anIt;
+ } else if (aType > aKeepShapeType) {
+ // shapes with greater shape type should be removed from the list
+ ListOfShape::iterator aRemoveIt = anIt++;
+ theShapes.erase(aRemoveIt);
+ } else
+ ++anIt;
+ }
+ }
+}
+
void Model_BodyBuilder::loadAndOrientModifiedShapes (
GeomAlgoAPI_MakeShape* theMS,
std::shared_ptr<GeomAPI_Shape> theShapeIn,
const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
if (!aView.Add(aRoot)) continue;
if (TNaming_Tool::NamedShape(aRoot, builder(theTag)->NamedShape()->Label()).IsNull())
- continue; // there is no sence to write history is old shape does not persented in document
+ continue; // there is no sense to write history if old shape does not exist in the document
ListOfShape aList;
std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
aRShape->setImpl((new TopoDS_Shape(aRoot)));
theMS->modified(aRShape, aList);
+ if (!theIsStoreSeparate)
+ keepTopLevelShapes(aList, aRoot, aResultShape);
+ // sort the list of images before naming
+ GeomAlgoAPI_SortListOfShapes::sort(aList);
+
+ // to trace situation where several objects are produced by one parent (#2317)
+ int aSameParentShapes = -1;
std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator
anIt = aList.begin(), aLast = aList.end();
for (; anIt != aLast; anIt++) {
}
GeomShapePtr aGeomNewShape(new GeomAPI_Shape());
aGeomNewShape->setImpl(new TopoDS_Shape(aNewShape));
- if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(aGeomNewShape, false)) {
+ if(!aRoot.IsSame(aNewShape) && aResultShape->isSubShape(aGeomNewShape, false) &&
+ !aResultShape->isSame(*anIt)) { // to avoid put of same shape on main label and sub
+ int aBuilderTag = aTag;
+ if (!theIsStoreSeparate)
+ aSameParentShapes++;
+
+ static const int THE_ANCHOR_TAG = 100000;
+ int aCurShapeType = (int)((*anIt)->shapeType());
+ bool needSuffix = false; // suffix for the name based on the shape type
+ if (aSameParentShapes > 0) { // store in other label
+ aBuilderTag = THE_ANCHOR_TAG - aSameParentShapes * 10 - aCurShapeType;
+ needSuffix = true;
+ } else if (aCurShapeType != theKindOfShape) {
+ // modified shape has different type => set another tag
+ // to avoid shapes of different types on the same label
+ aBuilderTag = THE_ANCHOR_TAG - aCurShapeType;
+ needSuffix = true;
+ }
+ std::string aSuffix;
+ if (needSuffix) {
+ switch (aCurShapeType) {
+ case GeomAPI_Shape::VERTEX: aSuffix = "_v"; break;
+ case GeomAPI_Shape::EDGE: aSuffix = "_e"; break;
+ case GeomAPI_Shape::FACE: aSuffix = "_f"; break;
+ default: break;
+ }
+ }
+
if(theIsStoreAsGenerated) {
// Here we store shapes as generated, to avoid problem when one parent shape produce
// several child shapes. In this case naming could not determine which shape to select.
- builder(aTag)->Generated(aRoot,aNewShape);
+ builder(aBuilderTag)->Generated(aRoot, aNewShape);
} else {
- builder(aTag)->Modify(aRoot,aNewShape);
+ builder(aBuilderTag)->Modify(aRoot, aNewShape);
}
if(isBuilt) {
- if(theIsStoreSeparate) {
+ aStream.str(std::string());
+ aStream.clear();
+ aStream << theName;
+ if(theIsStoreSeparate)
+ aStream << "_" << anIndex++;
+
+ if (aSameParentShapes > 0) {
aStream.str(std::string());
aStream.clear();
- aStream << theName << "_" << anIndex++;
- aName = aStream.str();
+ aStream << aName << "_" << aSameParentShapes << "divided";
}
- buildName(aTag, aName);
+
+ aStream << aSuffix;
+ buildName(aBuilderTag, aStream.str());
}
if(theIsStoreSeparate) {
aTag++;
}
+ } else if (aResultShape->isSame(*anIt)) {
+ // keep the modification evolution on the root level (2241 - history propagation issue)
+ if(theIsStoreAsGenerated) {
+ builder(0)->Generated(aRoot, aNewShape);
+ } else {
+ builder(0)->Modify(aRoot, aNewShape);
+ }
}
}
}
for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
if (!aView.Add(aRoot)) continue;
- if (TNaming_Tool::NamedShape(aRoot, builder(theTag)->NamedShape()->Label()).IsNull())
- continue; // there is no sence to write history is old shape does not persented in document
+ //if (TNaming_Tool::NamedShape(aRoot, builder(theTag)->NamedShape()->Label()).IsNull())
+ // continue; // there is no sense to write history if old shape does not exist in the document
ListOfShape aList;
std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
aRShape->setImpl((new TopoDS_Shape(aRoot)));
theMS->generated(aRShape, aList);
+ keepTopLevelShapes(aList, aRoot);
std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator
anIt = aList.begin(), aLast = aList.end();
for (; anIt != aLast; anIt++) {
#include <TDataStd_Name.hxx>
#include <TDataStd_AsciiString.hxx>
#include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_UAttribute.hxx>
#include <TDF_AttributeIterator.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_RelocationTable.hxx>
static const int kFlagDisplayed = 1;
// 2 - is deleted (for results) or not
static const int kFlagDeleted = 2;
+// TDataStd_Integer - 0 if the name of the object is generated automatically,
+// otherwise the name is defined by user
+Standard_GUID kUSER_DEFINED_NAME("9c694d18-a83c-4a56-bc9b-8020628a8244");
// invalid data
const static std::shared_ptr<ModelAPI_Data> kInvalid(new Model_Data());
isModified = true;
} else {
isModified = !aName->Get().IsEqual(theName.c_str());
- if (isModified)
+ if (isModified) {
aName->Set(theName.c_str());
+ // name is changed, thus special attribute is set
+ TDataStd_UAttribute::Set(myLab, kUSER_DEFINED_NAME);
+ }
}
if (mySendAttributeUpdated && isModified)
ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this);
#endif
}
+bool Model_Data::hasUserDefinedName() const
+{
+ return myLab.IsAttribute(kUSER_DEFINED_NAME);
+}
+
AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
{
AttributePtr aResult;
aRes->setIsConcealed(false);
}
-void Model_Data::removeBackReference(FeaturePtr theFeature, std::string theAttrID)
+void Model_Data::removeBackReference(ObjectPtr theObject, std::string theAttrID)
{
- AttributePtr anAttribute = theFeature->data()->attribute(theAttrID);
+ AttributePtr anAttribute = theObject->data()->attribute(theAttrID);
removeBackReference(anAttribute);
}
void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID,
const bool theApplyConcealment)
{
- // it is possible to add the same attribute twice: may be last time the owner was not Stable...
- AttributePtr anAttribute = theFeature->data()->attribute(theAttrID);
- if (myRefsToMe.find(anAttribute) == myRefsToMe.end())
- myRefsToMe.insert(theFeature->data()->attribute(theAttrID));
+ addBackReference(ObjectPtr(theFeature), theAttrID);
if (theApplyConcealment && theFeature->isStable() &&
ModelAPI_Session::get()->validators()->isConcealed(theFeature->getKind(), theAttrID)) {
}
}
+void Model_Data::addBackReference(ObjectPtr theObject, std::string theAttrID)
+{
+ // it is possible to add the same attribute twice: may be last time the owner was not Stable...
+ AttributePtr anAttribute = theObject->data()->attribute(theAttrID);
+ if (myRefsToMe.find(anAttribute) == myRefsToMe.end())
+ myRefsToMe.insert(anAttribute);
+}
+
void Model_Data::updateConcealmentFlag()
{
std::set<AttributePtr>::iterator aRefsIter = myRefsToMe.begin();
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
#include <ModelAPI_Object.h>
#include <TDF_Label.hxx>
MODEL_EXPORT virtual std::string name();
/// Defines the name of the feature visible by the user in the object browser
MODEL_EXPORT virtual void setName(const std::string& theName);
+ /// Return \c true if the object has been renamed by the user
+ MODEL_EXPORT virtual bool hasUserDefinedName() const;
/// Returns the attribute that references to another document
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_AttributeDocRef> document(const std::string& theID);
/// Returns the attribute that contains real value with double precision
/// Removes a back reference (with identifier which attribute references to this object)
/// \param theFeature feature referenced to this
/// \param theAttrID identifier of the attribute that is references from theFeature to this
- void removeBackReference(FeaturePtr theFeature, std::string theAttrID);
+ void removeBackReference(ObjectPtr theObject, std::string theAttrID);
/// Removes a back reference (by the attribute)
/// \param theAttr the referenced attribute
void removeBackReference(AttributePtr theAttr);
/// \param theApplyConcealment applies consealment flag changes
void addBackReference(FeaturePtr theFeature, std::string theAttrID,
const bool theApplyConcealment = true);
+ /// Adds a back reference to an object
+ /// \param theObject object referenced to this
+ /// \param theAttrID identifier of the attribute that is references from theFolder to this
+ void addBackReference(ObjectPtr theObject, std::string theAttrID);
/// Makes the concealment flag up to date for this object-owner.
MODEL_EXPORT virtual void updateConcealmentFlag();
/// Without concealment change, it will be done later, on synchronization.
#define ADD_BACK_REF(TARGET) \
if (TARGET.get() != NULL) { \
+ std::shared_ptr<Model_Data> aTargetData = \
+ std::dynamic_pointer_cast<Model_Data>((TARGET)->data()); \
FeaturePtr anAttributeOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner()); \
- if (anAttributeOwnerFeature.get()) { \
- std::shared_ptr<Model_Data> aTargetData = std::dynamic_pointer_cast<Model_Data>( \
- (TARGET)->data()); \
+ if (anAttributeOwnerFeature.get()) \
aTargetData->addBackReference(anAttributeOwnerFeature, id(), false); \
+ else { \
+ FolderPtr anAttributeOwnerFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(owner()); \
+ if (anAttributeOwnerFolder.get()) \
+ aTargetData->addBackReference(ObjectPtr(anAttributeOwnerFolder), id()); \
} \
}
/// Without concealment change, it will be done later, on synchronization.
#define REMOVE_BACK_REF(TARGET) \
if (TARGET.get() != NULL) { \
+ std::shared_ptr<Model_Data> aTargetData = \
+ std::dynamic_pointer_cast<Model_Data>((TARGET)->data()); \
FeaturePtr anAttOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner()); \
- if (anAttOwnerFeature.get()) { \
- std::shared_ptr<Model_Data> aTargetData = std::dynamic_pointer_cast<Model_Data>( \
- (TARGET)->data()); \
+ if (anAttOwnerFeature.get()) \
aTargetData->removeBackReference(anAttOwnerFeature, id()); \
+ else { \
+ FolderPtr anAttributeOwnerFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(owner()); \
+ if (anAttributeOwnerFolder.get()) \
+ aTargetData->removeBackReference(ObjectPtr(anAttributeOwnerFolder), id()); \
} \
}
int aSubs = aComp->numberOfSubs(false);
for(int a = 0; a < aSubs; a++) {
FeaturePtr aSub = aComp->subFeature(a, false);
- if (myObjs->isLater(aSub, aCurrent)) {
+ if (aSub && myObjs->isLater(aSub, aCurrent)) {
isModified = true;
aCurrent = aSub;
}
Model_Application::getApplication()->document(theDocID));
}
-ObjectPtr Model_Document::object(const std::string& theGroupID, const int theIndex)
+ObjectPtr Model_Document::object(const std::string& theGroupID,
+ const int theIndex,
+ const bool theAllowFolder)
{
- return myObjs->object(theGroupID, theIndex);
+ return myObjs->object(theGroupID, theIndex, theAllowFolder);
}
std::shared_ptr<ModelAPI_Object> Model_Document::objectByName(
return myObjs->objectByName(theGroupID, theName);
}
-const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject)
+const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject,
+ const bool theAllowFolder)
{
- return myObjs->index(theObject);
+ return myObjs->index(theObject, theAllowFolder);
}
-int Model_Document::size(const std::string& theGroupID)
+int Model_Document::size(const std::string& theGroupID, const bool theAllowFolder)
{
if (myObjs == 0) // may be on close
return 0;
- return myObjs->size(theGroupID);
+ return myObjs->size(theGroupID, theAllowFolder);
}
std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theVisible)
return myObjs->createParameter(theFeatureData, theIndex);
}
+std::shared_ptr<ModelAPI_Folder> Model_Document::addFolder(
+ std::shared_ptr<ModelAPI_Feature> theAddBefore)
+{
+ return myObjs->createFolder(theAddBefore);
+}
+
+void Model_Document::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
+{
+ if (theFolder)
+ myObjs->removeFolder(theFolder);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderAbove(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+ return myObjs->findFolder(theFeatures, false);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderBelow(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures)
+{
+ return myObjs->findFolder(theFeatures, true);
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Document::findContainingFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ int& theIndexInFolder)
+{
+ return myObjs->findContainingFolder(theFeature, theIndexInFolder);
+}
+
+bool Model_Document::moveToFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder)
+{
+ return myObjs->moveToFolder(theFeatures, theFolder);
+}
+
+bool Model_Document::removeFromFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore)
+{
+ return myObjs->removeFromFolder(theFeatures, theBefore);
+}
+
std::shared_ptr<ModelAPI_Feature> Model_Document::feature(
const std::shared_ptr<ModelAPI_Result>& theResult)
{
return aName->Label();
}
}
+ // check also "this" label
+ Handle(TDataStd_Name) aName;
+ if (aLabIter->FindAttribute(TDataStd_Name::GetID(), aName)) {
+ if (aName->Get() == aSubName) {
+ return aName->Label();
+ }
+ }
}
}
}
return myObjs->allFeatures();
}
+std::list<std::shared_ptr<ModelAPI_Object> > Model_Document::allObjects()
+{
+ return myObjs->allObjects();
+}
+
void Model_Document::setActive(const bool theFlag)
{
if (theFlag != myIsActive) {
//! Returns the object index in the group. Object must be visible. Otherwise returns -1.
//! \param theObject object of this document
+ //! \param theAllowFolder take into account grouping feature by folders
//! \returns index started from zero, or -1 if object is invisible or belongs to another document
- MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject);
+ MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
+ const bool theAllowFolder = false);
//! Internal sub-document by ID
MODEL_EXPORT virtual std::shared_ptr<Model_Document> subDoc(int theDocID);
//! Returns the feature in the group by the index (started from zero)
//! \param theGroupID group that contains a feature
//! \param theIndex zero-based index of feature in the group
- MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID, const int theIndex);
+ //! \param theAllowFolder take into account grouping feature by folders
+ MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID,
+ const int theIndex,
+ const bool theAllowFolder = false);
//! Returns the number of features in the group
- MODEL_EXPORT virtual int size(const std::string& theGroupID);
+ //! \param theGroupID group of objects
+ //! \param theAllowFolder take into account grouping feature by folders
+ MODEL_EXPORT virtual int size(const std::string& theGroupID, const bool theAllowFolder = false);
//! Returns the feature that is currently edited in this document, normally
//! this is the latest created feature
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Feature>
feature(const std::shared_ptr<ModelAPI_Result>& theResult);
+ //! Creates a folder (group of the features in the object browser)
+ //! \param theAddBefore a feature, the folder is added before
+ //! (if empty, the folder is added after the last feature)
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> addFolder(
+ std::shared_ptr<ModelAPI_Feature> theAddBefore = std::shared_ptr<ModelAPI_Feature>());
+ //! Removes the folder from the document (all features in the folder will be kept).
+ MODEL_EXPORT virtual void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder);
+ //! Search a folder above the list of features applicable to store them
+ //! (it means the list of features stored in the folder should be consequential)
+ //! \return Empty pointer if there is no applicable folder
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findFolderAbove(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures);
+ //! Search a folder below the list of features applicable to store them
+ //! (it means the list of features stored in the folder should be consequential)
+ //! \return Empty pointer if there is no applicable folder
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures);
+ //! Search a folder containing the given feature.
+ //! Addtionally calculates a zero-based index of the feature in this folder.
+ //! \param theFeature feature to search
+ //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+ //! \return the folder containing the feature or empty pointer if the feature is top-level.
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ int& theIndexInFolder);
+ //! Add a list of features to the folder. The correctness of the adding is not performed
+ //! (such checks have been done in corresponding find.. method).
+ //! \return \c true if the movement is successfull
+ MODEL_EXPORT virtual bool moveToFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder);
+ //! Remove features from the folder
+ //! \param theFeatures list of features to be removed
+ //! \param theBefore extract features before the folder (this parameter is applicable only
+ //! when all features in the folder are taking out,
+ //! in other cases the direction is taken automatically)
+ //! \return \c true if the features have been moved out
+ MODEL_EXPORT virtual bool removeFromFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore = true);
+
///! Returns true if parametric updater need to execute feature on recomputartion
///! On abort, undo or redo it is not necessary: results in document are updated automatically
bool executeFeatures() {return myExecuteFeatures;}
///! history. Not very fast method, for calling once, not in big cycles.
MODEL_EXPORT virtual std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures();
+ //! Returns all objects of the document including the hidden features which are not in
+ //! history. Not very fast method, for calling once, not in big cycles.
+ MODEL_EXPORT virtual std::list<std::shared_ptr<ModelAPI_Object> > allObjects();
+
/// Returns the global identifier of the current transaction (needed for the update algo)
MODEL_EXPORT virtual int transactionID();
/// Increases the transaction ID
#include <TDF_LabelMap.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
+static const std::string& groupNameFoldering(const std::string& theGroupID,
+ const bool theAllowFolder)
+{
+ if (theAllowFolder) {
+ static const std::string anOutOfFolderName = std::string("__") + ModelAPI_Feature::group();
+ static const std::string aDummyName;
+ return theGroupID == ModelAPI_Feature::group() ? anOutOfFolderName : aDummyName;
+ }
+ return theGroupID;
+}
+
+// Check theFeature is a first or last feature in folder and return this folder
+static FolderPtr inFolder(const FeaturePtr& theFeature, const std::string& theFolderAttr)
+{
+ const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
+ for (std::set<AttributePtr>::iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt) {
+ if ((*anIt)->id() != theFolderAttr)
+ continue;
+
+ ObjectPtr anOwner = (*anIt)->owner();
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(anOwner);
+ if (aFolder.get())
+ return aFolder;
+ }
+ return FolderPtr();
+}
+
+
static const int TAG_OBJECTS = 2; // tag of the objects sub-tree (features, results)
// feature sub-labels
aFeature->erase();
myFeatures.UnBind(aFeaturesIter.Key());
}
+ while (!myFolders.IsEmpty()) {
+ NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFoldersIter(myFolders);
+ ObjectPtr aFolder = aFoldersIter.Value();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Folder::group());
+ ModelAPI_EventCreator::get()->sendUpdated(aFolder, EVENT_DISP);
+ aFolder->erase();
+ myFolders.UnBind(aFoldersIter.Key());
+ }
myHistory.clear();
aLoop->activateFlushes(isActive);
// erase update, because features are destroyed and update should not performed for them anywhere
// store feature in the features array: before "initData" because in macro features
// in initData it creates new features, appeared later than this
TDF_Label aPrevFeateureLab;
+ FolderPtr aParentFolder;
if (theAfterThis.get()) { // searching for the previous feature label
std::shared_ptr<Model_Data> aPrevData =
std::dynamic_pointer_cast<Model_Data>(theAfterThis->data());
if (aPrevData.get()) {
aPrevFeateureLab = aPrevData->label().Father();
}
+ // check if the previous feature is the last feature in a folder,
+ // then the folder should be updated to contain additional feature
+ aParentFolder = inFolder(theAfterThis, ModelAPI_Folder::LAST_FEATURE_ID());
}
AddToRefArray(aFeaturesLab, aFeatureLab, aPrevFeateureLab);
// must be after binding to the map because of "Box" macro feature that
// creates other features in "initData"
initData(theFeature, aFeatureLab, TAG_FEATURE_ARGUMENTS);
+ // put feature to the end of folder if it is added while
+ // the history line is set to the last feature from the folder
+ if (aParentFolder) {
+ aParentFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID())->setValue(theFeature);
+ updateHistory(ModelAPI_Folder::group());
+ }
// event: feature is added, mist be before "initData" to update OB correctly on Duplicate:
// first new part, then the content
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
aComposite->removeFeature(theFeature);
}
}
+ // remove feature from folder
+ removeFromFolder(std::list<FeaturePtr>(1, theFeature));
// this must be before erase since theFeature erasing removes all information about
// the feature results and groups of results
// To reproduce: create sketch, extrusion, remove sketch => constructions tree is not updated
{
if (theObj.get()) {
const std::string aGroup = theObj->groupName();
- std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(aGroup);
- if (aHIter != myHistory.end())
- myHistory.erase(aHIter); // erase from map => this means that it is not synchronized
+ updateHistory(aGroup);
+
if (theObj->groupName() == ModelAPI_Feature::group()) { // clear results group of the feature
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
std::string aResultGroup = featureResultGroup(aFeature);
{
std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(theGroupID);
if (aHIter == myHistory.end()) {
- std::vector<ObjectPtr> aResult = std::vector<ObjectPtr>();
+ std::vector<ObjectPtr> aResult;
+ std::vector<ObjectPtr> aResultOutOfFolder;
+ FeaturePtr aLastFeatureInFolder;
// iterate the array of references and get feature by feature from the array
bool isFeature = theGroupID == ModelAPI_Feature::group();
+ bool isFolder = theGroupID == ModelAPI_Folder::group();
Handle(TDataStd_ReferenceArray) aRefs;
if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) {
if (isFeature) { // here may be also disabled features
if (!isSub && aFeature->isInHistory()) {
aResult.push_back(aFeature);
+ // the feature is out of the folders
+ if (aLastFeatureInFolder.get() == NULL)
+ aResultOutOfFolder.push_back(aFeature);
}
} else if (!aFeature->isDisabled()) { // iterate all results of not-disabled feature
// construction results of sub-features should not be in the tree
}
}
}
+
+ // the feature closes the folder, so the next features will be treated as out-of-folder
+ if (aLastFeatureInFolder.get() && aLastFeatureInFolder == aFeature)
+ aLastFeatureInFolder = FeaturePtr();
+
+ } else {
+ // it may be a folder
+ ObjectPtr aFolder = folder(aRefs->Value(a));
+ if (aFolder.get()) {
+ // store folder information for the Features group only
+ if (isFeature || isFolder) {
+ aResult.push_back(aFolder);
+ if (!isFolder)
+ aResultOutOfFolder.push_back(aFolder);
+ }
+
+ // get the last feature in the folder
+ AttributeReferencePtr aLastFeatAttr =
+ aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (aLastFeatAttr)
+ aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+ }
}
}
}
// to be sure that isConcealed did not update the history (issue 1089) during the iteration
- if (myHistory.find(theGroupID) == myHistory.end())
+ if (myHistory.find(theGroupID) == myHistory.end()) {
myHistory[theGroupID] = aResult;
+
+ // store the features placed out of any folder
+ const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroupID, true);
+ if (!anOutOfFolderGroupID.empty())
+ myHistory[anOutOfFolderGroupID] = aResultOutOfFolder;
+ }
}
}
void Model_Objects::updateHistory(const std::string theGroup)
{
std::map<std::string, std::vector<ObjectPtr> >::iterator aHIter = myHistory.find(theGroup);
- if (aHIter != myHistory.end())
+ if (aHIter != myHistory.end()) {
myHistory.erase(aHIter); // erase from map => this means that it is not synchronized
+
+ // erase history for the group of objects placed out of any folder
+ const std::string& anOutOfFolderGroupID = groupNameFoldering(theGroup, true);
+ if (!anOutOfFolderGroupID.empty())
+ myHistory.erase(anOutOfFolderGroupID);
+ }
+}
+
+ObjectPtr Model_Objects::folder(TDF_Label theLabel) const
+{
+ if (myFolders.IsBound(theLabel))
+ return myFolders.Find(theLabel);
+ return ObjectPtr();
}
FeaturePtr Model_Objects::feature(TDF_Label theLabel) const
return FeaturePtr(); // not found
}
-ObjectPtr Model_Objects::object(const std::string& theGroupID, const int theIndex)
+ObjectPtr Model_Objects::object(const std::string& theGroupID,
+ const int theIndex,
+ const bool theAllowFolder)
{
if (theIndex == -1)
return ObjectPtr();
createHistory(theGroupID);
- return myHistory[theGroupID][theIndex];
+ const std::string& aGroupID = groupNameFoldering(theGroupID, theAllowFolder);
+ const std::vector<ObjectPtr>& aVec = myHistory[theGroupID];
+ //if (aVec.size() <= theIndex)
+ // return aVec[aVec.size() - 1]; // too high index requested (to avoid crash in #2360)
+ return aGroupID.empty() ? myHistory[theGroupID][theIndex] : myHistory[aGroupID][theIndex];
}
std::shared_ptr<ModelAPI_Object> Model_Objects::objectByName(
return ObjectPtr();
}
-const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject)
+const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject,
+ const bool theAllowFolder)
{
std::string aGroup = theObject->groupName();
+ // treat folder as feature
+ if (aGroup == ModelAPI_Folder::group())
+ aGroup = ModelAPI_Feature::group();
createHistory(aGroup);
+
+ // get the group of features out of folder (if enabled)
+ if (theAllowFolder && !groupNameFoldering(aGroup, theAllowFolder).empty())
+ aGroup = groupNameFoldering(aGroup, theAllowFolder);
+
std::vector<ObjectPtr>& allObjs = myHistory[aGroup];
std::vector<ObjectPtr>::iterator anObjIter = allObjs.begin(); // iterate to search object
for(int anIndex = 0; anObjIter != allObjs.end(); anObjIter++, anIndex++) {
return -1;
}
-int Model_Objects::size(const std::string& theGroupID)
+int Model_Objects::size(const std::string& theGroupID, const bool theAllowFolder)
{
createHistory(theGroupID);
- return int(myHistory[theGroupID].size());
+ const std::string& aGroupID = groupNameFoldering(theGroupID, theAllowFolder);
+ return aGroupID.empty() ? int(myHistory[theGroupID].size()) : int(myHistory[aGroupID].size());
}
void Model_Objects::allResults(const std::string& theGroupID, std::list<ResultPtr>& theResults)
return myMain.FindChild(TAG_OBJECTS);
}
+static std::string composeName(const std::string& theFeatureKind, const int theIndex)
+{
+ std::stringstream aNameStream;
+ aNameStream << theFeatureKind << "_" << theIndex;
+ return aNameStream.str();
+}
+
void Model_Objects::setUniqueName(FeaturePtr theFeature)
{
if (!theFeature->data()->name().empty())
aNumObjects++;
}
// generate candidate name
- std::stringstream aNameStream;
- aNameStream << theFeature->getKind() << "_" << aNumObjects + 1;
- aName = aNameStream.str();
+ aName = composeName(theFeature->getKind(), aNumObjects + 1);
// check this is unique, if not, increase index by 1
for (aFIter.Initialize(myFeatures); aFIter.More();) {
FeaturePtr aFeature = aFIter.Value();
if (isSameName) {
aNumObjects++;
- std::stringstream aNameStream;
- aNameStream << theFeature->getKind() << "_" << aNumObjects + 1;
- aName = aNameStream.str();
+ aName = composeName(theFeature->getKind(), aNumObjects + 1);
// reinitialize iterator to make sure a new name is unique
aFIter.Initialize(myFeatures);
} else
theFeature->data()->setName(aName);
}
+void Model_Objects::setUniqueName(FolderPtr theFolder)
+{
+ if (!theFolder->name().empty())
+ return; // name is already defined
+
+ int aNbFolders = myFolders.Size();
+ std::string aName = composeName(ModelAPI_Folder::ID(), aNbFolders);
+
+ // check the uniqueness of the name
+ NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator anIt(myFolders);
+ while (anIt.More()) {
+ if (anIt.Value()->data()->name() == aName) {
+ aName = composeName(ModelAPI_Folder::ID(), aNbFolders);
+ // reinitialize iterator to make sure a new name is unique
+ anIt.Initialize(myFolders);
+ } else
+ anIt.Next();
+ }
+
+ theFolder->data()->setName(aName);
+}
+
void Model_Objects::initData(ObjectPtr theObj, TDF_Label theLab, const int theTag)
{
std::shared_ptr<Model_Data> aData(new Model_Data);
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
if (aFeature.get()) {
setUniqueName(aFeature); // must be before "initAttributes" because duplicate part uses name
+ } else { // is it a folder?
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(theObj);
+ if (aFolder)
+ setUniqueName(aFolder);
}
theObj->initAttributes();
}
TDF_Label& aFeatureLab = anUpdatedIter.Value();
while(aFeatureLab.Depth() > 3)
aFeatureLab = aFeatureLab.Father();
- if (myFeatures.IsBound(aFeatureLab))
+ if (myFeatures.IsBound(aFeatureLab) || myFolders.IsBound(aFeatureLab))
anUpdatedMap.Add(aFeatureLab);
}
// update all objects by checking are they on labels or not
- std::set<FeaturePtr> aNewFeatures, aKeptFeatures;
+ std::set<ObjectPtr> aNewFeatures, aKeptFeatures;
TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID());
for (; aLabIter.More(); aLabIter.Next()) {
TDF_Label aFeatureLabel = aLabIter.Value()->Label();
- FeaturePtr aFeature;
- if (!myFeatures.IsBound(aFeatureLabel)) { // a new feature is inserted
+ if (!myFeatures.IsBound(aFeatureLabel) && !myFolders.IsBound(aFeatureLabel)) {
+ // a new feature or folder is inserted
+
+ std::string aFeatureID = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
+ aLabIter.Value())->Get()).ToCString();
+ bool isFolder = aFeatureID == ModelAPI_Folder::ID();
+
+ std::shared_ptr<Model_Session> aSession =
+ std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get());
+
// create a feature
- aFeature = std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get())->createFeature(
- TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(aLabIter.Value())->Get())
- .ToCString(), anOwner);
+ ObjectPtr aFeature = isFolder ? ObjectPtr(new ModelAPI_Folder)
+ : ObjectPtr(aSession->createFeature(aFeatureID, anOwner));
if (!aFeature.get()) {
// somethig is wrong, most probably, the opened document has invalid structure
Events_InfoMessage("Model_Objects", "Invalid type of object in the document").send();
}
aFeature->init();
// this must be before "setData" to redo the sketch line correctly
- myFeatures.Bind(aFeatureLabel, aFeature);
+ if (isFolder)
+ myFolders.Bind(aFeatureLabel, aFeature);
+ else
+ myFeatures.Bind(aFeatureLabel, std::dynamic_pointer_cast<ModelAPI_Feature>(aFeature));
aNewFeatures.insert(aFeature);
initData(aFeature, aFeatureLabel, TAG_FEATURE_ARGUMENTS);
updateHistory(aFeature);
// event: model is updated
ModelAPI_EventCreator::get()->sendUpdated(aFeature, aCreateEvent);
} else { // nothing is changed, both iterators are incremented
- aFeature = myFeatures.Find(aFeatureLabel);
- aKeptFeatures.insert(aFeature);
+ ObjectPtr anObject;
+ FeaturePtr aFeature;
+ if (myFeatures.Find(aFeatureLabel, aFeature)) {
+ aKeptFeatures.insert(aFeature);
+ anObject = aFeature;
+ } else
+ if (myFolders.Find(aFeatureLabel, anObject))
+ aKeptFeatures.insert(anObject);
+
if (anUpdatedMap.Contains(aFeatureLabel)) {
if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed
std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
- aFeature->data()->attributes("");
+ anObject->data()->attributes("");
std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
for(; anAttr != anAttrs.end(); anAttr++)
(*anAttr)->reinit();
}
- ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent);
- if (aFeature->getKind() == "Parameter") {
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, anUpdateEvent);
+ if (aFeature && aFeature->getKind() == "Parameter") {
// if parameters are changed, update the results (issue 937)
const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
} else
aFIter.Next();
}
+ // verify folders are checked: if not => is was removed
+ for (NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFldIt(myFolders);
+ aFldIt.More(); aFldIt.Next()) {
+ ObjectPtr aCurObj = aFldIt.Value();
+ if (aKeptFeatures.find(aCurObj) == aKeptFeatures.end() &&
+ aNewFeatures.find(aCurObj) == aNewFeatures.end()) {
+ ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Folder::group());
+ // results of this feature must be redisplayed (hided)
+ // redisplay also removed feature (used for sketch and AISObject)
+ ModelAPI_EventCreator::get()->sendUpdated(aCurObj, aRedispEvent);
+ updateHistory(aCurObj);
+ aCurObj->erase();
+
+ // unbind after the "erase" call: on abort sketch
+ // is removes sub-objects that corrupts aFIter
+ myFolders.UnBind(aFldIt.Key());
+ // reinitialize iterator because unbind may corrupt the previous order in the map
+ aFldIt.Initialize(myFolders);
+ }
+ }
if (theUpdateReferences) {
synchronizeBackRefs();
for(; aNewIter != theNewRefs.end(); aNewIter++) {
if (aData->refsToMe().find(*aNewIter) == aData->refsToMe().end()) {
FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aNewIter)->owner());
- aData->addBackReference(aRefFeat, (*aNewIter)->id());
+ if (aRefFeat)
+ aData->addBackReference(aRefFeat, (*aNewIter)->id());
+ else // add back reference to a folder
+ aData->addBackReference((*aNewIter)->owner(), (*aNewIter)->id());
}
}
if (theNewRefs.size() != aData->refsToMe().size()) { // some back ref must be removed
aData->updateConcealmentFlag();
}
+static void collectReferences(std::shared_ptr<ModelAPI_Data> theData,
+ std::map<ObjectPtr, std::set<AttributePtr> >& theRefs)
+{
+ if (theData.get()) {
+ std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+ theData->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefsIt = aRefs.begin();
+ for(; aRefsIt != aRefs.end(); aRefsIt++) {
+ std::list<ObjectPtr>::iterator aRefTo = aRefsIt->second.begin();
+ for(; aRefTo != aRefsIt->second.end(); aRefTo++) {
+ if (*aRefTo) {
+ std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = theRefs.find(*aRefTo);
+ if (aFound == theRefs.end()) {
+ theRefs[*aRefTo] = std::set<AttributePtr>();
+ aFound = theRefs.find(*aRefTo);
+ }
+ aFound->second.insert(theData->attribute(aRefsIt->first));
+ }
+ }
+ }
+ }
+}
+
void Model_Objects::synchronizeBackRefs()
{
// collect all back references in the separated container: to update everything at once,
NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myFeatures);
for(; aFeatures.More(); aFeatures.Next()) {
FeaturePtr aFeature = aFeatures.Value();
- std::shared_ptr<Model_Data> aFData = std::dynamic_pointer_cast<Model_Data>(aFeature->data());
- if (aFData.get()) {
- std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
- aFData->referencesToObjects(aRefs);
- std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefsIt = aRefs.begin();
- for(; aRefsIt != aRefs.end(); aRefsIt++) {
- std::list<ObjectPtr>::iterator aRefTo = aRefsIt->second.begin();
- for(; aRefTo != aRefsIt->second.end(); aRefTo++) {
- if (*aRefTo) {
- std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = allRefs.find(*aRefTo);
- if (aFound == allRefs.end()) {
- allRefs[*aRefTo] = std::set<AttributePtr>();
- aFound = allRefs.find(*aRefTo);
- }
- aFound->second.insert(aFeature->data()->attribute(aRefsIt->first));
- }
- }
- }
- }
+ collectReferences(aFeature->data(), allRefs);
+ }
+ NCollection_DataMap<TDF_Label, ObjectPtr>::Iterator aFolders(myFolders);
+ for(; aFolders.More(); aFolders.Next()) {
+ ObjectPtr aFolder = aFolders.Value();
+ collectReferences(aFolder->data(), allRefs);
}
// second iteration: just compare back-references with existing in features and results
for(aFeatures.Initialize(myFeatures); aFeatures.More(); aFeatures.Next()) {
return false;
}
- theParentName = ModelAPI_Tools::getDefaultName(theResult, theResultIndex);
- return true;
+ std::pair<std::string, bool> aName = ModelAPI_Tools::getDefaultName(theResult, theResultIndex);
+ if (aName.second)
+ theParentName = aName.first;
+ return aName.second;
}
void Model_Objects::storeResult(std::shared_ptr<ModelAPI_Data> theFeatureData,
if (theResult->data()->name().empty()) {
// if was not initialized, generate event and set a name
std::string aNewName = theFeatureData->name();
- if (!hasCustomName(theFeatureData, theResult, theResultIndex, aNewName)) {
+ if (hasCustomName(theFeatureData, theResult, theResultIndex, aNewName)) {
+ // if the name of result is user-defined, then, at first time, assign name of the result
+ // by empty string to be sure that corresponding flag in the data model is set
+ theResult->data()->setName("");
+ } else {
std::stringstream aName;
aName << aNewName;
// if there are several results (issue #899: any number of result),
return aResult;
}
+std::shared_ptr<ModelAPI_Folder> Model_Objects::createFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theBeforeThis)
+{
+ FolderPtr aFolder(new ModelAPI_Folder);
+ if (!aFolder)
+ return aFolder;
+
+ TDF_Label aFeaturesLab = featuresLabel();
+ TDF_Label aFolderLab = aFeaturesLab.NewChild();
+ // store feature in the features array: before "initData" because in macro features
+ // in initData it creates new features, appeared later than this
+ TDF_Label aPrevFeatureLab;
+ if (theBeforeThis.get()) { // searching for the previous feature label
+ std::shared_ptr<Model_Data> aPrevData =
+ std::dynamic_pointer_cast<Model_Data>(theBeforeThis->data());
+ if (aPrevData.get()) {
+ aPrevFeatureLab = nextLabel(aPrevData->label().Father(), true);
+ }
+ } else { // find the label of the last feature
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ aPrevFeatureLab = aRefs->Value(aRefs->Upper());
+ }
+ AddToRefArray(aFeaturesLab, aFolderLab, aPrevFeatureLab);
+
+ // keep the feature ID to restore document later correctly
+ TDataStd_Comment::Set(aFolderLab, ModelAPI_Folder::ID().c_str());
+ myFolders.Bind(aFolderLab, aFolder);
+ // must be before the event sending: for OB the feature is already added
+ updateHistory(ModelAPI_Folder::group());
+ updateHistory(ModelAPI_Feature::group());
+
+ // must be after binding to the map because of "Box" macro feature that
+ // creates other features in "initData"
+ initData(aFolder, aFolderLab, TAG_FEATURE_ARGUMENTS);
+ // event: folder is added, must be before "initData" to update OB correctly on Duplicate:
+ // first new part, then the content
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+ ModelAPI_EventCreator::get()->sendUpdated(aFolder, anEvent);
+
+ return aFolder;
+}
+
+void Model_Objects::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
+{
+ std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theFolder->data());
+ if (!aData.get() || !aData->isValid())
+ return;
+
+ // this must be before erase since theFolder erasing removes all information about it
+ clearHistory(theFolder);
+ // erase fields
+ theFolder->erase();
+
+ TDF_Label aFolderLabel = aData->label().Father();
+ if (myFolders.IsBound(aFolderLabel))
+ myFolders.UnBind(aFolderLabel);
+
+ static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ ModelAPI_EventCreator::get()->sendUpdated(theFolder, EVENT_DISP);
+ // erase all attributes under the label of feature
+ aFolderLabel.ForgetAllAttributes();
+ // remove it from the references array
+ RemoveFromRefArray(featuresLabel(), aFolderLabel);
+ // event: feature is deleted
+ ModelAPI_EventCreator::get()->sendDeleted(theFolder->document(), ModelAPI_Folder::group());
+ updateHistory(ModelAPI_Folder::group());
+ updateHistory(ModelAPI_Feature::group());
+}
+
+// Returns one of the limiting features of the list
+static FeaturePtr limitingFeature(std::list<FeaturePtr>& theFeatures, const bool isLast)
+{
+ FeaturePtr aFeature;
+ if (isLast) {
+ aFeature = theFeatures.back();
+ theFeatures.pop_back();
+ } else {
+ aFeature = theFeatures.front();
+ theFeatures.pop_front();
+ }
+ return aFeature;
+}
+
+// Verify the feature is sub-element in composite feature or it is not used in the history
+static bool isSkippedFeature(FeaturePtr theFeature)
+{
+ bool isSub = ModelAPI_Tools::compositeOwner(theFeature).get() != NULL;
+ return isSub || (theFeature && !theFeature->isInHistory());
+}
+
+std::shared_ptr<ModelAPI_Folder> Model_Objects::findFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBelow)
+{
+ if (theFeatures.empty())
+ return FolderPtr(); // nothing to move
+
+ TDF_Label aFeaturesLab = featuresLabel();
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return FolderPtr(); // no reference array (something is wrong)
+
+ std::list<std::shared_ptr<ModelAPI_Feature> > aFeatures = theFeatures;
+ std::shared_ptr<ModelAPI_Feature> aLimitingFeature = limitingFeature(aFeatures, theBelow);
+
+ std::shared_ptr<Model_Data> aData =
+ std::static_pointer_cast<Model_Data>(aLimitingFeature->data());
+ if (!aData || !aData->isValid())
+ return FolderPtr(); // invalid feature
+
+ // label of the first feature in the list for fast searching
+ TDF_Label aFirstFeatureLabel = aData->label().Father();
+
+ // find a folder above the features and
+ // check the given features represent a sequential list of objects following the folder
+ FolderPtr aFoundFolder;
+ TDF_Label aLastFeatureInFolder;
+ int aRefIndex = aRefs->Lower();
+ for(; aRefIndex <= aRefs->Upper(); ++aRefIndex) { // iterate all existing features
+ TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+ if (IsEqual(aCurLabel, aFirstFeatureLabel))
+ break; // no need to continue searching
+
+ // searching the folder below, just continue to search last feature from the list
+ if (theBelow)
+ continue;
+
+ // if feature is in sub-component, skip it
+ FeaturePtr aCurFeature = feature(aCurLabel);
+ if (isSkippedFeature(aCurFeature))
+ continue;
+
+ if (!aLastFeatureInFolder.IsNull()) {
+ if (IsEqual(aCurLabel, aLastFeatureInFolder))
+ aLastFeatureInFolder.Nullify(); // the last feature in the folder is achived
+ continue;
+ }
+
+ aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
+ if (aFoundFolder) {
+ AttributeReferencePtr aLastFeatAttr =
+ aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (aLastFeatAttr) {
+ // setup iterating inside a folder to find last feature
+ ObjectPtr aLastFeature = aLastFeatAttr->value();
+ if (aLastFeature) {
+ aData = std::static_pointer_cast<Model_Data>(aLastFeature->data());
+ if (aData && aData->isValid())
+ aLastFeatureInFolder = aData->label().Father();
+ }
+ }
+ }
+ }
+
+ if (theBelow && aRefIndex < aRefs->Upper()) {
+ TDF_Label aLabel;
+ // skip following features which are sub-components or not in history
+ for (int anIndex = aRefIndex + 1; anIndex <= aRefs->Upper(); ++anIndex) {
+ aLabel = aRefs->Value(anIndex);
+ FeaturePtr aCurFeature = feature(aLabel);
+ if (!isSkippedFeature(aCurFeature))
+ break;
+ }
+ // check the next object is a folder
+ aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aLabel));
+ }
+
+ if (!aLastFeatureInFolder.IsNull() || // the last feature of the folder above is not found
+ !aFoundFolder)
+ return FolderPtr();
+
+ // check the given features are sequential list
+ int aStep = theBelow ? -1 : 1;
+ for (aRefIndex += aStep;
+ !aFeatures.empty() && aRefIndex >= aRefs->Lower() && aRefIndex <= aRefs->Upper();
+ aRefIndex += aStep) {
+ TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+ // if feature is in sub-component, skip it
+ FeaturePtr aCurFeature = feature(aCurLabel);
+ if (isSkippedFeature(aCurFeature))
+ continue;
+
+ aLimitingFeature = limitingFeature(aFeatures, theBelow);
+ if (!aCurFeature->data()->isEqual(aLimitingFeature->data()))
+ return FolderPtr(); // not a sequential list
+ }
+
+ return aFoundFolder;
+}
+
+bool Model_Objects::moveToFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder)
+{
+ if (theFeatures.empty() || !theFolder)
+ return false;
+
+ // labels for the folder and last feature in the list
+ TDF_Label aFolderLabel, aLastFeatureLabel;
+ std::shared_ptr<Model_Data> aData =
+ std::static_pointer_cast<Model_Data>(theFolder->data());
+ if (aData && aData->isValid())
+ aFolderLabel = aData->label().Father();
+ aData = std::static_pointer_cast<Model_Data>(theFeatures.back()->data());
+ if (aData && aData->isValid())
+ aLastFeatureLabel = aData->label().Father();
+
+ if (aFolderLabel.IsNull() || aLastFeatureLabel.IsNull())
+ return false;
+
+ AttributeReferencePtr aFirstFeatAttr =
+ theFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ AttributeReferencePtr aLastFeatAttr =
+ theFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ bool initFirstAttr = !aFirstFeatAttr->value().get();
+ bool initLastAttr = !aLastFeatAttr->value().get();
+
+ // check the folder is below the list of features
+ bool isFolderBelow = false;
+ TDF_Label aFeaturesLab = featuresLabel();
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return false; // no reference array (something is wrong)
+ for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
+ TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+ if (aCurLabel == aFolderLabel)
+ break; // folder is above the features
+ else if (aCurLabel == aLastFeatureLabel) {
+ isFolderBelow = true;
+ break;
+ }
+ }
+
+ if (isFolderBelow) {
+ aData = std::static_pointer_cast<Model_Data>(theFeatures.front()->data());
+ if (!aData || !aData->isValid())
+ return false;
+ TDF_Label aPrevFeatureLabel = aData->label().Father();
+ // label of the feature before the first feature in the list
+ for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex)
+ if (aPrevFeatureLabel == aRefs->Value(aRefIndex)) {
+ if (aRefIndex == aRefs->Lower())
+ aPrevFeatureLabel.Nullify();
+ else
+ aPrevFeatureLabel = aRefs->Value(aRefIndex - 1);
+ break;
+ }
+
+ // move the folder in the list of references before the first feature
+ RemoveFromRefArray(aFeaturesLab, aFolderLabel);
+ AddToRefArray(aFeaturesLab, aFolderLabel, aPrevFeatureLabel);
+ // update first feature of the folder
+ initFirstAttr = true;
+ } else {
+ // update last feature of the folder
+ initLastAttr = true;
+ }
+
+ if (initFirstAttr)
+ aFirstFeatAttr->setValue(theFeatures.front());
+ if (initLastAttr)
+ aLastFeatAttr->setValue(theFeatures.back());
+
+ updateHistory(ModelAPI_Feature::group());
+ return true;
+}
+
+static FolderPtr isExtractionCorrect(const FolderPtr& theFirstFeatureFolder,
+ const FolderPtr& theLastFeatureFolder,
+ bool& isExtractBefore)
+{
+ if (theFirstFeatureFolder.get()) {
+ if (theLastFeatureFolder.get())
+ return theFirstFeatureFolder == theLastFeatureFolder ? theFirstFeatureFolder : FolderPtr();
+ else
+ isExtractBefore = true;
+ return theFirstFeatureFolder;
+ } else if (theLastFeatureFolder.get()) {
+ isExtractBefore = false;
+ return theLastFeatureFolder;
+ }
+ // no folder found
+ return FolderPtr();
+}
+
+bool Model_Objects::removeFromFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore)
+{
+ if (theFeatures.empty())
+ return false;
+
+ FolderPtr aFirstFeatureFolder =
+ inFolder(theFeatures.front(), ModelAPI_Folder::FIRST_FEATURE_ID());
+ FolderPtr aLastFeatureFolder =
+ inFolder(theFeatures.back(), ModelAPI_Folder::LAST_FEATURE_ID());
+
+ bool isExtractBeforeFolder = theBefore;
+ FolderPtr aFoundFolder =
+ isExtractionCorrect(aFirstFeatureFolder, aLastFeatureFolder, isExtractBeforeFolder);
+ if (!aFoundFolder)
+ return false; // list of features cannot be extracted
+
+ // references of the current folder
+ ObjectPtr aFolderStartFeature;
+ ObjectPtr aFolderEndFeature;
+ if (aFirstFeatureFolder != aLastFeatureFolder) {
+ aFolderStartFeature = aFoundFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID())->value();
+ aFolderEndFeature = aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID())->value();
+ }
+
+ FeaturePtr aFeatureToFind = isExtractBeforeFolder ? theFeatures.back() : theFeatures.front();
+ std::shared_ptr<Model_Data> aData =
+ std::static_pointer_cast<Model_Data>(aFeatureToFind->data());
+ if (!aData || !aData->isValid())
+ return false;
+ TDF_Label aLabelToFind = aData->label().Father();
+
+ // search the label in the list of references
+ TDF_Label aFeaturesLab = featuresLabel();
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return false; // no reference array (something is wrong)
+ int aRefIndex = aRefs->Lower();
+ for (; aRefIndex <= aRefs->Upper(); ++aRefIndex)
+ if (aRefs->Value(aRefIndex) == aLabelToFind)
+ break;
+
+ // update folder position
+ if (isExtractBeforeFolder) {
+ aData = std::dynamic_pointer_cast<Model_Data>(aFoundFolder->data());
+ TDF_Label aFolderLabel = aData->label().Father();
+ TDF_Label aPrevFeatureLabel = aRefs->Value(aRefIndex);
+ // update start reference of the folder
+ if (aFolderStartFeature.get()) {
+ FeaturePtr aNewStartFeature;
+ do { // skip all features placed in the composite features
+ aPrevFeatureLabel = aRefs->Value(aRefIndex++);
+ aNewStartFeature =
+ aRefIndex <= aRefs->Upper() ? feature(aRefs->Value(aRefIndex)) : FeaturePtr();
+ } while (aNewStartFeature && isSkippedFeature(aNewStartFeature));
+ aFolderStartFeature = aNewStartFeature;
+ }
+ // move the folder in the list of references after the last feature from the list
+ RemoveFromRefArray(aFeaturesLab, aFolderLabel);
+ AddToRefArray(aFeaturesLab, aFolderLabel, aPrevFeatureLabel);
+ } else {
+ // update end reference of the folder
+ if (aFolderEndFeature.get()) {
+ FeaturePtr aNewEndFeature;
+ do { // skip all features placed in the composite features
+ --aRefIndex;
+ aNewEndFeature =
+ aRefIndex >= aRefs->Lower() ? feature(aRefs->Value(aRefIndex)) : FeaturePtr();
+ } while (aNewEndFeature && isSkippedFeature(aNewEndFeature));
+ aFolderEndFeature = aNewEndFeature;
+ }
+ }
+
+ // update folder references
+ aFoundFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID())->setValue(aFolderStartFeature);
+ aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID())->setValue(aFolderEndFeature);
+
+ updateHistory(ModelAPI_Feature::group());
+ return true;
+}
+
+FolderPtr Model_Objects::findContainingFolder(const FeaturePtr& theFeature, int& theIndexInFolder)
+{
+ // search the label in the list of references
+ TDF_Label aFeaturesLab = featuresLabel();
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return FolderPtr(); // no reference array (something is wrong)
+
+ std::shared_ptr<Model_Data> aData =
+ std::static_pointer_cast<Model_Data>(theFeature->data());
+ if (!aData || !aData->isValid())
+ return FolderPtr();
+ TDF_Label aLabelToFind = aData->label().Father();
+
+ theIndexInFolder = -1;
+ FolderPtr aFoundFolder;
+ TDF_Label aLastFeatureLabel;
+
+ for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
+ TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+ if (isSkippedFeature(feature(aCurLabel)))
+ continue;
+
+ if (aFoundFolder)
+ ++theIndexInFolder;
+
+ if (aCurLabel == aLabelToFind) // the feature is reached
+ return aFoundFolder;
+
+ if (!aFoundFolder) {
+ // if the current label refers to a folder, feel all necessary data
+ aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
+ if (aFoundFolder) {
+ theIndexInFolder = -1;
+
+ AttributeReferencePtr aLastRef =
+ aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (aLastRef->value()) {
+ aData = std::static_pointer_cast<Model_Data>(aLastRef->value()->data());
+ if (aData && aData->isValid())
+ aLastFeatureLabel = aData->label().Father();
+ } else // folder is empty
+ aFoundFolder = FolderPtr();
+ }
+ } else if (aLastFeatureLabel == aCurLabel) {
+ // folder is finished, clear all stored data
+ theIndexInFolder = -1;
+ aFoundFolder = FolderPtr();
+ }
+ }
+
+ // folder is not found
+ theIndexInFolder = -1;
+ return FolderPtr();
+}
+
+
std::shared_ptr<ModelAPI_Feature> Model_Objects::feature(
const std::shared_ptr<ModelAPI_Result>& theResult)
{
return aResult;
}
+TDF_Label Model_Objects::nextLabel(TDF_Label theCurrent, const bool theReverse)
+{
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+ for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features
+ TDF_Label aCurLab = aRefs->Value(a);
+ if (aCurLab.IsEqual(theCurrent)) {
+ a += theReverse ? -1 : 1;
+ if (a >= aRefs->Lower() && a <= aRefs->Upper())
+ return aRefs->Value(a);
+ break; // finish iiteration: it's last feature
+ }
+ }
+ }
+ return TDF_Label();
+}
+
FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse)
{
std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
if (aData.get() && aData->isValid()) {
TDF_Label aFeatureLabel = aData->label().Father();
- Handle(TDataStd_ReferenceArray) aRefs;
- if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
- for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { // iterate all existing features
- TDF_Label aCurLab = aRefs->Value(a);
- if (aCurLab.IsEqual(aFeatureLabel)) {
- a += theReverse ? -1 : 1;
- if (a >= aRefs->Lower() && a <= aRefs->Upper())
- return feature(aRefs->Value(a));
- break; // finish iiteration: it's last feature
- }
- }
- }
+ do {
+ TDF_Label aNextLabel = nextLabel(aFeatureLabel, theReverse);
+ if (aNextLabel.IsNull())
+ break; // last or something is wrong
+ FeaturePtr aFound = feature(aNextLabel);
+ if (aFound)
+ return aFound; // the feature is found
+ // if the next label is a folder, skip it
+ aFeatureLabel = folder(aNextLabel).get() ? aNextLabel : TDF_Label();
+ } while (!aFeatureLabel.IsNull());
}
return FeaturePtr(); // not found, last, or something is wrong
}
return false; // not found, or something is wrong
}
+std::list<std::shared_ptr<ModelAPI_Object> > Model_Objects::allObjects()
+{
+ std::list<std::shared_ptr<ModelAPI_Object> > aResult;
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+ for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) {
+ ObjectPtr anObject = object(aRefs->Value(a));
+ if (!anObject.get()) // is it a folder?
+ anObject = folder(aRefs->Value(a));
+ if (anObject.get())
+ aResult.push_back(anObject);
+ }
+ }
+ return aResult;
+}
+
std::list<std::shared_ptr<ModelAPI_Feature> > Model_Objects::allFeatures()
{
std::list<std::shared_ptr<ModelAPI_Feature> > aResult;
#include <Model.h>
#include <ModelAPI_Document.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
#include <ModelAPI_Result.h>
#include <ModelAPI_ResultParameter.h>
//! Returns the object index in the group. Object must be visible. Otherwise returns -1.
//! \param theObject object of this document
+ //! \param theAllowFolder take into account grouping feature by folders
//! \returns index started from zero, or -1 if object is invisible or belongs to another document
- const int index(std::shared_ptr<ModelAPI_Object> theObject);
+ const int index(std::shared_ptr<ModelAPI_Object> theObject,
+ const bool theAllowFolder = false);
//! Returns the feature in the group by the index (started from zero)
//! \param theGroupID group that contains a feature
//! \param theIndex zero-based index of feature in the group
- ObjectPtr object(const std::string& theGroupID, const int theIndex);
+ //! \param theAllowFolder take into account grouping feature by folders
+ ObjectPtr object(const std::string& theGroupID,
+ const int theIndex,
+ const bool theAllowFolder = false);
//! Returns the number of features in the group
- int size(const std::string& theGroupID);
+ //! \param theGroupID group of objects
+ //! \param theAllowFolder take into account grouping feature by folders
+ int size(const std::string& theGroupID, const bool theAllowFolder = false);
//! Returns all (and disabled) results of the given type.
//! Not fast method (iterates all features).
std::shared_ptr<ModelAPI_Feature>
feature(const std::shared_ptr<ModelAPI_Result>& theResult);
+ /// Creates a folder (group of the features in the object browser)
+ std::shared_ptr<ModelAPI_Folder> createFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theBeforeThis);
+ //! Removes the folder from the document (all features in the folder will be kept).
+ void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder);
+ //! Search a folder applicable for the list of features
+ //! (it means the list of features stored in the folder should be consequential)
+ //! \param theFeatures list of features to be added to folder
+ //! \param theBelow search the folder below the features (if \c false, search above)
+ //! \return Empty pointer if there is no applicable folder
+ std::shared_ptr<ModelAPI_Folder> findFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBelow);
+ //! Search a folder containing the given feature.
+ //! Addtionally calculates a zero-based index of the feature in this folder.
+ //! \param theFeature feature to search
+ //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+ //! \return the folder containing the feature or empty pointer if the feature is top-level.
+ std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ int& theIndexInFolder);
+ //! Add a list of features to the folder. The correctness of the adding is not performed
+ //! (such checks have been done in corresponding find.. method).
+ //! \return \c true if the movement is successfull
+ bool moveToFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder);
+ //! Remove features from the folder
+ //! \param theFeatures list of features to be removed
+ //! \param theBefore extract features before the folder (this parameter is applicable only
+ //! when all features in the folder are taking out,
+ //! in other cases the direction is taken automatically)
+ //! \return \c true if the features have been moved out
+ bool removeFromFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore = true);
+
//! Sets the owner of this manager
void setOwner(DocumentPtr theDoc);
//! feature type + "_" + index
void setUniqueName(FeaturePtr theFeature);
+ //! Initializes the foldet with an unique name ("Folder_" + index)
+ void setUniqueName(FolderPtr theFolder);
+
//! Synchronizes myFeatures list with the updated document
//! \param theUpdated list of labels that are marked as modified, so featrues must be also
//! \param theUpdateReferences causes the update of back-references
/// Returns true if theLater is in history of features creation later than theCurrent
bool isLater(FeaturePtr theLater, FeaturePtr theCurrent) const;
+ /// Returns the next or previous label
+ /// \param theCurrent given label
+ /// \param theReverse if it is true, iterates in reverced order (next becomes previous)
+ TDF_Label nextLabel(TDF_Label theCurrent, const bool theReverse = false);
+
/// Returns the result group identifier of the given feature (for this at least one result must
/// be created before)
std::string featureResultGroup(FeaturePtr theFeature);
//! history. Not very fast method, for calling once, not in big cycles.
std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures();
+ //! Returns all objects of the document including the hidden features which are not in
+ //! history. Not very fast method, for calling once, not in big cycles.
+ std::list<std::shared_ptr<ModelAPI_Object> > allObjects();
+
//! synchronises back references for the given object basing on the collected data
void synchronizeBackRefsForObject(
const std::set<std::shared_ptr<ModelAPI_Attribute>>& theNewRefs, ObjectPtr theObject);
int theResultIndex,
std::string& theParentName) const;
+ /// Return object representing a folder or empty pointer
+ ObjectPtr folder(TDF_Label theLabel) const;
+
private:
TDF_Label myMain; ///< main label of the data storage
/// For optimization mapped by labels
NCollection_DataMap<TDF_Label, FeaturePtr> myFeatures;
+ /// Managed folders
+ NCollection_DataMap<TDF_Label, ObjectPtr> myFolders;
+
/// Map from group id to the array that contains all objects located in history.
/// Each array is updated by demand from scratch, by browing all the features in the history.
std::map<std::string, std::vector<ObjectPtr> > myHistory;
}
// stores shape and name on sub-label of the main stored shape
-static void saveSubName(TDF_Label& theLab, const bool isSelectionMode, const TopoDS_Shape& aSub,
+static void saveSubName(CompositeFeaturePtr theComposite,
+ TDF_Label& theLab, const bool isSelectionMode, TopoDS_Shape aSub,
std::shared_ptr<Model_Document> theDoc, std::string theFullName)
{
+ // trying to store the edge of composite result, not sketch sub as it is
+ if (aSub.ShapeType() == TopAbs_EDGE) {
+ ResultPtr aRes = theComposite->firstResult();
+ ResultConstructionPtr aConstr = std::dynamic_pointer_cast<Model_ResultConstruction>(aRes);
+ if (aConstr.get()) {
+ Standard_Real aSubFirst, aSubLast;
+ TopoDS_Edge aSubEdge = TopoDS::Edge(aSub);
+ Handle(Geom_Curve) aSubCurve = BRep_Tool::Curve(aSubEdge, aSubFirst, aSubLast);
+ for(int aFaceIndex = 0; aFaceIndex < aConstr->facesNum(); aFaceIndex++) {
+ GeomShapePtr aGFace = aConstr->face(aFaceIndex);
+ TopoDS_Shape aFace = aGFace->impl<TopoDS_Shape>();
+ for(TopExp_Explorer anExp(aFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+ TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (aCurve == aSubCurve &&
+ ((fabs(aFirst - aSubFirst) < 1.e-9 && fabs(aLast - aSubLast) < 1.e-9)) ||
+ (fabs(aFirst - aSubLast) < 1.e-9 && fabs(aLast - aSubFirst) < 1.e-9)) {
+ aSub = anEdge;
+ break;
+ }
+ }
+ }
+ }
+ }
+
TNaming_Builder aBuilder(theLab);
if (isSelectionMode)
aBuilder.Select(aSub, aSub);
TDF_Label aSubLab = aLab.FindChild(anID);
TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
std::string aFullNameSub = fullName(aComposite, anEdge);
- saveSubName(aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
+ saveSubName(aComposite,
+ aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
if (anOrient != 0) {
TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current());
TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
std::string aFullNameSub = fullName(aComposite, aV);
- saveSubName(aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
+ saveSubName(aComposite,
+ aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
}
}
}
#include <TNaming_Tool.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Localizer.hxx>
+#include <TNaming_SameShapeIterator.hxx>
#include <TDataStd_Name.hxx>
#include <TColStd_MapOfTransient.hxx>
#include <algorithm>
myLab = theSelectionLab;
}
+// searches named shape by the shape in the given document (identified by the label)
+// tries to find s shape nearest to the context-label
+static Handle(TNaming_NamedShape) shapeToNS(const TDF_Label theLabAccess,
+ const TopoDS_Shape& theShape, const TDF_Label& theContextLab)
+{
+ Handle(TNaming_NamedShape) aResult;
+ if (!TNaming_Tool::HasLabel(theLabAccess, theShape)) // no shape in the document
+ return aResult;
+ int aContextLabDepth = theContextLab.IsNull() ? 100 : theContextLab.Depth();
+ TNaming_SameShapeIterator aNSIter(theShape, theLabAccess);
+ for(; aNSIter.More(); aNSIter.Next()) {
+ TDF_Label aLabel = aNSIter.Label();
+ Handle(TNaming_NamedShape) aNS;
+ if (aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ if (aNS->Evolution() != TNaming_SELECTED && aNS->Evolution() != TNaming_DELETE) {
+ // check this is new shape in this named shape
+ bool aIsNew = false;
+ for(TNaming_Iterator aNSIter(aNS); aNSIter.More(); aNSIter.Next())
+ if (!aNSIter.NewShape().IsNull() && aNSIter.NewShape().IsSame(theShape))
+ aIsNew = true;
+ if (!aIsNew)
+ continue;
+ // check this is the context-shape
+ while(aLabel.Depth() > aContextLabDepth)
+ aLabel = aLabel.Father();
+ if (aLabel.IsEqual(theContextLab))
+ return aNS;
+ if (aResult.IsNull()) // take the first, otherwise it will get shapes from results, etc
+ aResult = aNS; // keep some result anyway - if there are no context labels return any
+ }
+ }
+ }
+ return aResult;
+}
+
std::string Model_SelectionNaming::getShapeName(
std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
ResultPtr& theContext, const bool theAnotherDoc, const bool theWholeContext)
// (it was in BodyBuilder, but did not work on Result rename)
bool isNeedContextName = theContext->shape().get() != NULL;
// check if the subShape is already in DF
- Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(theShape, myLab);
+ std::shared_ptr<Model_Data> aData =
+ std::dynamic_pointer_cast<Model_Data>(theContext->data());
+ TDF_Label aContextDataLab(aData.get() && aData->isValid() ? aData->label() : TDF_Label());
+ Handle(TNaming_NamedShape) aNS = shapeToNS(myLab, theShape, aContextDataLab);
Handle(TDataStd_Name) anAttr;
if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document
if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) {
- std::shared_ptr<Model_Data> aData =
- std::dynamic_pointer_cast<Model_Data>(theContext->data());
- if (isNeedContextName && aData && aData->label().IsEqual(aNS->Label())) {
+ if (isNeedContextName && aData && aContextDataLab.IsEqual(aNS->Label())) {
// do nothing because this context name will be added later in this method
} else {
aName = TCollection_AsciiString(anAttr->Get()).ToCString();
break;
int n = aList.Extent();
bool isByFaces = n >= 3;
+ if (isByFaces) { // check that by faces vertex is identified uniquly (2317)
+ TopoDS_Shape aVertex = findCommonShape(TopAbs_VERTEX, aList);
+ isByFaces = !aVertex.IsNull() && aVertex.ShapeType() == TopAbs_VERTEX;
+ }
if(!isByFaces) { // open topology case or Compound case => via edges
TopTools_IndexedDataMapOfShapeListOfShape aMap;
TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
aFaceContext = aDoc->findByName(aContName, *it, anUniqueContext);
}
}
- const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
+ TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
+ if (aFace.IsNull() && aFaceContext.get() &&
+ aFaceContext->groupName() == ModelAPI_ResultConstruction::group() ) {
+ // search the construction sub-elements for the intersection if they are in the tree
+ size_t aSlash = it->find("/");
+ if (aSlash != std::string::npos) {
+ std::string aSubShapeName = it->substr(aSlash + 1);
+ aFace = findFaceByName(aSubShapeName, aDoc, aFaceContext, true);
+ }
+ }
if(!aFace.IsNull())
aList.Append(aFace);
}
}
// in case of construction, there is no registered names for all sub-elements,
// even for the main element; so, trying to find them by name (without "&" intersections)
- if (aN < 2) {
+ if (aSelection.IsNull() && aN < 2) {
size_t aConstrNamePos = aSubShapeName.find("/");
bool isFullName = aConstrNamePos == std::string::npos;
std::string anEmpty, aContrName = aContName;
ModelAPI_Expression.h
ModelAPI_Feature.h
ModelAPI_FeatureValidator.h
+ ModelAPI_Folder.h
ModelAPI_IReentrant.h
ModelAPI_Object.h
ModelAPI_Plugin.h
ModelAPI_Expression.cpp
ModelAPI_Feature.cpp
ModelAPI_FeatureValidator.cpp
+ ModelAPI_Folder.cpp
ModelAPI_IReentrant.cpp
ModelAPI_Object.cpp
ModelAPI_Plugin.cpp
TestCustomName_Rename.py
TestCustomName_RotateGroup.py
TestCustomName_Translation.py
+ TestFolder_Create.py
+ TestFolder_Update.py
+ TestFolder_Remove.py
+ TestFolder_Stability.py
)
%feature("director") ModelAPI_Feature;
%feature("director") ModelAPI_CompositeFeature;
%feature("director") ModelAPI_Data;
+%feature("director") ModelAPI_Folder;
// shared pointers
// For ModelAPI_ResultConstruction.shape()
%shared_ptr(ModelAPI_Feature)
%shared_ptr(ModelAPI_CompositeFeature)
%shared_ptr(ModelAPI_Data)
+%shared_ptr(ModelAPI_Folder)
%shared_ptr(ModelAPI_Attribute)
%shared_ptr(ModelAPI_AttributeDocRef)
%shared_ptr(ModelAPI_AttributeDouble)
}
}
+%apply int& OUTPUT {int& theIndexInFolder};
+
// all supported interfaces
%include "ModelAPI_Entity.h"
%include "ModelAPI_Document.h"
%include "ModelAPI_ResultParameter.h"
%include "ModelAPI_Tools.h"
%include "ModelAPI_ResultCompSolid.h"
+%include "ModelAPI_Folder.h"
// std::list -> []
%template(StringList) std::list<std::string>;
%template(featureToCompositeFeature) shared_ptr_cast<ModelAPI_CompositeFeature, ModelAPI_Feature>;
%template(objectToFeature) shared_ptr_cast<ModelAPI_Feature, ModelAPI_Object>;
%template(objectToResult) shared_ptr_cast<ModelAPI_Result, ModelAPI_Object>;
+%template(objectToFolder) shared_ptr_cast<ModelAPI_Folder, ModelAPI_Object>;
%template(compositeFeatureToFeature) shared_ptr_cast<ModelAPI_Feature, ModelAPI_CompositeFeature>;
%template(modelAPI_Result) shared_ptr_cast<ModelAPI_Result, ModelAPI_Object>;
/// Returns the name of the feature visible by the user in the object browser
virtual std::string name() = 0;
-
/// Defines the name of the feature visible by the user in the object browser
virtual void setName(const std::string& theName) = 0;
+ /// Return \c true if the object has been renamed by the user
+ virtual bool hasUserDefinedName() const = 0;
/// Returns the attribute that references to another document
virtual std::shared_ptr<ModelAPI_AttributeDocRef> document(const std::string& theID) = 0;
#include <set>
class ModelAPI_Feature;
+class ModelAPI_Folder;
class ModelAPI_Object;
class ModelAPI_Result;
class ModelAPI_ResultConstruction;
//! Returns the object in the group by the index (started from zero)
//! \param theGroupID group that contains an object
//! \param theIndex zero-based index of feature in the group
+ //! \param theAllowFolder take into account grouping feature by folders
virtual std::shared_ptr<ModelAPI_Object> object(const std::string& theGroupID,
- const int theIndex) = 0;
+ const int theIndex,
+ const bool theAllowFolder = false) = 0;
//! Returns the first found object in the group by the object name
//! \param theGroupID group that contains an object
//! Returns the object index in the group. Object must be visible. Otherwise returns -1.
//! \param theObject object of this document
+ //! \param theAllowFolder take into account grouping feature by folders
//! \returns index started from zero, or -1 if object is invisible or belongs to another document
- virtual const int index(std::shared_ptr<ModelAPI_Object> theObject) = 0;
+ virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
+ const bool theAllowFolder = false) = 0;
//! Returns the number of objects in the group of objects
- virtual int size(const std::string& theGroupID) = 0;
+ //! \param theGroupID group of objects
+ //! \param theAllowFolder take into account grouping feature by folders
+ virtual int size(const std::string& theGroupID, const bool theAllowFolder = false) = 0;
//! Returns the feature that is currently edited in this document, normally
//! this is the latest created feature
//! history. Not very fast method, for calling once, not in big cycles.
virtual std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures() = 0;
+ //! Returns all objects of the document including the hidden features which are not in
+ //! history. Not very fast method, for calling once, not in big cycles.
+ virtual std::list<std::shared_ptr<ModelAPI_Object> > allObjects() = 0;
+
+ //! Creates a folder (group of the features in the object browser)
+ //! \param theAddBefore a feature, the folder is added before
+ //! (if empty, the folder is added after the last feature)
+ virtual std::shared_ptr<ModelAPI_Folder> addFolder(
+ std::shared_ptr<ModelAPI_Feature> theAddBefore = std::shared_ptr<ModelAPI_Feature>()) = 0;
+ //! Removes the folder from the document (all features in the folder will be kept).
+ virtual void removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder) = 0;
+ //! Search a folder above the list of features applicable to store them
+ //! (it means the list of features stored in the folder should be consequential)
+ //! \return Empty pointer if there is no applicable folder
+ virtual std::shared_ptr<ModelAPI_Folder> findFolderAbove(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures) = 0;
+ //! Search a folder below the list of features applicable to store them
+ //! (it means the list of features stored in the folder should be consequential)
+ //! \return Empty pointer if there is no applicable folder
+ virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures) = 0;
+ //! Search a folder containing the given feature.
+ //! Addtionally calculates a zero-based index of the feature in this folder.
+ //! \param theFeature feature to search
+ //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+ //! \return the folder containing the feature or empty pointer if the feature is top-level.
+ virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ int& theIndexInFolder) = 0;
+ //! Add a list of features to the folder. The correctness of the adding is not performed
+ //! (such checks have been done in corresponding find.. method).
+ //! \return \c true if the movement is successfull
+ virtual bool moveToFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const std::shared_ptr<ModelAPI_Folder>& theFolder) = 0;
+ //! Remove features from the folder
+ //! \param theFeatures list of features to be removed
+ //! \param theBefore extract features before the folder (this parameter is applicable only
+ //! when all features in the folder are taking out,
+ //! in other cases the direction is taken automatically)
+ //! \return \c true if the features have been moved out
+ virtual bool removeFromFolder(
+ const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
+ const bool theBefore = true) = 0;
+
//! Informs the document that it becomes active and some actions must be performed
virtual void setActive(const bool theFlag) = 0;
//! Returns true if this document is currently active
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModelAPI_Folder.h"
+
+#include <ModelAPI_AttributeReference.h>
+
+ModelAPI_Folder::ModelAPI_Folder()
+{
+}
+
+ModelAPI_Folder::~ModelAPI_Folder()
+{
+}
+
+void ModelAPI_Folder::init()
+{
+}
+
+void ModelAPI_Folder::initAttributes()
+{
+ data()->addAttribute(FIRST_FEATURE_ID(), ModelAPI_AttributeReference::typeId());
+ data()->addAttribute(LAST_FEATURE_ID(), ModelAPI_AttributeReference::typeId());
+}
+
+void ModelAPI_Folder::execute()
+{
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModelAPI_Folder_H_
+#define ModelAPI_Folder_H_
+
+#include <ModelAPI.h>
+#include <ModelAPI_Object.h>
+
+/**\class ModelAPI_Folder
+ * \ingroup DataModel
+ * \brief Folder feature (groups the features).
+ */
+class ModelAPI_Folder : public ModelAPI_Object
+{
+public:
+ MODELAPI_EXPORT ModelAPI_Folder();
+ /// To virtually destroy the fields of successors
+ MODELAPI_EXPORT virtual ~ModelAPI_Folder();
+
+ /// Folder feature ID
+ static const std::string& ID()
+ {
+ static const std::string MY_FOLDER_ID("Folder");
+ return MY_FOLDER_ID;
+ }
+
+ /// Returns the group identifier of all features
+ inline static std::string group()
+ {
+ static std::string MY_GROUP = "Folders";
+ return MY_GROUP;
+ }
+
+ /// Returns the group identifier of this result
+ virtual std::string groupName()
+ {
+ return group();
+ }
+
+ /// Attribute referring first feature in the folder
+ static const std::string& FIRST_FEATURE_ID()
+ {
+ static const std::string MY_FIRST_FEATURE_ID("first_feature");
+ return MY_FIRST_FEATURE_ID;
+ }
+
+ /// Attribute referring last feature in the folder
+ static const std::string& LAST_FEATURE_ID()
+ {
+ static const std::string MY_LAST_FEATURE_ID("last_feature");
+ return MY_LAST_FEATURE_ID;
+ }
+
+ /// Request for initialization of data model of the object: adding all attributes
+ MODELAPI_EXPORT virtual void initAttributes();
+
+ /// Computes or recomputes the results
+ MODELAPI_EXPORT virtual void execute();
+
+ /// Returns the feature is disabled or not.
+ virtual bool isDisabled()
+ { return false; }
+
+ //
+ // Helper methods, aliases for data()->method()
+ // -----------------------------------------------------------------------------------------------
+ /// Returns the name stored in the attribute
+ inline std::string name()
+ {
+ return data()->name();
+ }
+ /// Returns the reference attribute by the identifier
+ inline std::shared_ptr<ModelAPI_AttributeReference> reference(const std::string& theID)
+ {
+ return data()->reference(theID);
+ }
+
+protected:
+ /// This method is called just after creation of the object: it must initialize
+ /// all fields, normally initialized in the constructor
+ MODELAPI_EXPORT virtual void init();
+};
+
+//! Pointer on a folder object
+typedef std::shared_ptr<ModelAPI_Folder> FolderPtr;
+
+#endif
return ModelAPI_Tools::removeFeatures(aFeatures, false);
}
+//***********************************************************************
bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
const bool theFlushRedisplay)
{
return true;
}
+//***********************************************************************
// Fills the references list by all references of the feature from the references map.
// This is a recusive method to find references by next found feature in the map of references.
// \param theFeature a feature to find references
}
}
-std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
- const int theResultIndex)
+std::pair<std::string, bool> getDefaultName(
+ const std::shared_ptr<ModelAPI_Result>& theResult,
+ const int theResultIndex)
{
typedef std::list< std::pair < std::string, std::list<ObjectPtr> > > ListOfReferences;
if (aCompSolidRes == *anIt)
break;
aDefaultName << "_" << (aCompSolidResultIndex + 1) << "_" << (theResultIndex + 1);
- return aDefaultName.str();
+ return std::pair<std::string, bool>(aDefaultName.str(), false);
}
DataPtr aData = anOwner->data();
ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(anObjRes);
if (aParentCompSolid)
anObjRes = aParentCompSolid;
- return anObjRes->data()->name();
+
+ // return name of reference result only if it has been renamed by the user,
+ // in other case compose a default name
+ if (anObjRes->data()->hasUserDefinedName())
+ return std::pair<std::string, bool>(anObjRes->data()->name(), true);
}
}
// add unique prefix starting from second
if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
aDefaultName << "_" << theResultIndex + 1;
- return aDefaultName.str();
+ return std::pair<std::string, bool>(aDefaultName.str(), false);
}
} // namespace ModelAPI_Tools
std::list<std::shared_ptr<ModelAPI_Result> >& theResults);
/*! Return the default name of the result according the the features it depends.
+ * Return also whether the name is get from the concealing result of parent object
+ * (means that concealing result has user-defined name).
*/
-MODELAPI_EXPORT std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
- const int theResultIndex);
+MODELAPI_EXPORT std::pair<std::string, bool> getDefaultName(
+ const std::shared_ptr<ModelAPI_Result>& theResult,
+ const int theResultIndex);
}
#endif
#include "ModelAPI_ResultField.h"
#include "ModelAPI_Tools.h"
#include "ModelAPI_ResultCompSolid.h"
+ #include "ModelAPI_Folder.h"
#include <memory>
#include <string>
aSession.abortOperation()
# check faces
-check_owner("_Extrusion_1_1/Generated_Face_1", "face", aBox)
-check_owner("Extrusion_3_1/Modified_3", "face", aBox)
-check_owner("Extrusion_1_1/Modified_1", "face", aHoleExt)
-check_owner("Extrusion_3_1/Modified_2", "face", aTower)
+check_owner("Extrusion_1_1/Generated_Face_1", "face", aBox)
+check_owner("Boolean_2_1/Modified_Face_3", "face", aBox)
+check_owner("Boolean_1_1/Modified_Face_1", "face", aHoleExt)
+check_owner("Boolean_2_1/Modified_Face_2", "face", aTower)
# check edges without ambiguity
-check_owner("Extrusion_3_1/Modified_3&_Extrusion_1_1/Generated_Face_2", "edge", aBox)
-check_owner("Extrusion_3_1/Modified_2&_Extrusion_3_1/To_Face_1", "edge", aTower)
+check_owner("Boolean_2_1/Modified_Face_3&Extrusion_1_1/Generated_Face_2", "edge", aBox)
+check_owner("Boolean_2_1/Modified_Face_2&Extrusion_3_1/To_Face_1_1", "edge", aTower)
# check the connected topology method: solid is not a compound of connected topology
assert(aFuse.firstResult().shape().isConnectedTopology() == False)
#=========================================================================
# Make a cylindrical hole using one of the produced faces
#=========================================================================
-ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Modfied_4"))
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"))
SketchCircle_1 = Sketch_3.addCircle(143.412751420315, -228.52745656314, 32.158435160764)
ExtrusionCut_2.setNestedSketch(Sketch_3)
#=========================================================================
# Modify the cylindrical hole base face by another groove in the history before the hole is created
#=========================================================================
-ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "__Extrusion_1_1/Generated_Face_3"), -50, [model.selection("SOLID", "Extrusion_1_1")])
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "__Extrusion_1_1/Generated_Face_1"))
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), -50, [model.selection("SOLID", "ExtrusionCut_1_1")])
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
SketchLine_9 = Sketch_4.addLine(-176.701443076057, -151.212050129331, -91.83965287802501, -151.212050129331)
SketchLine_10 = Sketch_4.addLine(-91.83965287802501, -151.212050129331, -91.83965287802501, -84.473709256573)
SketchLine_11 = Sketch_4.addLine(-91.83965287802501, -84.473709256573, -176.701443076057, -84.473709256573)
assert(ModelAPI.ModelAPI_Session.get().validators().validate(Sketch_4.feature()))
assert(ModelAPI.ModelAPI_Session.get().validators().validate(ExtrusionCut_2.feature()))
-assert(Sketch_3.feature().selection("External").namingName() == "_Extrusion_1_1/Modfied_4")
+assert(Sketch_3.feature().selection("External").namingName() == "ExtrusionCut_3_1/Modfied_5")
assert(model.checkPythonDump())
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "tutu/Face-SketchLine_1f-SketchLine_3f-SketchArc_1_2f-SketchArc_2_2f")], model.selection(), 10, 0)
Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "tutu/Edge-SketchLine_2")])
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("EDGE", "PartSet/OZ"), 100, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Edge_1_1/Generated_Edge_2&Edge_1_1/To_Edge_1"), model.selection("VERTEX", "Edge_1_1/Generated_Edge_1&Edge_1_1/To_Edge_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Extrusion_2_1/Generated_Edge_2&Extrusion_2_1/To_Edge_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Edge_1&Extrusion_2_1/To_Edge_1")])
model.end()
# check that resulting group selection is valid
SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_4.result())
model.do()
Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_1")])
-Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "_Extrusion_2_1/From_Face_1"), 0, model.selection(), 0)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "Extrusion_2_1/From_Face_1"), 0, model.selection(), 0)
Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_4_1")])
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("FACE", "Face_1_1")])
-Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Extrusion_1_1"))
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Boolean_1_1"), model.selection("SOLID", "Boolean_2_1"), model.selection("FACE", "Face_1_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Partition_1_1"))
Remove_SubShapes_1.setSubShapesToKeep([model.selection("COMPSOLID", "Partition_1_1_1")])
model.end()
MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Face_5_1")], model.selection("EDGE", "PartSet/OX"), "l", 4, model.selection("EDGE", "PartSet/OY"), "l", 2)
Recover_1 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_1_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"))
-Translation_1.result().setName("Translation_1_1")
MultiTranslation_2 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_1_1")], model.selection("EDGE", "PartSet/OX"), "l", 4, model.selection("EDGE", "PartSet/OY"), "l", 2)
Recover_2 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_2&Face_4_1/Edge_3"))
-Translation_2.result().setName("Translation_2_1")
MultiTranslation_3 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_2_1")], model.selection("EDGE", "PartSet/OX"), "l", 4)
Recover_3 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
-Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Translation_2_1/Translated_Edge_1_4&Translation_2_1/Translated_Edge_1_3"))
-Translation_3.result().setName("Translation_3_1")
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "LinearCopy_3_1/Translated_Edge_1_4&LinearCopy_3_1/Translated_Edge_1_3"))
MultiTranslation_4 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_3_1")], model.selection("EDGE", "PartSet/OX"), "l", 3)
Recover_4 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"), model.selection("VERTEX", "Face_4_1/Edge_1&Face_4_1/Edge_9"))
-Translation_4.result().setName("Translation_4_1")
MultiTranslation_5 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_4_1")], model.selection("EDGE", "PartSet/OX"), "l", 2)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "MultiTranslation_4_1_2"), model.selection("FACE", "MultiTranslation_1_1_8"), model.selection("FACE", "MultiTranslation_1_1_4"), model.selection("FACE", "MultiTranslation_1_1_3"), model.selection("FACE", "MultiTranslation_1_1_6"), model.selection("FACE", "MultiTranslation_1_1_2"), model.selection("FACE", "MultiTranslation_1_1_7"), model.selection("FACE", "MultiTranslation_2_1_3"), model.selection("FACE", "MultiTranslation_3_1_4"), model.selection("FACE", "MultiTranslation_2_1_8"), model.selection("FACE", "MultiTranslation_2_1_4"), model.selection("FACE", "MultiTranslation_2_1_7"), model.selection("FACE", "MultiTranslation_4_1_3"), model.selection("FACE", "MultiTranslation_1_1_1"), model.selection("FACE", "MultiTranslation_5_1_2"), model.selection("FACE", "MultiTranslation_4_1_1"), model.selection("FACE", "MultiTranslation_5_1_1"), model.selection("FACE", "MultiTranslation_3_1_3"), model.selection("FACE", "MultiTranslation_3_1_2"), model.selection("FACE", "MultiTranslation_3_1_1"), model.selection("FACE", "MultiTranslation_2_1_6"), model.selection("FACE", "MultiTranslation_2_1_2"), model.selection("FACE", "MultiTranslation_2_1_5"), model.selection("FACE", "MultiTranslation_2_1_1"), model.selection("FACE", "MultiTranslation_1_1_5")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "LinearCopy_4_1_2"), model.selection("FACE", "LinearCopy_1_1_8"), model.selection("FACE", "LinearCopy_1_1_4"), model.selection("FACE", "LinearCopy_1_1_3"), model.selection("FACE", "LinearCopy_1_1_6"), model.selection("FACE", "LinearCopy_1_1_2"), model.selection("FACE", "LinearCopy_1_1_7"), model.selection("FACE", "LinearCopy_2_1_3"), model.selection("FACE", "LinearCopy_3_1_4"), model.selection("FACE", "LinearCopy_2_1_8"), model.selection("FACE", "LinearCopy_2_1_4"), model.selection("FACE", "LinearCopy_2_1_7"), model.selection("FACE", "LinearCopy_4_1_3"), model.selection("FACE", "LinearCopy_1_1_1"), model.selection("FACE", "LinearCopy_5_1_2"), model.selection("FACE", "LinearCopy_4_1_1"), model.selection("FACE", "LinearCopy_5_1_1"), model.selection("FACE", "LinearCopy_3_1_3"), model.selection("FACE", "LinearCopy_3_1_2"), model.selection("FACE", "LinearCopy_3_1_1"), model.selection("FACE", "LinearCopy_2_1_6"), model.selection("FACE", "LinearCopy_2_1_2"), model.selection("FACE", "LinearCopy_2_1_5"), model.selection("FACE", "LinearCopy_2_1_1"), model.selection("FACE", "LinearCopy_1_1_5")])
Group_1.setName("Group_3")
Group_1.result().setName("assemblages")
Group_2 = model.addGroup(Part_1_doc, [model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_12")])
Group_3.setName("Group_2")
Group_3.result().setName("acier")
Group_3.result().setColor(170, 85, 0)
-Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "MultiTranslation_1_1_1"), model.selection("FACE", "MultiTranslation_1_1_2"), model.selection("FACE", "MultiTranslation_1_1_3"), model.selection("FACE", "MultiTranslation_1_1_4"), model.selection("FACE", "MultiTranslation_1_1_5"), model.selection("FACE", "MultiTranslation_1_1_6"), model.selection("FACE", "MultiTranslation_1_1_7"), model.selection("FACE", "MultiTranslation_2_1_4"), model.selection("FACE", "MultiTranslation_2_1_5"), model.selection("FACE", "MultiTranslation_2_1_6"), model.selection("FACE", "MultiTranslation_2_1_7"), model.selection("FACE", "MultiTranslation_2_1_8"), model.selection("FACE", "MultiTranslation_2_1_1"), model.selection("FACE", "MultiTranslation_2_1_2"), model.selection("FACE", "MultiTranslation_2_1_3"), model.selection("FACE", "MultiTranslation_3_1_4"), model.selection("FACE", "MultiTranslation_3_1_3"), model.selection("FACE", "MultiTranslation_3_1_2"), model.selection("FACE", "MultiTranslation_3_1_1"), model.selection("FACE", "MultiTranslation_4_1_1"), model.selection("FACE", "MultiTranslation_4_1_2"), model.selection("FACE", "MultiTranslation_4_1_3"), model.selection("FACE", "MultiTranslation_5_1_1"), model.selection("FACE", "MultiTranslation_5_1_2"), model.selection("FACE", "MultiTranslation_1_1_8")])
-Shell_1.result().setName("Shell_1_1")
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "LinearCopy_1_1_1"), model.selection("FACE", "LinearCopy_1_1_2"), model.selection("FACE", "LinearCopy_1_1_3"), model.selection("FACE", "LinearCopy_1_1_4"), model.selection("FACE", "LinearCopy_1_1_5"), model.selection("FACE", "LinearCopy_1_1_6"), model.selection("FACE", "LinearCopy_1_1_7"), model.selection("FACE", "LinearCopy_2_1_4"), model.selection("FACE", "LinearCopy_2_1_5"), model.selection("FACE", "LinearCopy_2_1_6"), model.selection("FACE", "LinearCopy_2_1_7"), model.selection("FACE", "LinearCopy_2_1_8"), model.selection("FACE", "LinearCopy_2_1_1"), model.selection("FACE", "LinearCopy_2_1_2"), model.selection("FACE", "LinearCopy_2_1_3"), model.selection("FACE", "LinearCopy_3_1_4"), model.selection("FACE", "LinearCopy_3_1_3"), model.selection("FACE", "LinearCopy_3_1_2"), model.selection("FACE", "LinearCopy_3_1_1"), model.selection("FACE", "LinearCopy_4_1_1"), model.selection("FACE", "LinearCopy_4_1_2"), model.selection("FACE", "LinearCopy_4_1_3"), model.selection("FACE", "LinearCopy_5_1_1"), model.selection("FACE", "LinearCopy_5_1_2"), model.selection("FACE", "LinearCopy_1_1_8")])
Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_4_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_12"), model.selection("SHELL", "Shell_1_1")])
-Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Face_3_1"))
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Partition_1_1"))
Remove_SubShapes_1.setSubShapesToKeep([model.selection("FACE", "Partition_1_1_2"), model.selection("FACE", "Partition_1_1_3"), model.selection("FACE", "Partition_1_1_4"), model.selection("FACE", "Partition_1_1_5"), model.selection("FACE", "Partition_1_1_6"), model.selection("FACE", "Partition_1_1_7"), model.selection("FACE", "Partition_1_1_8"), model.selection("FACE", "Partition_1_1_9")])
model.end()
Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
model.end()
-# check that group 2 is correct, but Group_1 and Group_3 elements are removed (because shell is removed)
+# check that group 2 is correct (some subs are removed), but Group_1 and Group_3 elements are removed (because shell is removed)
from ModelAPI import *
aFactory = ModelAPI_Session.get().validators()
-assert(Group_1.groupList().size() != 0)
-for a in range(Group_1.groupList().size()):
- assert(len(Group_1.groupList().value(a).namingName()) == 0)
+assert(Group_2.groupList().size() != 0)
+for a in range(Group_2.groupList().size()):
+ if not Group_1.groupList().value(a).context() is None:
+ assert(len(Group_1.groupList().value(a).namingName()) == 0)
-assert(aFactory.validate(Group_3.feature()))
-assert(Group_3.groupList().size() != 0)
-for a in range(Group_3.groupList().size()):
- assert(Group_3.groupList().value(a).value().shapeTypeStr() == "FACE")
- assert(len(Group_3.groupList().value(a).namingName()) > 0)
+#assert(aFactory.validate(Group_3.feature()))
+#assert(Group_3.groupList().size() != 0)
+#for a in range(Group_3.groupList().size()):
+# assert(Group_3.groupList().value(a).value().shapeTypeStr() == "FACE")
+# assert(len(Group_3.groupList().value(a).namingName()) > 0)
# for Group in [Group_1, Group_2, Group_3]:
# if Group == Group_2:
SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
SketchPoint_2 = SketchProjection_2.createdFeature()
-SketchConstraintDistanceVertical_1 = Sketch_2.setVerticalDistance(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_7.endPoint(), -5)
-SketchConstraintDistanceHorizontal_1 = Sketch_2.setHorizontalDistance(SketchLine_8.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -10)
+SketchConstraintDistanceVertical_1 = Sketch_2.setVerticalDistance(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_7.endPoint(), 5)
+SketchConstraintDistanceHorizontal_1 = Sketch_2.setHorizontalDistance(SketchLine_8.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 10)
SketchConstraintLength_3 = Sketch_2.setLength(SketchLine_8.result(), 60)
SketchConstraintLength_4 = Sketch_2.setLength(SketchLine_7.result(), 40)
model.do()
SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_5.result(), SketchLine_6.result())
SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 80)
-SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_6.startPoint(), SketchLine_1.endPoint(), -20)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_6.startPoint(), SketchLine_1.endPoint(), 20)
SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_1.startPoint(), 15)
-SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchLine_6.endPoint(), SketchLine_1.startPoint(), -50)
+SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchLine_6.endPoint(), SketchLine_1.startPoint(), 50)
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 50, 0)
Extrusion_1.result().setName("compsolid")
SketchCircle_1 = Sketch_1.addCircle(30, 70, 20)
SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 20)
SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 30, True)
-SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchLine_2.startPoint(), -30)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchLine_2.startPoint(), 30)
SketchLine_5 = Sketch_1.addLine(12.50000000006628, -45.31088913249455, 30, -15)
SketchLine_6 = Sketch_1.addLine(30, -15, 47.50000000006629, -45.31088913249455)
SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_6.result())
SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_7.result(), 35)
-SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_2.startPoint(), -30)
+SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_2.startPoint(), 30)
SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_5.endPoint(), SketchLine_2.startPoint(), 15)
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 10, 0)
SketchConstraintLength_5 = Sketch_2.setLength(SketchLine_9.result(), 130)
SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "box/Generated_Face_3&box/Generated_Face_2&box/From_Face_1"), False)
SketchPoint_2 = SketchProjection_2.createdFeature()
-SketchConstraintDistanceVertical_2 = Sketch_2.setVerticalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -30)
-SketchConstraintDistanceHorizontal_3 = Sketch_2.setHorizontalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), -25)
+SketchConstraintDistanceVertical_2 = Sketch_2.setVerticalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 30)
+SketchConstraintDistanceHorizontal_3 = Sketch_2.setHorizontalDistance(SketchLine_8.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 25)
model.do()
Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_8f-SketchLine_9f-SketchLine_10f-SketchLine_11f")], model.selection(), 5, 15)
Extrusion_4.result().setName("cut_tool")
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-22"
+
+#=========================================================================
+# Test 1. Check the Folder is created in PartSet
+#=========================================================================
+aSession = ModelAPI_Session.get()
+aPartSetDoc = aSession.activeDocument()
+
+aSession.startOperation()
+aPoint0 = aPartSetDoc.addFeature("Point")
+aPoint0Data = aPoint0.data()
+assert(aPoint0Data is not None)
+aPoint0Data.real("x").setValue(0.)
+aPoint0Data.real("y").setValue(0.)
+aPoint0Data.real("z").setValue(0.)
+aPoint0Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+aSession.startOperation()
+aPoint1 = aPartSetDoc.addFeature("Point")
+aPoint1Data = aPoint1.data()
+assert(aPoint1Data is not None)
+aPoint1Data.real("x").setValue(0.)
+aPoint1Data.real("y").setValue(0.)
+aPoint1Data.real("z").setValue(0.)
+aPoint1Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+assert(aPartSetDoc.size("Features") == 2), "Wrong number of features: {}".format(aPartSetDoc.size("Features"))
+
+# Folder before the feature
+aSession.startOperation()
+aFolder1 = aPartSetDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+assert(aPartSetDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartSetDoc.size("Folders"))
+assert(aPartSetDoc.size("Features") == 3), "Wrong number of features: {}".format(aPartSetDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder1.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder1.name(), FOLDER_NAME_EXPECTED)
+
+## Folder at the end of features list
+#aSession.startOperation()
+#aPartSetDoc.addFolder()
+#aSession.finishOperation()
+#assert(aPartSetDoc.size("Folders") == 2)
+
+#=========================================================================
+# Test 2. Check the Folder is created in a Part
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# check part is a last feature
+aFeaturesList = aSession.moduleDocument().allObjects()
+aLast = aFeaturesList[len(aFeaturesList)-1]
+assert(aLast.data().isEqual(aPart.data())), "Part is not a last object in the list"
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aSession.startOperation()
+aPoint2 = aPartDoc.addFeature("Point")
+aPoint2Data = aPoint2.data()
+assert(aPoint2Data is not None)
+aPoint2Data.real("x").setValue(0.)
+aPoint2Data.real("y").setValue(0.)
+aPoint2Data.real("z").setValue(0.)
+aPoint2Data.string("creation_method").setValue("by_xyz")
+aSession.finishOperation()
+
+assert(aPartDoc.size("Features") == 1), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == 2), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder2.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder2.name(), FOLDER_NAME_EXPECTED)
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-24"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+ aSession.startOperation()
+ aPoint = theDocument.addFeature("Point")
+ aPointData = aPoint.data()
+ assert(aPointData is not None)
+ aPointData.real("x").setValue(theX)
+ aPointData.real("y").setValue(theY)
+ aPointData.real("z").setValue(theZ)
+ aPointData.string("creation_method").setValue("by_xyz")
+ aSession.finishOperation()
+ return aPoint
+
+
+#=========================================================================
+# Prepare some features and folders
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add points
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc, 0., 0., 0.)
+aPoint2 = newPoint(aPartDoc, 10., 0., 0.)
+aPoint3 = newPoint(aPartDoc, 10., 10., 0.)
+aPoint4 = newPoint(aPartDoc, 0., 10., 0.)
+
+# add folders
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint2)
+aSession.finishOperation()
+aSession.startOperation()
+aFolder3 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+# place points into folders
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+toFolder = FeatureList()
+toFolder.append(aPoint3)
+toFolder.append(aPoint4)
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_FULL = 7
+NB_FEATURES_OUT = 4
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == 1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) == 2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+#=========================================================================
+# Test 1. Remove empty folder
+#=========================================================================
+aSession.startOperation()
+aPartDoc.removeFolder(aFolder2)
+aSession.finishOperation()
+
+NB_FEATURES_FULL -= 1
+NB_FEATURES_OUT -= 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) == 1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+#=========================================================================
+# Test 2. Remove non-empty folder
+#=========================================================================
+aSession.startOperation()
+aPartDoc.removeFolder(aFolder3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL -= 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder1, True) == 0), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder1, True))
+assert(aPartDoc.index(aFolder2, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder2, True))
+assert(aPartDoc.index(aFolder3, True) == -1), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aPartDoc.index(aPoint1, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint1, True))
+assert(aPartDoc.index(aPoint2, True) == 1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint2, True))
+assert(aPartDoc.index(aPoint3, True) == 2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == 3), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ Test checks adding sketch into a folder
+"""
+
+from ModelAPI import *
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Sketch_0 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_0.addLine(10, -10, 10, 10)
+model.do()
+
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(50, 50, 25)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2f")], model.selection(), 50, 0)
+
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchCircle_2 = Sketch_2.addCircle(100, -100, 50)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 10, 0)
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_2_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/To_Face_1"))
+SketchProjection_1 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1__cc"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchCircle_3 = Sketch_3.addCircle(100, -100, 25)
+SketchConstraintCoincidence_1 = Sketch_3.setCoincident(SketchPoint_1.result(), SketchCircle_3.center())
+ExtrusionCut_1.setNestedSketch(Sketch_3)
+model.do()
+model.end()
+
+
+aSession = ModelAPI_Session.get()
+aPartDoc = aSession.activeDocument()
+
+#=========================================================================
+# Test 1. Sketch and extrusion could be added to the folder above
+#=========================================================================
+aSession.startOperation()
+Folder_1 = aPartDoc.addFolder(Sketch_1.feature())
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 7
+NB_FEATURES_OUT = 7
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(Sketch_1.feature())
+toFolder.append(Extrusion_1.feature())
+
+# move features to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_1.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 2
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+# check the index of the extrusion in the folder
+aFound = aPartDoc.findContainingFolder(Extrusion_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 1)
+
+
+#=========================================================================
+# Test 2. Sketch could be added to the folder below
+#=========================================================================
+aSession.startOperation()
+Folder_2 = aPartDoc.addFolder(Extrusion_2.feature())
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(Sketch_2.feature())
+
+# move feature to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_2.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_2.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+
+
+#=========================================================================
+# Test 3. Sketch could be removed from the folder
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(Sketch_1.feature())
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+assert(aPartDoc.index(Sketch_1.feature(), True) == 1), "Wrong index of the {}: {}".format(Sketch_1.feature().name(), aPartDoc.index(Sketch_1.feature(), True))
+NB_FEATURES_OUT += 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+
+#=========================================================================
+# Test 4. Add 2 sketches to the folder below
+#=========================================================================
+
+toFolder = FeatureList()
+toFolder.append(Sketch_0.feature())
+toFolder.append(Sketch_1.feature())
+
+# move features to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None and aFolder.data().isEqual(Folder_1.data()))
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 2
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the sketch in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_0.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 0)
+# check the index of the extrusion in the folder
+aFound = aPartDoc.findContainingFolder(Sketch_1.feature())
+assert(aFound[0].data().isEqual(aFolder.data()))
+assert(aFound[1] == 1)
+
+
+from salome.shaper import model
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+#=========================================================================
+# Test checks stability of the foldering mechanism due to incorrect input parameters
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-23"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+ aSession.startOperation()
+ aPoint = theDocument.addFeature("Point")
+ aPointData = aPoint.data()
+ assert(aPointData is not None)
+ aPointData.real("x").setValue(theX)
+ aPointData.real("y").setValue(theY)
+ aPointData.real("z").setValue(theZ)
+ aPointData.string("creation_method").setValue("by_xyz")
+ aSession.finishOperation()
+ return aPoint
+
+
+#=========================================================================
+# Initialization of the model
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc, 0., 0., 0.)
+
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 2
+NB_FEATURES_OUT = 2
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+
+#=========================================================================
+# Test 1. Check number of features out of folder
+# and absense of the crash while getting size of incorrect group
+#=========================================================================
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True))
+
+#=========================================================================
+# Test 2. Add a feature to the folder and check number of features once again
+#=========================================================================
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 1
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True))
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+
+__updated__ = "2017-11-23"
+
+aSession = ModelAPI_Session.get()
+
+
+def newPoint(theDocument, theX, theY, theZ):
+ aSession.startOperation()
+ aPoint = theDocument.addFeature("Point")
+ aPointData = aPoint.data()
+ assert(aPointData is not None)
+ aPointData.real("x").setValue(theX)
+ aPointData.real("y").setValue(theY)
+ aPointData.real("z").setValue(theZ)
+ aPointData.string("creation_method").setValue("by_xyz")
+ aSession.finishOperation()
+ return aPoint
+
+
+#=========================================================================
+# Test 1. Add a point into a folder above
+#=========================================================================
+aSession.startOperation()
+aPart = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+
+# add point and a folder before it
+aPartDoc = aSession.activeDocument()
+aPoint1 = newPoint(aPartDoc, 0., 0., 0.)
+
+aSession.startOperation()
+aFolder1 = aPartDoc.addFolder(aPoint1)
+aSession.finishOperation()
+
+NB_FEATURES_FULL = 2
+NB_FEATURES_OUT = 2
+
+assert(aPartDoc.size("Folders") == 1), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}".format(aPartDoc.size("Features"))
+FOLDER_NAME_EXPECTED = "Folder_1"
+assert(aFolder1.name() == FOLDER_NAME_EXPECTED), "Actual name '{}', expected '{}'".format(aFolder1.name(), FOLDER_NAME_EXPECTED)
+
+toFolder = FeatureList()
+toFolder.append(aPoint1)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+NB_FEATURES_OUT -= 1
+# full number of features
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+# number of features outside the folder
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint1)
+assert(aFound[0].data().isEqual(aFolder1.data()))
+assert(aFound[1] == 0)
+
+#=========================================================================
+# Test 2. Add a point, check it is added to a folder, then move it out
+#=========================================================================
+aPoint2 = newPoint(aPartDoc, 10., 0., 0.)
+
+NB_FEATURES_FULL += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+fromFolder = FeatureList()
+fromFolder.append(aPoint2)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+#=========================================================================
+# Test 3. Add a point into a folder below
+#=========================================================================
+aPoint3 = newPoint(aPartDoc, 10., 10., 0.)
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+# add a folder
+aSession.startOperation()
+aFolder2 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Folders") == 2), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+toFolder = FeatureList()
+toFolder.append(aPoint2)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderBelow(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint2)
+assert(aFound[0].data().isEqual(aFolder2.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound == -1)
+
+#=========================================================================
+# Test 4. Add several points into a folder
+#=========================================================================
+aPoint4 = newPoint(aPartDoc, 0., 10., 0.)
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aPoint4) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aPoint4, True) == 3), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+# add a folder
+aSession.startOperation()
+aFolder3 = aPartDoc.addFolder(aPoint3)
+aSession.finishOperation()
+
+NB_FEATURES_FULL += 1
+NB_FEATURES_OUT += 1
+
+assert(aPartDoc.size("Folders") == 3), "Wrong number of folders: {}".format(aPartDoc.size("Folders"))
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aFolder3) == 4), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3))
+assert(aPartDoc.index(aPoint4) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint4, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+toFolder = FeatureList()
+toFolder.append(aPoint3)
+toFolder.append(aPoint4)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_OUT -= 2
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+# index without respect to foldering
+assert(aPartDoc.index(aFolder3) == 4), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3))
+assert(aPartDoc.index(aPoint3) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3))
+assert(aPartDoc.index(aPoint4) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4))
+# index according to folders
+assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint4)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 1)
+
+aPoint5 = newPoint(aPartDoc, 0., 0., 10.)
+fromFolder = FeatureList()
+fromFolder.append(aPoint5)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+# add more points to the folder to move them out
+aPoint6 = newPoint(aPartDoc, 10., 0., 10.)
+aPoint7 = newPoint(aPartDoc, 10., 10., 10.)
+aPoint8 = newPoint(aPartDoc, 0., 10., 10.)
+
+toFolder = FeatureList()
+toFolder.append(aPoint5)
+toFolder.append(aPoint6)
+toFolder.append(aPoint7)
+toFolder.append(aPoint8)
+
+# move point to the folder
+aSession.startOperation()
+aFolder = aPartDoc.findFolderAbove(toFolder)
+assert(aFolder is not None)
+isAdded = aPartDoc.moveToFolder(toFolder, aFolder)
+aSession.finishOperation()
+assert(isAdded)
+
+NB_FEATURES_FULL += 4
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint5, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 5. Remove a point from a folder before it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint3)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint3, True) == 2), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 6. Remove a point from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint8)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 1
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aPoint8, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 7. Try to remove several points which are not start nor end in a folder
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint5)
+fromFolder.append(aPoint6)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut is False)
+
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint5, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint8, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 8. Remove several points from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint6)
+fromFolder.append(aPoint7)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 2
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint6, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+assert(aFolder3.reference("first_feature").value() is not None)
+assert(aFolder3.reference("last_feature").value() is not None)
+
+#=========================================================================
+# Test 9. Remove all remaining points from a folder after it
+#=========================================================================
+fromFolder = FeatureList()
+fromFolder.append(aPoint4)
+fromFolder.append(aPoint5)
+
+aSession.startOperation()
+isMovedOut = aPartDoc.removeFromFolder(fromFolder, False)
+aSession.finishOperation()
+assert(isMovedOut)
+
+NB_FEATURES_OUT += 2
+assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
+assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
+
+assert(aPartDoc.index(aFolder3, True) == 3), "Wrong index of the folder: {}".format(aPartDoc.index(aFolder3, True))
+assert(aPartDoc.index(aPoint4, True) == 4), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
+assert(aPartDoc.index(aPoint5, True) == 5), "Wrong index of the point: {}".format(aPartDoc.index(aPoint5, True))
+assert(aPartDoc.index(aPoint6, True) == 6), "Wrong index of the point: {}".format(aPartDoc.index(aPoint6, True))
+assert(aPartDoc.index(aPoint7, True) == 7), "Wrong index of the point: {}".format(aPartDoc.index(aPoint7, True))
+assert(aPartDoc.index(aPoint8, True) == 8), "Wrong index of the point: {}".format(aPartDoc.index(aPoint8, True))
+
+# folder is empty
+assert(aFolder3.reference("first_feature").value() is None)
+assert(aFolder3.reference("last_feature").value() is None)
+# remove empty folder
+aSession.startOperation()
+aPartDoc.removeFolder(aFolder3)
+aSession.finishOperation()
+
+from salome.shaper import model
+assert(model.checkPythonDump())
ModelHighAPI_Services.h
ModelHighAPI_Tools.h
ModelHighAPI_FeatureStore.h
+ ModelHighAPI_Folder.h
)
SET(PROJECT_SOURCES
ModelHighAPI_Services.cpp
ModelHighAPI_Tools.cpp
ModelHighAPI_FeatureStore.cpp
+ ModelHighAPI_Folder.cpp
)
SET(PROJECT_LIBRARIES
// shared pointers
%shared_ptr(ModelHighAPI_Interface)
+%shared_ptr(ModelHighAPI_Folder)
// typemaps
%include "ModelHighAPI_Dumper.h"
%include "ModelHighAPI_Integer.h"
%include "ModelHighAPI_Interface.h"
+%include "ModelHighAPI_Folder.h"
%include "ModelHighAPI_RefAttr.h"
%include "ModelHighAPI_Reference.h"
%include "ModelHighAPI_Selection.h"
#include <ModelAPI_Document.h>
#include <ModelAPI_Entity.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
#include <ModelAPI_Result.h>
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_ResultCompSolid.h>
myFeatureCount.clear();
while (!myEntitiesStack.empty())
myEntitiesStack.pop();
+
+ myPostponed.clear();
+ myDumpPostponedInProgress = false;
}
}
return aFound->second.myCurrentName;
// entity is not found, store it
- std::string aName;
+ std::string aName, aKind;
bool isDefaultName = false;
+ bool isSaveNotDumped = theSaveNotDumped;
std::ostringstream aDefaultName;
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
if (aFeature) {
aName = aFeature->name();
- const std::string& aKind = aFeature->getKind();
- DocumentPtr aDoc = aFeature->document();
+ aKind = aFeature->getKind();
+ } else {
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(theEntity);
+ if (aFolder) {
+ aName = aFolder->data()->name();
+ aKind = ModelAPI_Folder::ID();
+ isSaveNotDumped = false;
+ }
+ }
+
+ ObjectPtr anObject = std::dynamic_pointer_cast<ModelAPI_Object>(theEntity);
+ if (anObject) {
+ DocumentPtr aDoc = anObject->document();
int& aNbFeatures = myFeatureCount[aDoc][aKind];
aNbFeatures += 1;
}
myNames[theEntity] = EntityName(aDefaultName.str(), aName, isDefaultName);
- if (theSaveNotDumped)
+ if (isSaveNotDumped)
myNotDumpedEntities.insert(theEntity);
// store names of results
const std::list<ResultPtr>& aResults = theFeature->results();
std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
for (int i = 0; aResIt != aResults.end(); ++aResIt, ++i) {
- std::string aDefaultName = ModelAPI_Tools::getDefaultName(*aResIt, i);
+ std::pair<std::string, bool> aName = ModelAPI_Tools::getDefaultName(*aResIt, i);
+ std::string aDefaultName = aName.first;
std::string aResName = (*aResIt)->data()->name();
bool isUserDefined = !(isFeatureDefaultName && aDefaultName == aResName);
for (int j = 0; j < aNbSubs; ++j) {
ResultPtr aSub = aCompSolid->subResult(j);
std::string aSubName = aSub->data()->name();
- aDefaultName = ModelAPI_Tools::getDefaultName(aSub, j);
+ aName = ModelAPI_Tools::getDefaultName(aSub, j);
+ aDefaultName = aName.first;
bool isUserDefinedSubName = isUserDefined || aDefaultName != aSubName;
myNames[aSub] = EntityName(aSubName,
bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc)
{
bool isOk = true;
- std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
- std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
+ std::list<ObjectPtr> anObjects = theDoc->allObjects();
+ std::list<ObjectPtr>::const_iterator anObjIt = anObjects.begin();
// firstly, dump all parameters
- for (; aFeatIt != aFeatures.end(); ++ aFeatIt)
- dumpParameter(*aFeatIt);
+ for (; anObjIt != anObjects.end(); ++ anObjIt) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIt);
+ if (aFeature)
+ dumpParameter(aFeature);
+ }
// dump all other features
- for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) {
- CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
+ for (anObjIt = anObjects.begin(); anObjIt != anObjects.end(); ++anObjIt) {
+ CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*anObjIt);
if (aCompFeat) // iteratively process composite features
isOk = process(aCompFeat) && isOk;
- else if (!isDumped(*aFeatIt)) // dump common feature
- dumpFeature(*aFeatIt);
+ else if (!isDumped(EntityPtr(*anObjIt))) {
+ // dump folder
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(*anObjIt);
+ if (aFolder)
+ dumpFolder(aFolder);
+ else {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIt);
+ if (aFeature) // dump common feature
+ dumpFeature(aFeature);
+ }
+ }
}
+ // dump folders if any
+ dumpPostponed(true);
return isOk;
}
// increase composite features stack
++gCompositeStackDepth;
// dump composite itself
- if (!isDumped(theComposite) || isForce)
+ if (!isDumped(EntityPtr(theComposite)) || isForce)
dumpFeature(FeaturePtr(theComposite), isForce);
// sub-part is processed independently, because it provides separate document
// decrease composite features stack
--gCompositeStackDepth;
+ // dump folders if any
+ dumpPostponed(true);
return isOk;
}
int aNbSubs = theComposite->numberOfSubs();
for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
FeaturePtr aFeature = theComposite->subFeature(anIndex);
- if (isDumped(aFeature))
+ if (isDumped(EntityPtr(aFeature)))
continue;
isSubDumped = true;
// dump "setName" for composite feature
if (isDumpSetName)
dumpEntitySetName();
+ // dump folders if any
+ dumpPostponed(true);
return isOk;
}
+void ModelHighAPI_Dumper::postpone(const EntityPtr& theEntity)
+{
+ // keep the name
+ name(theEntity, false);
+ myPostponed.push_back(theEntity);
+}
+
+void ModelHighAPI_Dumper::dumpPostponed(bool theDumpFolders)
+{
+ if (myDumpPostponedInProgress)
+ return;
+
+ myDumpPostponedInProgress = true;
+ // make a copy of postponed entities, because the list will be updated
+ // if some features are not able to be dumped
+ std::list<EntityPtr> aPostponedCopy = myPostponed;
+ myPostponed.clear();
+
+ // iterate over postponed entities and try to dump them
+ std::list<EntityPtr>::const_iterator anIt = aPostponedCopy.begin();
+ for (; anIt != aPostponedCopy.end(); ++anIt) {
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(*anIt);
+ if (aFolder) {
+ if (theDumpFolders)
+ dumpFolder(aFolder);
+ else
+ myPostponed.push_back(*anIt);
+ }
+ else {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
+ if (aFeature)
+ dumpFeature(aFeature);
+ }
+ }
+ myDumpPostponedInProgress = false;
+}
+
void ModelHighAPI_Dumper::dumpSubFeatureNameAndColor(const std::string theSubFeatureGet,
const FeaturePtr& theSubFeature)
{
{
EntityNameMap::const_iterator aFound = myNames.find(theEntity);
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
- return aFound != myNames.end() || myFeaturesToSkip.find(aFeature) != myFeaturesToSkip.end();
+ return (aFound != myNames.end() && aFound->second.myIsDumped) ||
+ myFeaturesToSkip.find(aFeature) != myFeaturesToSkip.end();
+}
+
+bool ModelHighAPI_Dumper::isDumped(const AttributeRefAttrPtr& theRefAttr) const
+{
+ FeaturePtr aFeature;
+ if (theRefAttr->isObject())
+ aFeature = ModelAPI_Feature::feature(theRefAttr->object());
+ else
+ aFeature = ModelAPI_Feature::feature(theRefAttr->attr()->owner());
+ return aFeature && isDumped(EntityPtr(aFeature));
+}
+
+bool ModelHighAPI_Dumper::isDumped(const AttributeRefListPtr& theRefList) const
+{
+ std::list<ObjectPtr> aRefs = theRefList->list();
+ std::list<ObjectPtr>::iterator anIt = aRefs.begin();
+ for (; anIt != aRefs.end(); ++anIt) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
+ if (aFeature && !isDumped(EntityPtr(aFeature)))
+ return false;
+ }
+ return true;
}
bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const
return *this;
}
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FolderPtr& theFolder)
+{
+ myDumpBuffer << name(theFolder);
+ return *this;
+}
+
ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity)
{
myDumpBuffer << name(theEntity);
ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
const std::shared_ptr<ModelAPI_AttributeSelectionList>& theAttrSelList)
{
- myDumpBuffer << "[";
+ static const int aThreshold = 2;
+ // if number of elements in the list if greater than a threshold,
+ // dump it in a separate line with specific name
+ std::string aDumped = myDumpBuffer.str();
- GeomShapePtr aShape;
- std::string aShapeTypeStr;
+ if (aDumped.empty() || theAttrSelList->size() <= aThreshold) {
+ myDumpBuffer << "[";
- bool isAdded = false;
+ GeomShapePtr aShape;
+ std::string aShapeTypeStr;
- for(int anIndex = 0; anIndex < theAttrSelList->size(); ++anIndex) {
- AttributeSelectionPtr anAttribute = theAttrSelList->value(anIndex);
- aShape = anAttribute->value();
- if(!aShape.get()) {
- ResultPtr aContext = anAttribute->context();
- if (aContext.get())
- aShape = aContext->shape();
- }
+ bool isAdded = false;
- if(!aShape.get()) {
- continue;
- }
+ for(int anIndex = 0; anIndex < theAttrSelList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttribute = theAttrSelList->value(anIndex);
+ aShape = anAttribute->value();
+ if(!aShape.get()) {
+ ResultPtr aContext = anAttribute->context();
+ if (aContext.get())
+ aShape = aContext->shape();
+ }
- if(isAdded) {
- myDumpBuffer << ", ";
- } else {
- isAdded = true;
+ if(!aShape.get()) {
+ continue;
+ }
+
+ if(isAdded) {
+ myDumpBuffer << ", ";
+ } else {
+ isAdded = true;
+ }
+ myDumpBuffer << "model.selection(\"" <<
+ aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")";
}
- myDumpBuffer << "model.selection(\"" <<
- aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")";
- }
- myDumpBuffer << "]";
+ myDumpBuffer << "]";
+ } else {
+ // clear buffer and store list "as is"
+ myDumpBuffer.str("");
+ *this << theAttrSelList;
+ // save buffer and clear it again
+ std::string aDumpedList = myDumpBuffer.str();
+ myDumpBuffer.str("");
+ // obtain name of list
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theAttrSelList->owner());
+ std::string aListName = name(anOwner) + "_objects";
+ // store all previous data
+ myDumpBuffer << aListName << " = " << aDumpedList << std::endl
+ << aDumped << aListName;
+ }
return *this;
}
isCopy = aCopyAttr.get() && aCopyAttr->value();
}
}
- } while (isCopy);
+ } while (isCopy && !theDumper.myEntitiesStack.empty());
}
// store all not-dumped entities first
if ((*aRefIt)->id() == "ProjectedFeature")
{ // process projection only
FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
- if (anOwner && !theDumper.isDumped(anOwner))
+ if (anOwner && !theDumper.isDumped(EntityPtr(anOwner)))
theDumper.dumpFeature(anOwner, true);
}
}
// then store currently dumped string
theDumper.myFullDump << aBufCopy;
+ // now, store all postponed features
+ theDumper.dumpPostponed();
+
return theDumper;
}
class ModelAPI_Document;
class ModelAPI_Entity;
class ModelAPI_Feature;
+class ModelAPI_Folder;
class ModelAPI_Object;
class ModelAPI_Result;
typedef std::shared_ptr<ModelAPI_Document> DocumentPtr;
typedef std::shared_ptr<ModelAPI_Entity> EntityPtr;
typedef std::shared_ptr<ModelAPI_Feature> FeaturePtr;
+typedef std::shared_ptr<ModelAPI_Folder> FolderPtr;
typedef std::shared_ptr<ModelAPI_Result> ResultPtr;
/**\class ModelHighAPI_Dumper
virtual void dumpParameter(const FeaturePtr& theFeature) = 0;
/// Dump given feature
virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
+ /// Dump folder
+ virtual void dumpFolder(const FolderPtr& theFolder) = 0;
+
+ /// Set feature postponed until all its dependencies are not dumped.
+ /// The name of the feature is stored anyway.
+ MODELHIGHAPI_EXPORT
+ void postpone(const EntityPtr& theEntity);
/// Set a feature that should not be dumped anyway
MODELHIGHAPI_EXPORT
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const FeaturePtr& theEntity);
+ /// Dump folder
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const FolderPtr& theFolder);
+
/// Dump result
MODELHIGHAPI_EXPORT
ModelHighAPI_Dumper& operator<<(const ResultPtr& theResult);
/// clear list of not dumped entities
MODELHIGHAPI_EXPORT void clearNotDumped();
+ /// Check the entity is already dumped
+ MODELHIGHAPI_EXPORT
+ bool isDumped(const EntityPtr& theEntity) const;
+ /// Check theRefAttr is already dumped
+ MODELHIGHAPI_EXPORT
+ bool isDumped(const std::shared_ptr<ModelAPI_AttributeRefAttr>& theRefAttr) const;
+ /// Check all objects in theRefList are already dumped
+ MODELHIGHAPI_EXPORT
+ bool isDumped(const std::shared_ptr<ModelAPI_AttributeRefList>& theRefList) const;
+
protected:
/// Dump "setName" command if last entity had user-defined name
MODELHIGHAPI_EXPORT void dumpEntitySetName();
bool processSubs(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite,
bool theDumpModelDo = false);
- /// Check the entity is already dumped
- bool isDumped(const EntityPtr& theEntity) const;
-
/// Stores names of results for the given feature
void saveResultNames(const FeaturePtr& theFeature);
/// Check the result feature has default transparency
bool isDefaultTransparency(const ResultPtr& theResult) const;
+ /// Dump postponed entities
+ void dumpPostponed(bool theDumpFolders = false);
+
private:
struct EntityName {
std::string myCurrentName; ///< default name of current feature
/// features which should not be dumped (like coincidence and tangency created by tangent arc)
std::set<FeaturePtr> myFeaturesToSkip;
+ std::list<EntityPtr> myPostponed; ///< list of postponed entities (sketch constraints or folders)
+ bool myDumpPostponedInProgress; ///< processing postponed is in progress
+
protected:
- /// list of entities, used by other features but not dumped yet
+ /// list of entities, used by other features but not dumped yet
std::set<EntityPtr> myNotDumpedEntities;
friend class SketchAPI_Sketch;
+ friend class ModelHighAPI_Folder;
};
#endif
#define PRECISION 6
#define TOLERANCE (1.e-7)
-ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) {
- storeData(theFeature->data(), myAttrs);
- // iterate results to store
- std::list<ResultPtr> allResults;
- ModelAPI_Tools::allResults(theFeature, allResults);
- std::list<ResultPtr>::iterator aRes = allResults.begin();
- for(; aRes != allResults.end(); aRes++) {
- std::map<std::string, std::string> aResDump;
- storeData((*aRes)->data(), aResDump);
- myRes.push_back(aResDump);
+ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(ObjectPtr theObject) {
+ storeData(theObject->data(), myAttrs);
+
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+ if (aFeature) {
+ // iterate results to store
+ std::list<ResultPtr> allResults;
+ ModelAPI_Tools::allResults(aFeature, allResults);
+ std::list<ResultPtr>::iterator aRes = allResults.begin();
+ for(; aRes != allResults.end(); aRes++) {
+ std::map<std::string, std::string> aResDump;
+ storeData((*aRes)->data(), aResDump);
+ myRes.push_back(aResDump);
+ }
}
}
-std::string ModelHighAPI_FeatureStore::compare(FeaturePtr theFeature) {
- std::string anError = compareData(theFeature->data(), myAttrs);
+std::string ModelHighAPI_FeatureStore::compare(ObjectPtr theObject) {
+ std::string anError = compareData(theObject->data(), myAttrs);
if (!anError.empty()) {
- return "Features '" + theFeature->name() + "' differ:" + anError;
- }
- std::list<ResultPtr> allResults;
- ModelAPI_Tools::allResults(theFeature, allResults);
- std::list<ResultPtr>::iterator aRes = allResults.begin();
- std::list<std::map<std::string, std::string> >::iterator aResIter = myRes.begin();
- for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
- anError = compareData((*aRes)->data(), *aResIter);
- if (!anError.empty())
- return "Results of feature '" + theFeature->name() + "' '" + (*aRes)->data()->name() +
- "' differ:" + anError;
- }
- if (aRes != allResults.end()) {
- return "Current model has more results '" + (*aRes)->data()->name() + "'";
+ return "Features '" + theObject->data()->name() + "' differ:" + anError;
}
- if (aResIter != myRes.end()) {
- return "Original model had more results '" + (*aResIter)["__name__"] + "'";
+
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+ if (aFeature) {
+ std::list<ResultPtr> allResults;
+ ModelAPI_Tools::allResults(aFeature, allResults);
+ std::list<ResultPtr>::iterator aRes = allResults.begin();
+ std::list<std::map<std::string, std::string> >::iterator aResIter = myRes.begin();
+ for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
+ anError = compareData((*aRes)->data(), *aResIter);
+ if (!anError.empty())
+ return "Results of feature '" + aFeature->name() + "' '" + (*aRes)->data()->name() +
+ "' differ:" + anError;
+ }
+ if (aRes != allResults.end()) {
+ return "Current model has more results '" + (*aRes)->data()->name() + "'";
+ }
+ if (aResIter != myRes.end()) {
+ return "Original model had more results '" + (*aResIter)["__name__"] + "'";
+ }
}
return ""; // ok
}
#include <string>
#include <memory>
-class ModelAPI_Feature;
+class ModelAPI_Object;
class ModelAPI_Data;
class GeomAPI_Shape;
class ModelAPI_Attribute;
-typedef std::shared_ptr<ModelAPI_Feature> FeaturePtr;
-typedef std::shared_ptr<ModelAPI_Attribute> AttributePtr;
+typedef std::shared_ptr<ModelAPI_Object> ObjectPtr;
+typedef std::shared_ptr<ModelAPI_Attribute> AttributePtr;
/**\class ModelHighAPI_FeatureStore
* \ingroup CPPHighAPI
// unused constructor for the map container needs
ModelHighAPI_FeatureStore() {}
// constructor that initializes this object by feature to store
- ModelHighAPI_FeatureStore(FeaturePtr theFeature);
+ ModelHighAPI_FeatureStore(ObjectPtr theObject);
// compares the stored feature information with the given feature
- std::string compare(FeaturePtr theFeature);
+ std::string compare(ObjectPtr theObject);
private:
/// stores the information about all attributes of data in map
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModelHighAPI_Folder.h"
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Reference.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_Document.h>
+
+//--------------------------------------------------------------------------------------
+
+ModelHighAPI_Folder::ModelHighAPI_Folder(const std::shared_ptr<ModelAPI_Folder> & theFolder)
+ : ModelHighAPI_Interface(FeaturePtr()),
+ myFolder(theFolder)
+{
+ initialize();
+}
+
+ModelHighAPI_Folder::~ModelHighAPI_Folder()
+{
+}
+
+bool ModelHighAPI_Folder::initialize()
+{
+ if (!myFolder) {
+ throwException(ID() + " exception: The folder is NULL.");
+ return false;
+ }
+
+ myFirstFeature = myFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ if (!myFirstFeature)
+ return false;
+ myAttrGetter[ModelAPI_Folder::FIRST_FEATURE_ID()] = "firstFeature";
+
+ myLastFeature = myFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (!myLastFeature)
+ return false;
+ myAttrGetter[ModelAPI_Folder::LAST_FEATURE_ID()] = "lastFeature";
+
+ return true;
+}
+
+void ModelHighAPI_Folder::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ const std::string& aDocName = theDumper.name(myFolder->document());
+
+ AttributeReferencePtr aStartRef = myFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ AttributeReferencePtr aEndRef = myFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+
+ // do not dump empty folders
+ if (!aEndRef->value())
+ return;
+
+ // Dump folder when its features have been already dumped.
+ // Otherwise, store the folder postponed.
+ if (theDumper.isDumped(EntityPtr(aEndRef->value())))
+ theDumper << myFolder << " = model.addFolder(" << aDocName << ", "
+ << aStartRef << ", " << aEndRef << ")" << std::endl;
+ else
+ theDumper.postpone(myFolder);
+}
+
+//--------------------------------------------------------------------------------------
+
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc)
+{
+ std::shared_ptr<ModelAPI_Folder> aFolder = theDoc->addFolder();
+ return std::shared_ptr<ModelHighAPI_Folder>(new ModelHighAPI_Folder(aFolder));
+}
+
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc,
+ const ModelHighAPI_Reference& theFirstFeature,
+ const ModelHighAPI_Reference& theLastFeature)
+{
+ std::shared_ptr<ModelAPI_Folder> aFolder = theDoc->addFolder(theFirstFeature.feature());
+
+ AttributeReferencePtr aFirstFeatAttr = aFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ fillAttribute(theFirstFeature.feature(), aFirstFeatAttr);
+
+ AttributeReferencePtr aLastFeatAttr = aFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ fillAttribute(theLastFeature.feature(), aLastFeatAttr);
+
+ return std::shared_ptr<ModelHighAPI_Folder>(new ModelHighAPI_Folder(aFolder));
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_
+#define SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_
+
+//--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Interface.h>
+
+#include <ModelAPI_Folder.h>
+
+#include <memory>
+//--------------------------------------------------------------------------------------
+class ModelAPI_AttributeReference;
+class ModelAPI_Document;
+class ModelHighAPI_Reference;
+//--------------------------------------------------------------------------------------
+/**\class ModelHighAPI_Folder
+ * \ingroup CPPHighAPI
+ * \brief Class for filling ModelAPI_Folder
+ */
+class ModelHighAPI_Folder : public ModelHighAPI_Interface
+{
+public:
+ /// Constructor for a folder
+ MODELHIGHAPI_EXPORT
+ explicit ModelHighAPI_Folder(const std::shared_ptr<ModelAPI_Folder>& theFolder);
+ /// Destructor
+ MODELHIGHAPI_EXPORT virtual ~ModelHighAPI_Folder();
+
+ static std::string ID() { return ModelAPI_Folder::ID(); }
+ virtual std::string getID() { return ID(); }
+
+ /// First feature reference
+ std::shared_ptr<ModelAPI_AttributeReference> firstFeature() const
+ { return myFirstFeature; }
+
+ /// Last feature reference
+ std::shared_ptr<ModelAPI_AttributeReference> lastFeature() const
+ { return myLastFeature; }
+
+ /// Dump wrapped feature
+ MODELHIGHAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+protected:
+ bool initialize();
+
+private:
+ std::shared_ptr<ModelAPI_Folder> myFolder;
+
+ std::shared_ptr<ModelAPI_AttributeReference> myFirstFeature;
+ std::shared_ptr<ModelAPI_AttributeReference> myLastFeature;
+};
+
+//--------------------------------------------------------------------------------------
+/**\ingroup CPPHighAPI
+ * \brief Create empty Folder feature
+ */
+MODELHIGHAPI_EXPORT
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc);
+
+/**\ingroup CPPHighAPI
+ * \brief Create Folder feature
+ */
+MODELHIGHAPI_EXPORT
+std::shared_ptr<ModelHighAPI_Folder> addFolder(const std::shared_ptr<ModelAPI_Document>& theDoc,
+ const ModelHighAPI_Reference& theFirstFeature,
+ const ModelHighAPI_Reference& theLastFeature);
+//--------------------------------------------------------------------------------------
+#endif /* SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_ */
}
}
// store the model features information: iterate all features
- int aFeaturesCount = 0; // stores the number of compared features for this document to compate
+ int anObjectsCount = 0; // stores the number of compared features for this document to compate
std::set<std::string> aProcessed; // processed features names (that are in the current document)
- std::list<FeaturePtr> allFeatures = theDoc->allFeatures();
- std::list<FeaturePtr>::iterator allIter = allFeatures.begin();
- for(; allIter != allFeatures.end(); allIter++) {
- FeaturePtr aFeat = *allIter;
+
+ // process all objects (features and folders)
+ std::list<ObjectPtr> allObjects = theDoc->allObjects();
+ std::list<ObjectPtr>::iterator allIter = allObjects.begin();
+ for(; allIter != allObjects.end(); allIter++) {
+ ObjectPtr anObject = *allIter;
if (theCompare) {
std::map<std::string, ModelHighAPI_FeatureStore>::iterator
- aFeatFind = aDocFind->second.find(aFeat->name());
- if (aFeatFind == aDocFind->second.end()) {
- return "Document '" + theDocName + "' feature '" + aFeat->name() + "' not found";
+ anObjFind = aDocFind->second.find(anObject->data()->name());
+ if (anObjFind == aDocFind->second.end()) {
+ return "Document '" + theDocName + "' feature '" + anObject->data()->name() + "' not found";
}
- std::string anError = aFeatFind->second.compare(aFeat);
+ std::string anError = anObjFind->second.compare(anObject);
if (!anError.empty()) {
anError = "Document " + theDocName + " " + anError;
return anError;
}
- aFeaturesCount++;
- aProcessed.insert(aFeat->name());
+ anObjectsCount++;
+ aProcessed.insert(anObject->data()->name());
} else {
- theStore[theDocName][aFeat->name()] = ModelHighAPI_FeatureStore(aFeat);
+ theStore[theDocName][anObject->data()->name()] = ModelHighAPI_FeatureStore(anObject);
}
- // iterate all results of this feature
- std::list<ResultPtr> allResults;
- ModelAPI_Tools::allResults(aFeat, allResults);
- std::list<ResultPtr>::iterator aRes = allResults.begin();
- for(; aRes != allResults.end(); aRes++) {
- // recoursively store features of sub-documents
- if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) {
- DocumentPtr aDoc = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes)->partDoc();
- if (aDoc.get()) {
- std::string anError = storeFeatures((*aRes)->data()->name(), aDoc, theStore, theCompare);
- if (!anError.empty())
- return anError;
+
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ if (aFeature) {
+ // iterate all results of this feature
+ std::list<ResultPtr> allResults;
+ ModelAPI_Tools::allResults(aFeature, allResults);
+ std::list<ResultPtr>::iterator aRes = allResults.begin();
+ for(; aRes != allResults.end(); aRes++) {
+ // recoursively store features of sub-documents
+ if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) {
+ DocumentPtr aDoc = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes)->partDoc();
+ if (aDoc.get()) {
+ std::string anError =
+ storeFeatures((*aRes)->data()->name(), aDoc, theStore, theCompare);
+ if (!anError.empty())
+ return anError;
+ }
}
}
}
}
// checks the number of compared features
if (theCompare) {
- if (aDocFind->second.size() != aFeaturesCount) {
+ if (aDocFind->second.size() != anObjectsCount) {
// search for disappeared feature
std::string aLostName;
std::map<std::string, ModelHighAPI_FeatureStore>::iterator aLostIter;
#include "ModelHighAPI.h"
#include "ModelHighAPI_Double.h"
#include "ModelHighAPI_Dumper.h"
+ #include "ModelHighAPI_Folder.h"
#include "ModelHighAPI_Integer.h"
#include "ModelHighAPI_Interface.h"
#include "ModelHighAPI_Macro.h"
ModuleBase.h
ModuleBase_ActionInfo.h
ModuleBase_ActionType.h
+ ModuleBase_BRepOwner.h
ModuleBase_Definitions.h
ModuleBase_DoubleSpinBox.h
ModuleBase_Events.h
ModuleBase_IPrefMgr.h
ModuleBase_IPropertyPanel.h
ModuleBase_ISelection.h
+ ModuleBase_ISelectionActivate.h
ModuleBase_IViewWindow.h
ModuleBase_IViewer.h
ModuleBase_IWidgetCreator.h
ModuleBase_IWorkshop.h
ModuleBase_LabelValue.h
+ ModuleBase_ListView.h
ModuleBase_ModelWidget.h
ModuleBase_Operation.h
ModuleBase_OperationAction.h
ModuleBase_IconFactory.h
ModuleBase_Dialog.h
ModuleBase_ModelDialogWidget.h
+ ModuleBase_ActionParameter.h
+ ModuleBase_ActionIntParameter.h
ModuleBase_ChoiceCtrl.h
ModuleBase_WidgetNameEdit.h
)
ModuleBase_IViewer.h
ModuleBase_IWorkshop.h
ModuleBase_LabelValue.h
+ ModuleBase_ListView.h
ModuleBase_ModelDialogWidget.h
ModuleBase_ModelWidget.h
ModuleBase_Operation.h
SET(PROJECT_SOURCES
ModuleBase_ActionInfo.cpp
+ ModuleBase_BRepOwner.cpp
ModuleBase_DoubleSpinBox.cpp
ModuleBase_Filter.cpp
ModuleBase_FilterValidated.cpp
ModuleBase_IWidgetCreator.cpp
ModuleBase_IWorkshop.cpp
ModuleBase_LabelValue.cpp
+ ModuleBase_ListView.cpp
ModuleBase_ModelWidget.cpp
ModuleBase_Operation.cpp
ModuleBase_OperationAction.cpp
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ActionIntParameter_H_
+#define ModuleBase_ActionIntParameter_H_
+
+#include "ModuleBase_ActionParameter.h"
+
+class ModuleBase_ActionIntParameter : public ModuleBase_ActionParameter
+{
+public:
+ ModuleBase_ActionIntParameter(int theVal):ModuleBase_ActionParameter(), myVal(theVal) {}
+
+ int value() const { return myVal; }
+
+private:
+ int myVal;
+};
+
+typedef std::shared_ptr<ModuleBase_ActionIntParameter> ActionIntParamPtr;
+
+#endif
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ActionParameter_H_
+#define ModuleBase_ActionParameter_H_
+
+#include <memory>
+
+class ModuleBase_ActionParameter
+{
+public:
+ /// Destuctor is added in order to virtualize the class
+ virtual ~ModuleBase_ActionParameter() {}
+};
+
+typedef std::shared_ptr<ModuleBase_ActionParameter> ActionParamPtr;
+
+#endif
\ No newline at end of file
#ifndef ModuleBase_ActionType_H_
#define ModuleBase_ActionType_H_
-#include <ModuleBase.h>
-
/*!
* Structure to describe widget processed types of actions.
*/
-enum MODULEBASE_EXPORT ModuleBase_ActionType
+enum ModuleBase_ActionType
{
ActionEnter,
ActionEscape,
ActionDelete,
+ ActionSelection,
ActionUndo,
ActionRedo
};
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModuleBase_BRepOwner.h"
+
+IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner);
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_BRepOwner_H
+#define ModuleBase_BRepOwner_H
+
+#include "ModuleBase.h"
+
+#include <Standard_DefineHandle.hxx>
+#include <StdSelect_BRepOwner.hxx>
+
+#include <QMap>
+
+DEFINE_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner)
+
+/**
+* \ingroup GUI
+* A redefinition of standard BRep Owner in order to provide specific selection
+* of CompSolid objects. This owner is created only for selection mode TopAbs_COMPSOLID
+*/
+class ModuleBase_BRepOwner: public StdSelect_BRepOwner
+{
+public:
+ /// Constructor
+ /// \param aShape an owner shape
+ /// \param aPriority drawig priority
+ /// \param ComesFromDecomposition decomposition flag
+ ModuleBase_BRepOwner(const TopoDS_Shape& aShape,
+ const Standard_Integer aPriority = 0,
+ const Standard_Boolean ComesFromDecomposition = Standard_False)
+ : StdSelect_BRepOwner(aShape, aPriority, ComesFromDecomposition) {}
+
+ /// Highlight the presentation with the given color
+ /// \param aPM a presentations manager
+ /// \param theStyle a style of presentation
+ /// \param theMode a drawing mode
+ virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM,
+ const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0)
+ {
+ Selectable()->HilightOwnerWithColor(aPM, theStyle, this);
+ }
+
+ DEFINE_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner)
+};
+
+#endif
\ No newline at end of file
#include <GeomAPI_Shape.h>
#include <GeomAPI_ICustomPrs.h>
+#include <SelectMgr_ListOfFilter.hxx>
+
#include <QString>
#include <QObject>
#include <QMap>
virtual ~ModuleBase_IModule() {}
- /// Add default selection filters of the module to the current viewer
- virtual void activateSelectionFilters() {}
-
- /// Remove default selection filters of the module from the current viewer
- virtual void deactivateSelectionFilters() {}
-
/// Stores the current selection
virtual void storeSelection() {}
virtual void activeSelectionModes(QIntList& theModes) {}
/// Appends specific selection modes for the module to the list of types
- /// \param theTypes a selection modes to be extended
- virtual void customSubShapesSelectionModes(QIntList& theTypes) {}
+ /// \param theModesType combination of available selection filters
+ /// \param theModes a selection modes to be extended
+ virtual void moduleSelectionModes(int theModesType, QIntList& theModes) = 0;
+
+ /// Appends into container of filters module filters corresponded to the modes type
+ /// \param theFilterTypes container of available selection filters
+ /// \param theSelectionFilters [out] container to be extend by elements
+ virtual void moduleSelectionFilters(const QIntList& theFilterTypes,
+ SelectMgr_ListOfFilter& theSelectionFilters) = 0;
+
+ /// Returns types of registered module selection filters
+ /// \param theSelectionFilters [out] container of type value
+ virtual QIntList selectionFilters() { return QIntList(); }
+
+ /// Returns selection filter
+ /// \param theType selection filter type
+ /// \param theFilter instance of filter
+ virtual Handle(SelectMgr_Filter) selectionFilter(const int theType) = 0;
/// Return true if the custom presentation is activated
/// \param theFlag a flag of level of customization, which means that only part of sub-elements
/// The signal about the widget activation
/// \param theWidget the activated widget
- void widgetActivated(ModuleBase_ModelWidget* theWidget);
+ //void widgetActivated(ModuleBase_ModelWidget* theWidget);
/// Emited when there is no next widget
/// \param thePreviousAttributeID an attribute key of the previous active widget
/**
* Makes the given widget active, highlights it and removes
* highlighting from the previous active widget
- * emits widgetActivated(theWidget) signal
* \param theWidget which has to be activated
* \param theEmitSignal a flag to prohibit signal emit
*/
class ModuleBase_ViewerPrs;
class SelectMgr_EntityOwner;
-/**
-* \ingroup GUI
-* A class which provides access to selection.
-* A selection can be obtained as from a viewer as from Object browser in various forms
-*/
+/// \ingroup GUI
+/// A class which provides access to selection.
+/// A selection can be obtained as from a viewer as from Object browser in various forms
class ModuleBase_ISelection
{
public:
virtual void fillPresentation(std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,
const Handle(SelectMgr_EntityOwner)& theOwner) const = 0;
- /**
- * Returns list of features currently selected in object browser
- */
+ /// Returns list of features currently selected in object browser
virtual QObjectPtrList selectedObjects() const = 0;
- /// Set selected objects list
- virtual void setSelectedObjects( const QObjectPtrList& ) const = 0;
-
- /**
- * Returns list of currently selected results
- */
+ /// Returns list of currently selected results
virtual QObjectPtrList selectedPresentations() const = 0;
- //! Returns list of currently selected QModelIndexes
+ /// Returns list of currently selected QModelIndexes
virtual QModelIndexList selectedIndexes() const = 0;
- //! Returns list of currently selected AIS objects
- //! \param theList returning list of selected AIS objects
- virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const = 0;
-
- //! Returns list of currently selected QModelIndexes
- virtual ObjectPtr getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const = 0;
-
- //! Return the shape from the viewer presentation.
- //! If the shape is equal to the shape of selected object, it returns an empty shape
- //! \param thePrs a selected object
- //! \return a shape
+ /// Return the shape from the viewer presentation.
+ /// If the shape is equal to the shape of selected object, it returns an empty shape
+ /// \param thePrs a selected object
+ /// \return a shape
MODULEBASE_EXPORT ResultPtr getResult(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- //! Return the shape from the viewer presentation.
- //! If the shape is equal to the shape of selected object, it returns an empty shape
- //! \param thePrs a selected object
- //! \return a shape
+ /// Return the shape from the viewer presentation.
+ /// If the shape is equal to the shape of selected object, it returns an empty shape
+ /// \param thePrs a selected object
+ /// \return a shape
MODULEBASE_EXPORT GeomShapePtr getShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- //! Return the IO from the viewer presentation.
- //! \param thePrs a selected object
- //! \return an interactive object
+ /// Return the IO from the viewer presentation.
+ /// \param thePrs a selected object
+ /// \return an interactive object
virtual MODULEBASE_EXPORT
Handle(AIS_InteractiveObject) getIO(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs) = 0;
- //! Wraps the object list into the viewer prs list
- //! \param theObjects a list of objects
- //! \return a list of prs, where only object is not empty
+ /// Wraps the object list into the viewer prs list
+ /// \param theObjects a list of objects
+ /// \return a list of prs, where only object is not empty
static MODULEBASE_EXPORT QList<std::shared_ptr<ModuleBase_ViewerPrs>> getViewerPrs(
const QObjectPtrList& theObjects);
/// owner with the qual vertex stays in the list.
static MODULEBASE_EXPORT void filterSelectionOnEqualPoints
(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theSelected);
+protected:
+ /// Returns list of currently selected QModelIndexes
+ virtual ObjectPtr getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const = 0;
+
private:
/// Find vertex shape build by a Brep owner of the presentation if it exists
/// \param thePrs a viewer presentation
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ISelectionActivate_H
+#define ModuleBase_ISelectionActivate_H
+
+#include "ModuleBase.h"
+
+#include "ModuleBase_IWorkshop.h"
+
+#include <SelectMgr_ListOfFilter.hxx>
+
+class ModuleBase_ModelWidget;
+
+
+/// \ingroup GUI
+/// A class which provides interface of activation/deactivate selection modes
+/// and using selection filters.
+class ModuleBase_ISelectionActivate
+{
+public:
+ /// Constructor
+ ModuleBase_ISelectionActivate(ModuleBase_IWorkshop* theWorkshop) : myWorkshop(theWorkshop) {}
+
+ /// Destructor
+ ~ModuleBase_ISelectionActivate() {}
+
+ /// Updates active selection modes in the viewer depending on the application state
+ MODULEBASE_EXPORT virtual void updateSelectionModes() = 0;
+
+ /// Updates active selection filters in the viewer depending on the application state
+ MODULEBASE_EXPORT virtual void updateSelectionFilters() = 0;
+
+ /// Activates parameter filters in the workshop, deactivate active out of the container
+ /// Please find a possibility to use updateSelectionFilters instead of direct call this method.
+ /// \param theSelectionFilters a filtes
+ MODULEBASE_EXPORT virtual void activateSelectionFilters
+ (const SelectMgr_ListOfFilter& theSelectionFilters) = 0;
+
+protected:
+ ModuleBase_IWorkshop* myWorkshop; ///< active workshop
+};
+
+#endif
class ModuleBase_IPropertyPanel;
class ModuleBase_IErrorMgr;
class ModuleBase_Operation;
+class ModuleBase_ISelectionActivate;
class ModuleBase_ViewerPrs;
class QMainWindow;
/// Return current selection instance
virtual ModuleBase_ISelection* selection() const = 0;
- /// Activate sub-shapes selection (opens local context)
- /// Types has to be defined according to TopAbs_ShapeEnum
- virtual void activateSubShapesSelection(const QIntList& theTypes) = 0;
-
- /// Activate objects in the module selection modes(opens local context)
- virtual void activateModuleSelectionModes() = 0;
-
- /// Deactivate sub-shapes selection (closes local context)
- virtual void deactivateSubShapesSelection() = 0;
-
//! Returns instance of loaded module
virtual ModuleBase_IModule* module() const = 0;
/// \return a filter
Handle(ModuleBase_FilterValidated) validatorFilter();
+ /// A selection activate in 3D View handler
+ virtual ModuleBase_ISelectionActivate* selectionActivate() const = 0;
+
//! Returns currently active operation
virtual ModuleBase_Operation* currentOperation() const = 0;
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModuleBase_ListView.h"
+#include "ModuleBase_Tools.h"
+
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QListWidget>
+#include <QWidget>
+
+#ifndef WIN32
+#include <QResizeEvent>
+#include <QTimer>
+#endif
+
+const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1;
+
+/**
+* Customization of a List Widget to make it to be placed on full width of container
+*/
+class CustomListWidget : public QListWidget
+{
+public:
+ /// Constructor
+ /// \param theParent a parent widget
+ CustomListWidget(QWidget* theParent)
+ : QListWidget(theParent)
+ {
+ }
+
+ /// Redefinition of virtual method
+ virtual QSize sizeHint() const
+ {
+ int aHeight = 2*QFontMetrics(font()).height();
+ QSize aSize = QListWidget::sizeHint();
+ return QSize(aSize.width(), aHeight);
+ }
+
+ /// Redefinition of virtual method
+ virtual QSize minimumSizeHint() const
+ {
+ int aHeight = 4/*2*/*QFontMetrics(font()).height();
+ QSize aSize = QListWidget::minimumSizeHint();
+ return QSize(aSize.width(), aHeight);
+ }
+
+#ifndef WIN32
+// The code is necessary only for Linux because
+//it can not update viewport on widget resize
+protected:
+ void resizeEvent(QResizeEvent* theEvent)
+ {
+ QListWidget::resizeEvent(theEvent);
+ QTimer::singleShot(5, viewport(), SLOT(repaint()));
+ }
+#endif
+};
+
+//********************************************************************
+ModuleBase_ListView::ModuleBase_ListView(QWidget* theParent, const QString& theObjectName,
+ const QString& theToolTip)
+{
+ myListControl = new CustomListWidget(theParent);
+
+ myListControl->setObjectName(theObjectName);
+ myListControl->setToolTip(theToolTip);
+ myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+ myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"),
+ theParent, this, SLOT(onCopyItem()));
+ myCopyAction->setShortcut(QKeySequence::Copy);
+ myCopyAction->setEnabled(false);
+ myListControl->addAction(myCopyAction);
+
+ myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"),
+ theParent, this, SIGNAL(deleteActionClicked()));
+ myDeleteAction->setEnabled(false);
+ myListControl->addAction(myDeleteAction);
+
+ myListControl->setContextMenuPolicy(Qt::ActionsContextMenu);
+ connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection()));
+}
+
+//********************************************************************
+void ModuleBase_ListView::addItem(const QString& theTextValue, const int theIndex)
+{
+ QListWidgetItem* anItem = new QListWidgetItem(theTextValue, myListControl);
+ anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, theIndex);
+ myListControl->addItem(anItem);
+}
+
+//********************************************************************
+void ModuleBase_ListView::getSelectedIndices(std::set<int>& theIndices)
+{
+ QList<QListWidgetItem*> aItems = myListControl->selectedItems();
+ foreach(QListWidgetItem* anItem, aItems) {
+ int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt();
+ if (theIndices.find(anIndex) == theIndices.end())
+ theIndices.insert(anIndex);
+ }
+}
+
+//********************************************************************
+void ModuleBase_ListView::removeSelectedItems()
+{
+ QList<QListWidgetItem*> aItems = myListControl->selectedItems();
+ foreach(QListWidgetItem* anItem, aItems)
+ myListControl->takeItem(myListControl->row(anItem));
+}
+
+//********************************************************************
+void ModuleBase_ListView::removeItems(std::set<int>& theIndices)
+{
+ QList<QListWidgetItem*> aItems;
+ for (int i = 0; i < myListControl->count(); i++) {
+ QListWidgetItem* anItem = myListControl->item(i);
+ int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt();
+ if (theIndices.find(anIndex) != theIndices.end())
+ aItems.append(anItem);
+ }
+ foreach(QListWidgetItem* anItem, aItems)
+ myListControl->takeItem(myListControl->row(anItem));
+}
+
+//********************************************************************
+void ModuleBase_ListView::restoreSelection(const QModelIndexList& theIndices)
+{
+ int aRows = myListControl->model()->rowCount();
+ if (aRows > 0) {
+ foreach(QModelIndex aIndex, theIndices) {
+ if (aIndex.row() < aRows)
+ myListControl->selectionModel()->select(aIndex, QItemSelectionModel::Select);
+ else {
+ QModelIndex aIdx = myListControl->model()->index(aRows - 1, 0);
+ myListControl->selectionModel()->select(aIdx, QItemSelectionModel::Select);
+ }
+ }
+ }
+}
+
+//********************************************************************
+void ModuleBase_ListView::onCopyItem()
+{
+ QList<QListWidgetItem*> aItems = myListControl->selectedItems();
+ QString aRes;
+ foreach(QListWidgetItem* aItem, aItems) {
+ if (!aRes.isEmpty())
+ aRes += "\n";
+ aRes += aItem->text();
+ }
+ if (!aRes.isEmpty()) {
+ QClipboard* aClipboard = QApplication::clipboard();
+ aClipboard->setText(aRes);
+ }
+}
+
+//********************************************************************
+void ModuleBase_ListView::onListSelection()
+{
+ QList<QListWidgetItem*> aItems = myListControl->selectedItems();
+ myCopyAction->setEnabled(!aItems.isEmpty());
+ myDeleteAction->setEnabled(!aItems.isEmpty());
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ListView_H_
+#define ModuleBase_ListView_H_
+
+#include "ModuleBase.h"
+
+#include <QModelIndex>
+#include <QObject>
+
+#include <set>
+
+class QAction;
+class QListWidget;
+class QWidget;
+
+/**
+* \ingroup GUI
+* An extension of QListWidget to provide Undo/Redo functionality
+*/
+class MODULEBASE_EXPORT ModuleBase_ListView : public QObject
+{
+Q_OBJECT
+
+public:
+ /// Constructor
+ ModuleBase_ListView(QWidget* theParent = 0, const QString& theObjectName = QString(),
+ const QString& theToolTip = QString());
+ /// Destructor
+ virtual ~ModuleBase_ListView() {}
+
+ /// Returns current control
+ /// \return list view instance
+ QListWidget* getControl() const { return myListControl; }
+
+ /// Adds a new list widget item to the end of the list and connect it to the given index
+ /// \param theTextValue value visualized in the view
+ /// \param theIndex an item internal index
+ void addItem(const QString& theTextValue, const int theIndex);
+
+ /// Returns list of internal list view item indices
+ /// \param theIndices an output container for indices
+ void getSelectedIndices(std::set<int>& theIndices);
+
+ /// Removes selected items from the list widget
+ void removeSelectedItems();
+
+ /// Remove items contain parameter indices
+ /// \param theIndices an indices
+ void removeItems(std::set<int>& theIndices);
+
+ /// Set selected items if possible
+ /// \param theIndices container of indices to be selected
+ void restoreSelection(const QModelIndexList& theIndices);
+
+ /// Update enable/disable state of context menu actions
+ void updateActionsStatus();
+
+protected slots:
+ /// Slot for copy command in a list pop-up menu
+ void onCopyItem();
+
+ /// Slot is called on selection of list of selected items
+ void onListSelection();
+
+signals:
+ /// Signal about delete action click
+ void deleteActionClicked();
+
+protected:
+ QListWidget* myListControl; ///< List control
+
+ QAction* myCopyAction; ///< A copy action for pop-up menu in a list control
+ QAction* myDeleteAction; ///< A delete action for pop-up menu in a list control
+};
+
+#endif
//#define DEBUG_WIDGET_INSTANCE
//#define DEBUG_ENABLE_SKETCH_INPUT_FIELDS
+//**************************************************************
ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,
const Config_WidgetAPI* theData)
: QWidget(theParent),
connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));
}
+//**************************************************************
ModuleBase_ModelWidget::~ModuleBase_ModelWidget()
{
#ifdef DEBUG_WIDGET_INSTANCE
#endif
}
+//**************************************************************
bool ModuleBase_ModelWidget::reset()
{
bool aResult = resetCustom();
return aResult;
}
+//**************************************************************
bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const
{
return theObject->data()->attribute(attributeID())->isInitialized();
}
+//**************************************************************
+void ModuleBase_ModelWidget::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
+{
+ theModuleSelectionModes = -1;
+ if (myWidgetValidator)
+ myWidgetValidator->selectionModes(theModuleSelectionModes, theModes);
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ if (myWidgetValidator)
+ myWidgetValidator->selectionFilters(theModuleSelectionFilters, theSelectionFilters);
+}
+
+//**************************************************************
bool ModuleBase_ModelWidget::isValueEnabled() const
{
bool anEnabled = true;
return anEnabled;
}
+//**************************************************************
void ModuleBase_ModelWidget::processValueState()
{
if (myState == ModifiedInPP || myState == ModifiedInViewer)
storeValue();
}
+//**************************************************************
Events_InfoMessage ModuleBase_ModelWidget::getValueStateError() const
{
Events_InfoMessage aMessage;
return aMessage;
}
+//**************************************************************
QString ModuleBase_ModelWidget::getError(const bool theValueStateChecked) const
{
QString anError;
return anError;
}
+//**************************************************************
void ModuleBase_ModelWidget::enableFocusProcessing()
{
QList<QWidget*> aMyControls = getControls();
}
}
+//**************************************************************
void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)
{
QList<QWidget*> aWidgetList = getControls();
}
}
+//**************************************************************
void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue,
const bool isUpdateFlushed)
{
myFlushUpdateBlocked = false;
}
+//**************************************************************
bool ModuleBase_ModelWidget::focusTo()
{
#ifdef DEBUG_WIDGET_INSTANCE
return isFocusAccepted;
}
+//**************************************************************
void ModuleBase_ModelWidget::activate()
{
#ifdef DEBUG_WIDGET_INSTANCE
if (anAttribute.get() != NULL && !anAttribute->isInitialized())
initializeValueByActivate();
}
-
- if (myWidgetValidator)
- myWidgetValidator->activateFilters(true);
-
activateCustom();
}
+//**************************************************************
void ModuleBase_ModelWidget::deactivate()
{
#ifdef DEBUG_WIDGET_INSTANCE
myIsValueStateBlocked = false;
myState = Stored;
if (myWidgetValidator)
- myWidgetValidator->activateFilters(false);
+ myWidgetValidator->clearValidatedCash();
}
+//**************************************************************
void ModuleBase_ModelWidget::initializeValueByActivate()
{
if (isComputedDefault()) {
}
}
+//**************************************************************
QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)
{
QWidget* aControl = 0;
return aControl;
}
+//**************************************************************
void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
{
myDefaultValue = theValue;
}
+//**************************************************************
bool ModuleBase_ModelWidget::storeValue()
{
setValueState(Stored);
return isDone;
}
#ifdef DEBUG_VALUE_STATE
+
+//**************************************************************
std::string getDebugInfo(const ModuleBase_ModelWidget::ValueState& theState)
{
std::string anInfo;
}
return anInfo;
}
-
#endif
+
+//**************************************************************
ModuleBase_ModelWidget::ValueState ModuleBase_ModelWidget::setValueState
(const ModuleBase_ModelWidget::ValueState& theState)
{
return aState;
}
+//**************************************************************
bool ModuleBase_ModelWidget::blockValueState(const bool theBlocked)
{
bool isBlocked = myIsValueStateBlocked;
return isBlocked;
}
+//**************************************************************
bool ModuleBase_ModelWidget::restoreValue()
{
emit beforeValuesRestored();
return isDone;
}
+//**************************************************************
void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)
{
if (!myFlushUpdateBlocked) {
}
}
+//**************************************************************
bool ModuleBase_ModelWidget::canProcessAction(ModuleBase_ActionType theActionType,
bool& isActionEnabled)
{
case ActionEnter: return false;
case ActionEscape: return false;
case ActionDelete: return true;
+ case ActionSelection: return true;
case ActionUndo:
case ActionRedo:
default:
}
}
-bool ModuleBase_ModelWidget::processAction(ModuleBase_ActionType theActionType)
+//**************************************************************
+bool ModuleBase_ModelWidget::processAction(ModuleBase_ActionType theActionType,
+ const ActionParamPtr& theParam)
{
switch (theActionType) {
case ActionEnter:
return processEscape();
case ActionDelete:
return processDelete();
+ case ActionSelection:
+ processSelection();
case ActionUndo:
case ActionRedo:
default:
}
}
+//**************************************************************
bool ModuleBase_ModelWidget::processEnter()
{
return false;
}
+//**************************************************************
bool ModuleBase_ModelWidget::processEscape()
{
return false;
}
+//**************************************************************
bool ModuleBase_ModelWidget::processDelete()
{
// we consider that model objects eats delete key in order to
return true;
}
+//**************************************************************
+bool ModuleBase_ModelWidget::processSelection()
+{
+ return false;
+}
+
+//**************************************************************
bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
{
QWidget* aWidget = qobject_cast<QWidget*>(theObject);
#include <ModuleBase.h>
#include <ModuleBase_ActionType.h>
+#include <ModuleBase_Definitions.h>
#include <ModuleBase_OperationFeature.h>
+#include <ModuleBase_ActionInfo.h>
+#include <ModuleBase_ActionParameter.h>
#include <ModelAPI_Feature.h>
+#include <SelectMgr_ListOfFilter.hxx>
+
#include <QWidget>
#include <memory>
/// \return the boolean result
bool isInitialized(ObjectPtr theObject) const;
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param [out] theModes a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
+ /// Appends into container of workshop selection filters
+ /// \param [out] theModuleSelectionFilters module additional modes, -1 means all default modes
+ /// \param [out] theSelectionFilters selection filters
+ virtual void selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters);
+
/// Returns true, if default value of the widget should be computed
/// on operation's execute, like radius for circle's constraint (can not be zero)
bool isComputedDefault() const { return myIsComputedDefault; }
/// The method called when widget is deactivated
virtual void deactivate();
+ /// Opportunity to do something after the active widget of the property panel changed
+ virtual void updateAfterDeactivation() {}
+ /// Opportunity to do something after the active widget of the property panel changed
+ virtual void updateAfterActivation() {}
+
+ /// The method called if widget should be activated always
+ virtual bool needToBeActiated() { return false; }
+
/// Returns list of widget controls
/// \return a control list
virtual QList<QWidget*> getControls() const = 0;
virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
/// Returns true if the event is processed. The default implementation is empty, returns false.
- virtual bool processAction(ModuleBase_ActionType theActionType);
+ virtual bool processAction(ModuleBase_ActionType theActionType,
+ const ActionParamPtr& theParam = ActionParamPtr());
+
+ /// Returns list of accessible actions for Undo/Redo commands. By default it returns empty list.
+ /// \param theActionType type of action. It can be ActionUndo or ActionRedo.
+ virtual QList<ActionInfo> actionsList(ModuleBase_ActionType theActionType) const
+ { return QList<ActionInfo>(); }
/// Sends Update and Redisplay for the given object
/// \param theObj is updating object
//// Returns true if the event is processed. The default implementation is empty, returns false.
virtual bool processDelete();
-protected slots:
+ /// Returns true if envent is processed. It applyes workshop selection for the widget attribute.
+ virtual bool processSelection();
+
+ protected slots:
/// Processing of values changed in model widget by store the current value to the feature
void onWidgetValuesChanged();
afterCommitOperation();
#ifdef DEBUG_OPERATION_START
- qDebug("ModuleBase_OperationFeature::commit -- end : IMPOSSIBLE to commit");
+ qDebug("ModuleBase_OperationFeature::commit -- end");
#endif
return true;
}
#ifdef DEBUG_OPERATION_START
- qDebug("ModuleBase_OperationFeature::commit -- end");
+ qDebug("ModuleBase_OperationFeature::commit -- end : IMPOSSIBLE to commit");
#endif
return false;
}
//
#include "ModuleBase_ResultPrs.h"
-#include "ModuleBase_Tools.h"
+
+#include <GeomAPI_PlanarEdges.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_ResultCompSolid.h>
-#include <GeomAPI_PlanarEdges.h>
+
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_BRepOwner.h"
#include <Events_InfoMessage.h>
#include <Events_Loop.h>
+#include <AIS_ColoredDrawer.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_Selection.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
#include <BRep_Builder.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d.hxx>
#include <Prs3d_PointAspect.hxx>
#include <Prs3d_IsoAspect.hxx>
-#include <TopoDS_Builder.hxx>
-#include <TopoDS.hxx>
+#include <Prs3d_ShadingAspect.hxx>
#include <SelectMgr_SequenceOfOwner.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_SelectionManager.hxx>
#include <StdPrs_WFShape.hxx>
+#include <StdPrs_ShadedShape.hxx>
#include <StdSelect_BRepSelectionTool.hxx>
-#include <AIS_InteractiveContext.hxx>
-#include <AIS_Selection.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <Graphic3d_AspectMarker3d.hxx>
#include <TopExp_Explorer.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner);
+#include <TopoDS.hxx>
+#include <TopoDS_Builder.hxx>
//*******************************************************************************************
+//********************************************************************
ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult)
- : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myAdditionalSelectionPriority(0)
+ : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myAdditionalSelectionPriority(0),
+ myTransparency(1)
{
std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(theResult);
TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
SetAutoHilight(aCompSolid.get() == NULL);
+ myHiddenSubShapesDrawer = new AIS_ColoredDrawer (myDrawer);
+ Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect();
+ aShadingAspect->SetMaterial(Graphic3d_NOM_BRASS); //default value of context material
+ myHiddenSubShapesDrawer->SetShadingAspect(aShadingAspect);
+
ModuleBase_Tools::setPointBallHighlighting(this);
}
+//********************************************************************
void ModuleBase_ResultPrs::setAdditionalSelectionPriority(const int thePriority)
{
myAdditionalSelectionPriority = thePriority;
}
+//********************************************************************
+void ModuleBase_ResultPrs::SetColor (const Quantity_Color& theColor)
+{
+ ViewerData_AISShape::SetColor(theColor);
+ myHiddenSubShapesDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
+}
+
+//********************************************************************
+bool ModuleBase_ResultPrs::setSubShapeHidden(const NCollection_List<TopoDS_Shape>& theShapes)
+{
+ bool isModified = false;
+
+ TopoDS_Compound aCompound;
+ BRep_Builder aBBuilder;
+ aBBuilder.MakeCompound (aCompound);
+ // restore hidden shapes if there are not the shapes in parameter container
+ NCollection_List<TopoDS_Shape> aVisibleSubShapes;
+ for (NCollection_List<TopoDS_Shape>::Iterator aHiddenIt(myHiddenSubShapes); aHiddenIt.More();
+ aHiddenIt.Next()) {
+ if (!theShapes.Contains(aHiddenIt.Value()))
+ aVisibleSubShapes.Append(aHiddenIt.Value());
+ else
+ aBBuilder.Add (aCompound, aHiddenIt.Value());
+ }
+ isModified = !aVisibleSubShapes.IsEmpty();
+ for (NCollection_List<TopoDS_Shape>::Iterator aVisibleIt(aVisibleSubShapes); aVisibleIt.More();
+ aVisibleIt.Next())
+ myHiddenSubShapes.Remove(aVisibleIt.Value());
+
+ // append hidden shapes into internal container if there are not these shapes
+ for (NCollection_List<TopoDS_Shape>::Iterator aShapeIt(theShapes); aShapeIt.More();
+ aShapeIt.Next())
+ {
+ if (aShapeIt.Value().ShapeType() != TopAbs_FACE) // only face shape can be hidden
+ continue;
+
+ if (!myHiddenSubShapes.Contains(aShapeIt.Value())) {
+ myHiddenSubShapes.Append(aShapeIt.Value());
+ aBBuilder.Add (aCompound, aShapeIt.Value());
+ isModified = true;
+ }
+ }
+ myHiddenCompound = aCompound;
+ return isModified;
+}
+
+//********************************************************************
+bool ModuleBase_ResultPrs::hasSubShapeVisible(
+ const NCollection_List<TopoDS_Shape>& theShapesToSkip)
+{
+ TopoDS_Compound aCompound;
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound (aCompound);
+ NCollection_List<TopoDS_Shape> aShapesToSkip;
+ aShapesToSkip.Append(myHiddenSubShapes);
+ for (NCollection_List<TopoDS_Shape>::Iterator anIt(theShapesToSkip); anIt.More(); anIt.Next())
+ aShapesToSkip.Append(anIt.Value());
+
+ collectSubShapes(aBuilder, aCompound, myOriginalShape, aShapesToSkip);
+ return !BOPTools_AlgoTools3D::IsEmptyShape(aCompound);
+}
+
+//********************************************************************
+bool ModuleBase_ResultPrs::setHiddenSubShapeTransparency(double theTransparency)
+{
+ if (myTransparency == theTransparency || theTransparency > 1 || theTransparency < 0)
+ return false;
+
+ myTransparency = theTransparency;
+ myHiddenSubShapesDrawer->ShadingAspect()->SetTransparency (theTransparency, myCurrentFacingModel);
+ return true;
+}
+
+//********************************************************************
void ModuleBase_ResultPrs::Compute(
const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
const Handle(Prs3d_Presentation)& thePresentation,
bool aReadyToDisplay = aShapePtr.get();
if (aReadyToDisplay) {
myOriginalShape = aShapePtr->impl<TopoDS_Shape>();
- if (!myOriginalShape.IsNull())
- Set(myOriginalShape);
+ if (myHiddenSubShapes.IsEmpty() || myOriginalShape.ShapeType() > TopAbs_FACE ) {
+ if (!myOriginalShape.IsNull())
+ Set(myOriginalShape);
+ }
+ else { // convert shape into SHELL
+ TopoDS_Compound aCompound;
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound (aCompound);
+ collectSubShapes(aBuilder, aCompound, myOriginalShape, myHiddenSubShapes);
+ bool isEmptyShape = BOPTools_AlgoTools3D::IsEmptyShape(aCompound);
+ Set(aCompound);
+ if (isEmptyShape)
+ aReadyToDisplay = false;
+ }
}
// change deviation coefficient to provide more precise circle
//ModuleBase_Tools::setDefaultDeviationCoefficient(myResult, Attributes());
AIS_Shape::Compute(thePresentationManager, thePresentation, theMode);
+ // visualize hidden sub-shapes transparent
+ if (myTransparency < 1 && !myHiddenSubShapes.IsEmpty())
+ {
+ StdPrs_ShadedShape::Add (thePresentation, myHiddenCompound, myHiddenSubShapesDrawer);
+ aReadyToDisplay = true;
+ }
+
if (!aReadyToDisplay) {
Events_InfoMessage("ModuleBase_ResultPrs",
"An empty AIS presentation: ModuleBase_ResultPrs").send();
}
}
+//********************************************************************
+void ModuleBase_ResultPrs::collectSubShapes(BRep_Builder& theBuilder,
+ TopoDS_Shape& theCompound, const TopoDS_Shape& theShape,
+ const NCollection_List<TopoDS_Shape>& theHiddenSubShapes)
+{
+ switch (theShape.ShapeType()) {
+ case TopAbs_COMPOUND: {
+ for (TopoDS_Iterator aChildIter (theShape); aChildIter.More(); aChildIter.Next())
+ collectSubShapes(theBuilder, theCompound, aChildIter.Value(), theHiddenSubShapes);
+ }
+ break;
+ case TopAbs_SOLID:
+ case TopAbs_SHELL: {
+ for (TopExp_Explorer anExp (theShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
+ collectSubShapes(theBuilder, theCompound, anExp.Current(), theHiddenSubShapes);
+ }
+ }
+ break;
+ case TopAbs_WIRE: {
+ for (TopExp_Explorer anExp (theShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+ collectSubShapes(theBuilder, theCompound, anExp.Current(), theHiddenSubShapes);
+ }
+ }
+ break;
+ case TopAbs_FACE: {
+ if (theHiddenSubShapes.Contains(theShape))
+ return; // remove hidden shape
+ theBuilder.Add(theCompound, theShape);
+ }
+ break;
+ case TopAbs_EDGE:
+ case TopAbs_VERTEX: {
+ theBuilder.Add(theCompound, theShape);
+ }
+ default:
+ break;
+ }
+}
+
+//********************************************************************
void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
const Standard_Integer theMode)
{
}
}
+//********************************************************************
bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
const Standard_Integer theMode)
{
return false;
}
+//********************************************************************
void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM,
const SelectMgr_SequenceOfOwner& theOwners)
{
}
}
+//********************************************************************
void ModuleBase_ResultPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM,
const Handle(Graphic3d_HighlightStyle)& theStyle,
const Handle(SelectMgr_EntityOwner)& theOwner)
#include <ModelAPI_Result.h>
+#include <BRep_Builder.hxx>
+#include <NCollection_List.hxx>
#include <ViewerData_AISShape.hxx>
#include <Standard_DefineHandle.hxx>
-#include <StdSelect_BRepOwner.hxx>
+#include <TopoDS_Compound.hxx>
#include <QMap>
-DEFINE_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner)
-
-/**
-* \ingroup GUI
-* A redefinition of standard BRep Owner in order to provide specific selection
-* of CompSolid objects. This owner is created only for selection mode TopAbs_COMPSOLID
-*/
-class ModuleBase_BRepOwner: public StdSelect_BRepOwner
-{
-public:
- /// Constructor
- /// \param aShape an owner shape
- /// \param aPriority drawig priority
- /// \param ComesFromDecomposition decomposition flag
- ModuleBase_BRepOwner(const TopoDS_Shape& aShape,
- const Standard_Integer aPriority = 0,
- const Standard_Boolean ComesFromDecomposition = Standard_False)
- : StdSelect_BRepOwner(aShape, aPriority, ComesFromDecomposition) {}
-
- /// Highlight the presentation with the given color
- /// \param aPM a presentations manager
- /// \param theStyle a style of presentation
- /// \param theMode a drawing mode
- virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM,
- const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0)
- {
- Selectable()->HilightOwnerWithColor(aPM, theStyle, this);
- }
-
- DEFINE_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner)
-};
-
-
+class AIS_ColoredDrawer;
+class AIS_InteractiveContext;
DEFINE_STANDARD_HANDLE(ModuleBase_ResultPrs, ViewerData_AISShape)
/// \param thePriority a new priority value
Standard_EXPORT void setAdditionalSelectionPriority(const int thePriority);
+ //! Updates color of sub shape drawer
+ Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor);
+
+ /// Change presentation to have given shape hidden.
+ /// It suports FACE type of the shape to be hidden.
+ /// If presentation type is greater than FACE, the SHELL with be shown with the FACE hidden
+ /// It is possible to hide more than one FACE by calling the method with given FACES
+ /// Visual state of the face is controlled by the second parameter
+ /// \param theShapes a container of shape objects
+ /// \returns true if the presentation is changed, or false (if for example it was hidden)
+ Standard_EXPORT bool setSubShapeHidden(const NCollection_List<TopoDS_Shape>& theShapes);
+
+ /// Returns true if there are no hidden sub shapes or original shape has at least one not hidden
+ /// \param theShapesToSkip container of shape to be hidden in the presentation (faces)
+ /// \return boolean value
+ Standard_EXPORT bool hasSubShapeVisible(const NCollection_List<TopoDS_Shape>& theShapesToSkip);
+
+ /// Set transparency of hidden sub shapes: if value is 1, shapes are entirely hidden
+ /// \param theTransparency transparency value
+ /// \return false if parameter is out of [0, 1]
+ Standard_EXPORT bool setHiddenSubShapeTransparency(double theTransparency);
+
DEFINE_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape)
+
protected:
/// Redefinition of virtual function
Standard_EXPORT virtual void Compute(
bool appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
const Standard_Integer theMode);
+ /// Creates compound of vertices, edges and faces.
+ /// If the shape is COMPOUND, iterate by sub-shapes.
+ /// If the shape is SOLID/SHEL, explore shape by FACES,
+ /// If the shape is WIRE, explore shape by EDGES
+ /// \param theBuilder result compound builder
+ /// \param theCompound the result shape
+ /// \param theShape the processed shape
+ /// \param theHiddenSubShapes container of shapes to be skipped (faces)
+ void collectSubShapes(BRep_Builder& theBuilder, TopoDS_Shape& theCompound,
+ const TopoDS_Shape& theShape, const NCollection_List<TopoDS_Shape>& theHiddenSubShapes);
+
+private:
/// Reference to result object
ResultPtr myResult;
/// Original shape of the result object
TopoDS_Shape myOriginalShape;
+ /// Container of original Shape sub shape to be hidden and not selectable
+ NCollection_List<TopoDS_Shape> myHiddenSubShapes;
+ TopoDS_Compound myHiddenCompound; /// compound of hidden sub shapes
+ double myTransparency; ///< transparency of hidden shapes, where 0 - there is no transparency
+ Handle(AIS_ColoredDrawer) myHiddenSubShapesDrawer; ///< drawer for hidden sub shapes
+
/// selection priority that will be added to the standard
/// selection priority of the selection entity
int myAdditionalSelectionPriority;
#include <ModuleBase_IModule.h>
#include <ModuleBase_IconFactory.h>
#include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_ViewerPrs.h>
#include <ModelAPI_Attribute.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Events.h>
+#include <ModelAPI_Folder.h>
#include <ModelGeomAlgo_Point2D.h>
+#include <StdSelect_BRepOwner.hxx>
#include <TopoDS_Iterator.hxx>
#include <GeomDataAPI_Point2D.h>
}
void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
- bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory)
+ bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
+ bool& hasFolder)
{
hasResult = false;
hasFeature = false;
hasParameter = false;
hasCompositeOwner = false;
hasResultInHistory = false;
+ hasFolder = false;
foreach(ObjectPtr aObj, theObjects) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
hasResult |= (aResult.get() != NULL);
hasFeature |= (aFeature.get() != NULL);
+ hasFolder |= (aFolder.get() != NULL);
hasParameter |= (aConstruction.get() != NULL);
if (hasFeature)
hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
hasResultInHistory = aFeature.get() && aFeature->isInHistory();
}
- if (hasFeature && hasResult && hasParameter && hasCompositeOwner)
+ if (hasFeature && hasResult && hasParameter && hasCompositeOwner && hasFeature)
break;
}
}
return aShapeType;
}
+TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
+{
+ if (thePrs->shape().get())
+ return thePrs->shape()->impl<TopoDS_Shape>();
+
+ Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
+ if (!anOwner.IsNull())
+ return anOwner->Shape();
+
+ return TopoDS_Shape();
+}
+
void getParameters(QStringList& theParameters)
{
theParameters.clear();
if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
aFeature = ModelAPI_Feature::feature(anObject);
}
- theFeatures.insert(aFeature);
+ if (aFeature.get())
+ theFeatures.insert(aFeature);
}
}
+//**************************************************************
+void convertToFolders(const QObjectPtrList& theObjects,
+ std::set<FolderPtr>& theFolders)
+{
+ QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
+ for(; anIt != aLast; anIt++) {
+ ObjectPtr anObject = *anIt;
+ FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
+ if (aFeature.get())
+ theFolders.insert(aFeature);
+ }
+}
+
+
+//**************************************************************
QString translate(const Events_InfoMessage& theMessage)
{
QString aMessage;
#include <ModelAPI_Attribute.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Folder.h>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Shape.hxx>
class QLayout;
class QDoubleSpinBox;
class QAction;
+class ModuleBase_IWorkshop;
class ModuleBase_ParamIntSpinBox;
class ModuleBase_ParamSpinBox;
-class ModuleBase_IWorkshop;
+class ModuleBase_ViewerPrs;
class GeomAPI_Shape;
/// \param hasParameter will be set to true if list contains Parameter objects
/// \param hasCompositeOwner will be set to true if list contains Sub-Feature objects
/// \param hasResultInHistory will be set to true if one of result is in history
+/// \param hasFolder will be set to true if one of folder is in the list
MODULEBASE_EXPORT void checkObjects(const QObjectPtrList& theObjects, bool& hasResult,
bool& hasFeature, bool& hasParameter, bool& hasCompositeOwner,
- bool& hasResultInHistory);
+ bool& hasResultInHistory, bool& hasFolder);
/// Sets the default coeffient into the driver calculated accordingly the shape type.
/// It provides 1.e-4 for results of construction type
/// \param theObj an object
MODULEBASE_EXPORT TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape);
+/// Returns either presentation shape or shape of BREP owner if it is casted to it
+/// \param thePrs selection presentation
+/// \return shape
+MODULEBASE_EXPORT TopoDS_Shape getSelectedShape(
+ const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
/// Returns list of parameters accessible in the active part and partset
/// \theParameters a list of parameter names
MODULEBASE_EXPORT void getParameters(QStringList& theParameters);
std::set<FeaturePtr>& theFeatures);
+/// Converts a list of objects to set of folders.
+/// \param theObjects a list of objects
+/// \param theFeatures an out conteiner of features
+void MODULEBASE_EXPORT convertToFolders(const QObjectPtrList& theObjects,
+ std::set<FolderPtr>& theFolders);
+
+
/// Returns translation from the given data.
/// If translation is not exists then it returns a string
/// from the info data without translation
#include "ModuleBase_ViewerPrs.h"
#include <ModuleBase_ResultPrs.h>
+#include <StdSelect_BRepOwner.hxx>
ModuleBase_ViewerPrs::ModuleBase_ViewerPrs(ObjectPtr theResult,
const GeomShapePtr& theShape,
}
//********************************************************************
-void ModuleBase_WidgetFeatureSelector::deactivate()
+void ModuleBase_WidgetFeatureSelector::selectionModes(int& theModuleSelectionModes,
+ QIntList& theModes)
{
- ModuleBase_ModelWidget::deactivate();
- disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- activateFilters(false);
- myWorkshop->deactivateSubShapesSelection();
+ theModuleSelectionModes = -1;
+ theModes.push_back(ModuleBase_ResultPrs::Sel_Result);
}
//********************************************************************
void ModuleBase_WidgetFeatureSelector::activateCustom()
{
- connect(myWorkshop, SIGNAL(selectionChanged()), this,
- SLOT(onSelectionChanged()), Qt::UniqueConnection);
-
- activateFilters(true);
-
- QIntList aShapeTypes;
- aShapeTypes.push_back(ModuleBase_ResultPrs::Sel_Result);
- myWorkshop->activateSubShapesSelection(aShapeTypes);
-
// Restore selection in the viewer by the attribute selection list
// it should be postponed to have current widget as active to validate restored selection
//static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
}
//********************************************************************
-void ModuleBase_WidgetFeatureSelector::onSelectionChanged()
+bool ModuleBase_WidgetFeatureSelector::processSelection()
{
QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(
ModuleBase_ISelection::AllControls);
bool isDone = setSelection(aSelected, true/*false*/);
updateOnSelectionChanged(isDone);
+
+ return isDone;
}
//********************************************************************
virtual bool setSelection(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues,
const bool theToValidate);
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param theModes [out] a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
/// Returns list of widget controls
/// \return a control list
virtual QList<QWidget*> getControls() const;
/// \param thePrs a selected owner
virtual bool setSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- /// The method called when widget is deactivated
- virtual void deactivate();
-
protected:
/// The method called when widget is activated
virtual void activateCustom();
/// \param theDone a state whether the selection is set
virtual void updateOnSelectionChanged(const bool theDone);
-protected slots:
- /// Called on selection changed event
- virtual void onSelectionChanged();
+protected:
+ /// Returns true if envent is processed.
+ virtual bool processSelection();
//----------- Class members -------------
protected:
//
#include <ModuleBase_WidgetMultiSelector.h>
-#include <ModuleBase_WidgetShapeSelector.h>
+
+#include <ModuleBase_ActionIntParameter.h>
+#include <ModuleBase_Definitions.h>
+#include <ModuleBase_Events.h>
+#include <ModuleBase_IconFactory.h>
+#include <ModuleBase_IModule.h>
#include <ModuleBase_ISelection.h>
-#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_ISelectionActivate.h>
#include <ModuleBase_IPropertyPanel.h>
#include <ModuleBase_IViewer.h>
+#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_ListView.h>
#include <ModuleBase_Tools.h>
-#include <ModuleBase_Definitions.h>
-#include <ModuleBase_IModule.h>
#include <ModuleBase_ViewerPrs.h>
-#include <ModuleBase_IconFactory.h>
-#include <ModuleBase_Events.h>
+#include <ModuleBase_WidgetShapeSelector.h>
#include <ModuleBase_ChoiceCtrl.h>
#include <ModelAPI_Data.h>
#include <QString>
#include <QComboBox>
#include <QEvent>
-#include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QTimer>
#include <memory>
#include <string>
-const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1;
-
//#define DEBUG_UNDO_REDO
-/**
-* Customization of a List Widget to make it to be placed on full width of container
-*/
-class CustomListWidget : public QListWidget
-{
-public:
- /// Constructor
- /// \param theParent a parent widget
- CustomListWidget( QWidget* theParent )
- : QListWidget( theParent )
- {
- }
-
- /// Redefinition of virtual method
- virtual QSize sizeHint() const
- {
- int aHeight = 2*QFontMetrics( font() ).height();
- QSize aSize = QListWidget::sizeHint();
- return QSize( aSize.width(), aHeight );
- }
-
- /// Redefinition of virtual method
- virtual QSize minimumSizeHint() const
- {
- int aHeight = 4/*2*/*QFontMetrics( font() ).height();
- QSize aSize = QListWidget::minimumSizeHint();
- return QSize( aSize.width(), aHeight );
- }
-
-#ifndef WIN32
-// The code is necessary only for Linux because
-//it can not update viewport on widget resize
-protected:
- void resizeEvent(QResizeEvent* theEvent)
- {
- QListWidget::resizeEvent(theEvent);
- QTimer::singleShot(5, viewport(), SLOT(repaint()));
- }
-#endif
-};
-
#ifdef DEBUG_UNDO_REDO
void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex,
QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > theSelectedHistoryValues)
}
QString aToolTip = QString::fromStdString(theData->widgetTooltip());
- myListControl = new CustomListWidget(this);
QString anObjName = QString::fromStdString(attributeID());
- myListControl->setObjectName(anObjName);
- myListControl->setToolTip(aToolTip);
- myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ myListView = new ModuleBase_ListView(this, anObjName, aToolTip);
+ connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection()));
+ connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem()));
- aMainLay->addWidget(myListControl, 2, 0, 1, -1);
+ aMainLay->addWidget(myListView->getControl(), 2, 0, 1, -1);
aMainLay->setRowStretch(2, 1);
//aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)???
//aMainLay->setRowMinimumHeight(3, 20);
//this->setLayout(aMainLay);
connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged()));
- myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"),
- myWorkshop->desktop(), this, SLOT(onCopyItem()));
- myCopyAction->setShortcut(QKeySequence::Copy);
- myCopyAction->setEnabled(false);
- myListControl->addAction(myCopyAction);
-
- myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"),
- myWorkshop->desktop(), this, SLOT(onDeleteItem()));
- myDeleteAction->setEnabled(false);
- myListControl->addAction(myDeleteAction);
-
- myListControl->setContextMenuPolicy(Qt::ActionsContextMenu);
- connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection()));
-
myIsNeutralPointClear = theData->getBooleanAttribute("clear_in_neutral_point", true);
}
myWorkshop->module()->activateCustomPrs(myFeature,
ModuleBase_IModule::CustomizeHighlightedObjects, true);
clearSelectedHistory();
- myWorkshop->updateCommandStatus();
}
//********************************************************************
myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true);
clearSelectedHistory();
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::updateAfterDeactivation()
+{
+ // restore previous Undo/Redo workshop state
+ myWorkshop->updateCommandStatus();
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::updateAfterActivation()
+{
+ // fill Undo/Redo actions with current information
myWorkshop->updateCommandStatus();
}
}
break;
default:
+ aCanProcess = ModuleBase_WidgetSelector::canProcessAction(theActionType, isActionEnabled);
break;
}
return aCanProcess;
}
//********************************************************************
-bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActionType)
+bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActionType,
+ const ActionParamPtr& theParam)
{
switch (theActionType) {
case ActionUndo:
case ActionRedo: {
+ ActionIntParamPtr aParam =
+ std::dynamic_pointer_cast<ModuleBase_ActionIntParameter>(theParam);
+ int aNb = aParam->value();
if (theActionType == ActionUndo)
- myCurrentHistoryIndex--;
+ myCurrentHistoryIndex -= aNb;
else
- myCurrentHistoryIndex++;
+ myCurrentHistoryIndex += aNb;
QList<ModuleBase_ViewerPrsPtr> aSelected = mySelectedHistoryValues[myCurrentHistoryIndex];
// equal vertices should not be used here
ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected);
return true;
}
default:
- return ModuleBase_ModelWidget::processAction(theActionType);
+ return ModuleBase_ModelWidget::processAction(theActionType, theParam);
}
}
-//********************************************************************
-bool ModuleBase_WidgetMultiSelector::activateSelectionAndFilters(bool toActivate)
-{
- myWorkshop->updateCommandStatus(); // update enable state of Undo/Redo application actions
- return ModuleBase_WidgetSelector::activateSelectionAndFilters(toActivate);
-}
-
//********************************************************************
bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
{
std::set<int> anAttributeIds;
getSelectedAttributeIndices(anAttributeIds);
- QModelIndexList aIndexes = myListControl->selectionModel()->selectedIndexes();
+ QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes();
// refill attribute by the items which indices are not in the list of ids
bool aDone = false;
}
// Restore selection
- int aRows = myListControl->model()->rowCount();
- if (aRows > 0) {
- foreach(QModelIndex aIndex, aIndexes) {
- if (aIndex.row() < aRows)
- myListControl->selectionModel()->select(aIndex, QItemSelectionModel::Select);
- else {
- QModelIndex aIdx = myListControl->model()->index(aRows - 1, 0);
- myListControl->selectionModel()->select(aIdx, QItemSelectionModel::Select);
- }
- }
- }
+ myListView->restoreSelection(anIndices);
+
appendSelectionInHistory();
return aDone;
}
QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
{
QList<QWidget*> result;
- result << myListControl;
+ result << myListView->getControl();
return result;
}
//********************************************************************
void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
{
- activateSelectionAndFilters(true);
+ // Clear current selection in order to avoid updating of object browser with obsolete indexes
+ // which can appear because of results deletetion after changing a type of selection
+ QList<ModuleBase_ViewerPrsPtr> aEmptyList;
+ myWorkshop->setSelected(aEmptyList);
+
+ updateSelectionModesAndFilters(true);
+ myWorkshop->selectionActivate()->updateSelectionModes();
if (!myFeature)
return;
}
//********************************************************************
-void ModuleBase_WidgetMultiSelector::onSelectionChanged()
+bool ModuleBase_WidgetMultiSelector::processSelection()
{
if (!myIsNeutralPointClear) {
QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent);
Events_Loop::loop()->flush(anEvent);
- return;
+ return true;
}
}
}
appendFirstSelectionInHistory();
- ModuleBase_WidgetSelector::onSelectionChanged();
+ bool aDone = ModuleBase_WidgetSelector::processSelection();
appendSelectionInHistory();
+ return aDone;
}
void ModuleBase_WidgetMultiSelector::appendFirstSelectionInHistory()
{
// Set focus to List control in order to make possible
// to use Tab key for transfer the focus to next widgets
- ModuleBase_Tools::setFocus(myListControl,
+ ModuleBase_Tools::setFocus(myListView->getControl(),
"ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()");
}
foreach (QString aShapeTypeName, myShapeTypes) {
int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName);
if(aRefType == theShapeType && idx != myTypeCtrl->value()) {
- bool aWasActivated = activateSelectionAndFilters(false);
+ updateSelectionModesAndFilters(false);
bool isBlocked = myTypeCtrl->blockSignals(true);
myTypeCtrl->setValue(idx);
myTypeCtrl->blockSignals(isBlocked);
- if (aWasActivated)
- activateSelectionAndFilters(true);
+ updateSelectionModesAndFilters(true);
break;
}
idx++;
//********************************************************************
void ModuleBase_WidgetMultiSelector::updateSelectionList()
{
- myListControl->clear();
+ myListView->getControl()->clear();
DataPtr aData = myFeature->data();
AttributePtr anAttribute = aData->attribute(attributeID());
AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
for (int i = 0; i < aSelectionListAttr->size(); i++) {
AttributeSelectionPtr aAttr = aSelectionListAttr->value(i);
- QListWidgetItem* anItem = new QListWidgetItem(aAttr->namingName().c_str(), myListControl);
- anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i);
- myListControl->addItem(anItem);
+ myListView->addItem(aAttr->namingName().c_str(), i);
}
}
else if (aType == ModelAPI_AttributeRefList::typeId()) {
for (int i = 0; i < aRefListAttr->size(); i++) {
ObjectPtr anObject = aRefListAttr->object(i);
if (anObject.get()) {
- QListWidgetItem* anItem = new QListWidgetItem(anObject->data()->name().c_str(),
- myListControl);
- anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i);
- myListControl->addItem(anItem);
+ myListView->addItem(anObject->data()->name().c_str(), i);
}
}
}
aName = anObject->data()->name().c_str();
}
}
- QListWidgetItem* anItem = new QListWidgetItem(aName, myListControl);
- anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i);
- myListControl->addItem(anItem);
+ myListView->addItem(aName, i);
}
}
// We have to call repaint because sometimes the List control is not updated
- myListControl->repaint();
+ myListView->getControl()->repaint();
}
//********************************************************************
QList<ModuleBase_ViewerPrsPtr> anEmptyList;
// This method will call Selection changed event which will call onSelectionChanged
- // To clear mySelection, myListControl and storeValue()
+ // To clear mySelection, myListView and storeValue()
// So, we don't need to call it
myWorkshop->setSelected(anEmptyList);
myIsNeutralPointClear = isClearInNeutralPoint;
}
-//********************************************************************
-void ModuleBase_WidgetMultiSelector::onCopyItem()
-{
- QList<QListWidgetItem*> aItems = myListControl->selectedItems();
- QString aRes;
- foreach(QListWidgetItem* aItem, aItems) {
- if (!aRes.isEmpty())
- aRes += "\n";
- aRes += aItem->text();
- }
- if (!aRes.isEmpty()) {
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(aRes);
- }
-}
-
//********************************************************************
void ModuleBase_WidgetMultiSelector::onDeleteItem()
{
//********************************************************************
void ModuleBase_WidgetMultiSelector::onListSelection()
{
- QList<QListWidgetItem*> aItems = myListControl->selectedItems();
- myCopyAction->setEnabled(!aItems.isEmpty());
- myDeleteAction->setEnabled(!aItems.isEmpty());
-
myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects,
true);
}
//********************************************************************
void ModuleBase_WidgetMultiSelector::getSelectedAttributeIndices(std::set<int>& theAttributeIds)
{
- QList<QListWidgetItem*> aItems = myListControl->selectedItems();
- foreach(QListWidgetItem* anItem, aItems) {
- int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt();
- if (theAttributeIds.find(anIndex) == theAttributeIds.end())
- theAttributeIds.insert(anIndex);
- }
+ myListView->getSelectedIndices(theAttributeIds);
}
void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set<int> theAttributeIds,
}
return aFound;
}
+
+QList<ActionInfo>
+ ModuleBase_WidgetMultiSelector::actionsList(ModuleBase_ActionType theActionType) const
+{
+ QList<ActionInfo> aList;
+ if (myCurrentHistoryIndex > -1) {
+ int i = 0;
+ QString aTitle("Selection %1 items");
+ QString aTit("Selection %1 item");
+ QIcon aIcon(":pictures/selection.png");
+ int aNb;
+ switch (theActionType) {
+ case ActionUndo:
+ i = 1;
+ while (i <= myCurrentHistoryIndex) {
+ aNb = mySelectedHistoryValues.at(i).count();
+ if (aNb == 1) {
+ ActionInfo aInfo(aIcon, aTit.arg(aNb));
+ aList.insert(0, aInfo);
+ } else {
+ ActionInfo aInfo(aIcon, aTitle.arg(aNb));
+ aList.insert(0, aInfo);
+ }
+ i++;
+ }
+ break;
+ case ActionRedo:
+ i = mySelectedHistoryValues.length() - 1;
+ while (i > myCurrentHistoryIndex) {
+ aNb = mySelectedHistoryValues.at(i).count();
+ if (aNb == 1) {
+ ActionInfo aInfo(aIcon, aTit.arg(mySelectedHistoryValues.at(i).count()));
+ aList.insert(0, aInfo);
+ } else {
+ ActionInfo aInfo(aIcon, aTitle.arg(mySelectedHistoryValues.at(i).count()));
+ aList.insert(0, aInfo);
+ }
+ i--;
+ }
+ break;
+ }
+ }
+ return aList;
+}
\ No newline at end of file
#include <QMap>
class QWidget;
-class QListWidget;
//class QComboBox;
+class ModuleBase_ListView;
class ModuleBase_IWorkshop;
-class QAction;
class ModuleBase_ChoiceCtrl;
-
/**
* \ingroup GUI
* Implementation of widget for shapes selection. This widget provides selection of several shapes.
/// The methiod called when widget is deactivated
virtual void deactivate();
+ /// Update Undo/Redo actions state
+ virtual void updateAfterDeactivation();
+
+ /// Update Undo/Redo actions state
+ virtual void updateAfterActivation();
+
/// Set the given wrapped value to the current widget
/// This value should be processed in the widget according to the needs
/// \param theValues the wrapped selection values
virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
/// Returns true if the event is processed. The default implementation is empty, returns false.
- virtual bool processAction(ModuleBase_ActionType theActionType);
-
- /// Activate or deactivate selection and selection filters
- /// \return true if the selection filter of the widget is activated in viewer context
- virtual bool activateSelectionAndFilters(bool toActivate);
+ virtual bool processAction(ModuleBase_ActionType theActionType,
+ const ActionParamPtr& theParam = ActionParamPtr());
/// Checks the widget validity. By default, it returns true.
/// \param thePrs a selected presentation in the view
/// \return a boolean value
virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+ /// Returns list of accessible actions for Undo/Redo commands. By default it returns empty list.
+ /// \param theActionType type of action. It can be ActionUndo or ActionRedo.
+ virtual QList<ActionInfo> actionsList(ModuleBase_ActionType theActionType) const;
+
public slots:
/// Slot is called on selection type changed
void onSelectionTypeChanged();
- /// Slot which is called on selection event. Redefined to process XML state about
- /// clear selection in neutral point
- virtual void onSelectionChanged();
+protected:
+ /// Returns true if envent is processed.
+ /// Redefined to process XML state about clear selection in neutral point
+ virtual bool processSelection();
protected slots:
- /// Slot for copy command in a list pop-up menu
- void onCopyItem();
-
/// Slot for delete command in a list pop-up menu
void onDeleteItem();
ModuleBase_IWorkshop* theWorkshop);
protected:
- /// List control
- QListWidget* myListControl;
+ ModuleBase_ListView* myListView; ///< List control
+
+ bool myIsUseChoice; ///< A flag to store use_choice parameter state
- QStringList myShapeTypes;
+ QStringList myShapeTypes; ///< List of Shape types defined in XML
/// Control for types
ModuleBase_ChoiceCtrl* myTypeCtrl;
- /// Provides correspondance between Result object and its shape
- typedef QPair<ResultPtr, GeomShapePtr> GeomSelection;
-
- /// A copy action for pop-up menu in a list control
- QAction* myCopyAction;
-
- /// A delete action for pop-up menu in a list control
- QAction* myDeleteAction;
-
- /// A flag to store use_choice parameter state
- bool myIsUseChoice;
-
/// A flag to clear selection by click in empty place in the viewer
bool myIsNeutralPointClear;
#include <ModuleBase_WidgetSelector.h>
+#include <ModuleBase_Events.h>
+#include <ModuleBase_IModule.h>
#include <ModuleBase_ISelection.h>
+#include <ModuleBase_ISelectionActivate.h>
#include <ModuleBase_IWorkshop.h>
-#include <ModuleBase_Tools.h>
#include <ModuleBase_Operation.h>
#include <ModuleBase_OperationDescription.h>
-#include <ModuleBase_WidgetFactory.h>
-#include <ModuleBase_IModule.h>
#include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_Tools.h>
#include <ModuleBase_ViewerPrs.h>
-#include <ModuleBase_Events.h>
+#include <ModuleBase_WidgetFactory.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_Events.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_ResultConstruction.h>
#include <TopoDS_Iterator.hxx>
}
//********************************************************************
-void ModuleBase_WidgetSelector::onSelectionChanged()
+bool ModuleBase_WidgetSelector::processSelection()
{
QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
// equal vertices should not be used here
bool isDone = setSelection(aSelected, true/*false*/);
updateOnSelectionChanged(isDone);
+
+ return isDone;
}
//********************************************************************
}
//********************************************************************
-bool ModuleBase_WidgetSelector::activateSelectionAndFilters(bool toActivate)
+void ModuleBase_WidgetSelector::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
+{
+ theModuleSelectionModes = -1;
+ theModes.append(getShapeTypes());
+}
+
+//********************************************************************
+void ModuleBase_WidgetSelector::updateSelectionModesAndFilters(bool toActivate)
{
updateSelectionName();
- if (toActivate) {
- myWorkshop->activateSubShapesSelection(getShapeTypes());
- } else {
- myWorkshop->deactivateSubShapesSelection();
- }
- return activateFilters(toActivate);
+ myWorkshop->selectionActivate()->updateSelectionFilters();
+ myWorkshop->selectionActivate()->updateSelectionModes();
+
+ if (!toActivate)
+ clearValidatedCash();
}
//********************************************************************
void ModuleBase_WidgetSelector::activateCustom()
{
- connect(myWorkshop, SIGNAL(selectionChanged()), this,
- SLOT(onSelectionChanged()), Qt::UniqueConnection);
-
- activateSelectionAndFilters(true);
-
// Restore selection in the viewer by the attribute selection list
// it should be postponed to have current widget as active to validate restored selection
static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
//********************************************************************
void ModuleBase_WidgetSelector::deactivate()
{
- ModuleBase_ModelWidget::deactivate();
- disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- activateSelectionAndFilters(false);
-
+ ModuleBase_WidgetValidated::deactivate();
/// clear temporary cash
AttributePtr anAttribute = attribute();
if (!anAttribute.get())
virtual ~ModuleBase_WidgetSelector();
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param [out] theModes a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
/// Defines if it is supposed that the widget should interact with the viewer.
virtual bool isViewerSelector() { return true; }
/// Activate or deactivate selection and selection filters
- /// \return true if the selection filter of the widget is activated in viewer context
- virtual bool activateSelectionAndFilters(bool toActivate);
+ virtual void updateSelectionModesAndFilters(bool toActivate);
/// Checks the widget validity. By default, it returns true.
/// \param thePrs a selected presentation in the view
/// a shape. If the attribute do not uses the shape, it is empty
virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getAttributeSelection() const;
-protected slots:
- /// Slot which is called on selection event
- virtual void onSelectionChanged();
-
protected:
+ /// Returns true if envent is processed. The default implementation is empty, returns false.
+ virtual bool processSelection();
+
/// Emits model changed info, updates the current control by selection change
/// \param theDone a state whether the selection is set
virtual void updateOnSelectionChanged(const bool theDone);
//
#include <ModuleBase_WidgetValidated.h>
+#include <ModuleBase_IModule.h>
#include <ModuleBase_IViewer.h>
#include <ModuleBase_IWorkshop.h>
#include <ModuleBase_ISelection.h>
+#include <ModuleBase_ISelectionActivate.h>
#include <ModuleBase_WidgetSelectorStore.h>
#include <ModuleBase_ViewerPrs.h>
return myPresentedObject;
}
+//********************************************************************
+void ModuleBase_WidgetValidated::deactivate()
+{
+ clearValidatedCash();
+}
+
//********************************************************************
void ModuleBase_WidgetValidated::clearValidatedCash()
{
// the widget validator filter should be active, but during check by preselection
// it is not yet activated, so we need to activate/deactivate it manually
bool isActivated = isFilterActivated();
- if (!isActivated)
- activateFilters(true);
+ if (!isActivated) {
+ QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
+ SelectMgr_ListOfFilter aSelectionFilters;
+ selectionFilters(aModuleSelectionFilters, aSelectionFilters);
+ /// after validation, the selection filters should be restored
+ myWorkshop->selectionActivate()->activateSelectionFilters(aSelectionFilters);
+ }
Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
if (!aContext.IsNull()) {
}
}
if (!isActivated)
- activateFilters(false);
+ {
+ // reset filters set in activateSelectionFilters above
+ myWorkshop->selectionActivate()->updateSelectionFilters();
+ clearValidatedCash();
+ }
}
// removes created owner
return aFactory->validate(theAttribute, aValidatorID, anError);
}
+//********************************************************************
bool ModuleBase_WidgetValidated::isFilterActivated() const
{
bool isActivated = false;
return aViewer->hasSelectionFilter(aSelFilter);
}
-bool ModuleBase_WidgetValidated::activateFilters(const bool toActivate)
+//********************************************************************
+void ModuleBase_WidgetValidated::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
{
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();
-
- Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
- bool aHasSelectionFilter = aViewer->hasSelectionFilter(aSelFilter);
-
- if (toActivate)
- aViewer->addSelectionFilter(aSelFilter);
- else {
- aViewer->removeSelectionFilter(aSelFilter);
- clearValidatedCash();
- }
-
- return aHasSelectionFilter;
+ theSelectionFilters.Append(myWorkshop->validatorFilter());
}
//********************************************************************
//! Returns data object by AIS
ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const;
+ /// The method called when widget is deactivated
+ virtual void deactivate();
+
//! Clear all validated cash in the widget
void clearValidatedCash();
/// \return boolean value
bool isFilterActivated() const;
+ /// Appends into container of workshop selection filters
+ /// \param [out] theModuleSelectionFilters module additional modes, -1 means all default modes
+ /// \param [out] selection filters
+ virtual void selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters);
+
/// Block the model flush of update and intialization of attribute
/// \param theAttribute an attribute of blocking
/// \param theFeature a feature
/// \return a list of presentations
QList<std::shared_ptr<ModuleBase_ViewerPrs>> getFilteredSelected();
- /// It obtains selection filters from the workshop and activates them in the active viewer
- /// \param toActivate a flag about activation or deactivation the filters
- /// \return true if the selection filter of the widget is activated in viewer context
- bool activateFilters(const bool toActivate);
-
/// Block the model flush of update and intialization of attribute
/// \param theAttribute an attribute of blocking
/// \param theToBlock flag whether the model is blocked or unblocked
delete myAttributeStore;
}
+//********************************************************************
+void ModuleBase_WidgetValidator::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ theSelectionFilters.Append(myWorkshop->validatorFilter());
+}
+
//********************************************************************
bool ModuleBase_WidgetValidator::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue)
{
return aValid;
}
-bool ModuleBase_WidgetValidator::activateFilters(const bool toActivate)
-{
- ModuleBase_IViewer* aViewer = myWorkshop->viewer();
-
- Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
- bool aHasSelectionFilter = aViewer->hasSelectionFilter(aSelFilter);
-
- if (toActivate)
- aViewer->addSelectionFilter(aSelFilter);
- else {
- aViewer->removeSelectionFilter(aSelFilter);
- clearValidatedCash();
- }
-
- return aHasSelectionFilter;
-}
-
void ModuleBase_WidgetValidator::storeAttributeValue(const AttributePtr& theAttribute)
{
myIsInValidate = true;
#ifndef ModuleBase_WidgetValidator_H_
#define ModuleBase_WidgetValidator_H_
-#include <ModuleBase.h>
+#include "ModuleBase.h"
+
+#include "ModuleBase_Definitions.h"
+
+#include <SelectMgr_ListOfFilter.hxx>
#include <QList>
#include <memory>
ModuleBase_IWorkshop* theWorkshop);
virtual ~ModuleBase_WidgetValidator();
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param theModes [out] a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes) {}
+
+ /// Appends into container of workshop selection filters
+ /// \param [out] theModuleSelectionFilters module additional modes, -1 means all default modes
+ /// \param [out] selection filters
+ virtual void selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters);
+
/// Returns true if the validation is activated
bool isInValidate() const { return myIsInValidate; }
/// \return a boolean value
virtual bool isValidSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theValue);
- /// It obtains selection filters from the workshop and activates them in the active viewer
- /// \param toActivate a flag about activation or deactivation the filters
- /// \return true if the selection filter of the widget is activated in viewer context
- bool activateFilters(const bool toActivate);
-
/// Creates a backup of the current values of the attribute
/// It should be realized in the specific widget because of different
/// parameters of the current attribute
/// \return true if all validators return that the attribute is valid
bool isValidAttribute(const std::shared_ptr<ModelAPI_Attribute>& theAttribute) const;
+ //! Clear all validated cash in the widget
+ void clearValidatedCash();
+
private:
/// Returns true if the workshop validator filter has been already activated
/// \return boolean value
bool isFilterActivated() const;
- //! Clear all validated cash in the widget
- void clearValidatedCash();
-
/// Gets the validity state of the presentation in an internal map.
/// Returns true if the valid state of value is stored
/// \param theValue a viewer presentation
/// Reference to workshop
ModuleBase_ModelWidget* myModelWidget; ///< the current widget to be validated
ModuleBase_IWorkshop* myWorkshop; ///< the active workshop
- ModuleBase_WidgetSelectorStore* myAttributeStore; //< store/restore attribute values
+ ModuleBase_WidgetSelectorStore* myAttributeStore; ///< store/restore attribute values
/// cash of valid selection presentations
QList<std::shared_ptr<ModuleBase_ViewerPrs>> myValidPrs;
int aNbFeatures = aDoc->numInternalFeatures();
for (int i = 0; i < aNbFeatures; i++) {
aParamFeature = aDoc->internalFeature(i);
- if (aParamFeature->getKind() == ParametersPlugin_Parameter::ID()) {
+ if (aParamFeature && aParamFeature->getKind() == ParametersPlugin_Parameter::ID()) {
myParametersList.append(aParamFeature);
}
}
//
#include "PartSet_ExternalObjectsMgr.h"
+
+#include "PartSet_CenterPrs.h"
#include "PartSet_Tools.h"
#include <XGUI_Workshop.h>
return aSelectedObject;
}
+ObjectPtr PartSet_ExternalObjectsMgr::externalCenterObject(const ModuleBase_ViewerPrsPtr& thePrs,
+ const CompositeFeaturePtr& theSketch,
+ const bool theTemporary)
+{
+ if (!thePrs.get() || thePrs->interactive().IsNull())
+ return ObjectPtr();
+
+ Handle(PartSet_CenterPrs) aAIS = Handle(PartSet_CenterPrs)::DownCast(thePrs->interactive());
+ if (aAIS.IsNull())
+ return ObjectPtr();
+
+ gp_Pnt aPntComp = aAIS->Component()->Pnt();
+ GeomVertexPtr aVertPtr(new GeomAPI_Vertex(aPntComp.X(), aPntComp.Y(), aPntComp.Z()));
+ TopoDS_Shape aShape = aVertPtr->impl<TopoDS_Shape>();
+
+ ResultPtr aSelectedObject =
+ PartSet_Tools::findFixedObjectByExternal(aShape, aAIS->object(), theSketch);
+ if (!aSelectedObject.get())
+ {
+ FeaturePtr aCreatedFeature;
+ aSelectedObject = PartSet_Tools::createFixedByExternalCenter(aAIS->object(), aAIS->edge(),
+ aAIS->centerType(), theSketch, theTemporary, aCreatedFeature);
+ if (aCreatedFeature.get() && theTemporary)
+ myExternalObjectValidated = aCreatedFeature;
+ }
+ return aSelectedObject;
+}
+
void PartSet_ExternalObjectsMgr::getGeomSelection(const ModuleBase_ViewerPrsPtr& thePrs,
- ObjectPtr& theObject,
- GeomShapePtr& theShape,
- ModuleBase_IWorkshop* theWorkshop,
- const CompositeFeaturePtr& theSketch,
- const bool isInValidate)
+ ObjectPtr& theObject,
+ GeomShapePtr& theShape,
+ ModuleBase_IWorkshop* theWorkshop,
+ const CompositeFeaturePtr& theSketch,
+ const bool isInValidate)
{
FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(theObject);
std::shared_ptr<SketchPlugin_Feature> aSPFeature =
if (aShape.get() != NULL && !aShape->isNull())
anExternalObject =
externalObject(theObject, aShape, theSketch, isInValidate);
+ if (!anExternalObject.get()) {
+ anExternalObject = externalCenterObject(thePrs, theSketch, isInValidate);
+ }
}
else { /// use objects of found selection
anExternalObject = theObject;
ObjectPtr externalObject(const ObjectPtr& theSelectedObject, const GeomShapePtr& theShape,
const CompositeFeaturePtr& theSketch, const bool theTemporary = false);
+ /// Finds or create and external object by selected circle center (PartSet_CenterPrs)
+ /// \param thePrs a selection
+ /// \param theSketch a current sketch
+ /// \param theTemporary the created external object is temporary, execute is not performed for it
+ /// \return the object
+ ObjectPtr externalCenterObject(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,
+ const CompositeFeaturePtr& theSketch,
+ const bool theTemporary);
+
// Removes the external presentation from the model
/// \param theSketch a current sketch
/// \param theFeature a current feature
#include <XGUI_Tools.h>
#include <XGUI_Displayer.h>
#include <XGUI_Workshop.h>
+#include <XGUI_SelectionActivate.h>
#include <XGUI_SelectionMgr.h>
PartSet_ExternalPointsMgr::PartSet_ExternalPointsMgr(ModuleBase_IWorkshop* theWorkshop,
myPresentations[aPrs->object()] = aList;
foreach(AISObjectPtr anAIS, aList) {
aDisplayer->displayAIS(anAIS, false);
- aDisplayer->activateAIS(anAIS->impl<Handle(AIS_InteractiveObject)>(), TopAbs_VERTEX, false);
+ aWorkshop->selectionActivate()->activateAIS(anAIS->impl<Handle(AIS_InteractiveObject)>(),
+ TopAbs_VERTEX, false);
}
}
}
return aValid;
}
+IMPLEMENT_STANDARD_RTTIEXT(PartSet_ResultGroupNameFilter, SelectMgr_Filter);
+
+void PartSet_ResultGroupNameFilter::setGroupNames(const std::set<std::string>& theGroupNames)
+{
+ myGroupNames = theGroupNames;
+}
+
+Standard_Boolean PartSet_ResultGroupNameFilter::IsOk(
+ const Handle(SelectMgr_EntityOwner)& theOwner) const
+{
+ std::shared_ptr<GeomAPI_AISObject> aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+ if (theOwner->HasSelectable()) {
+ Handle(AIS_InteractiveObject) aAisObj =
+ Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
+ if (!aAisObj.IsNull()) {
+ aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aAisObj));
+ }
+ }
+ ObjectPtr anObject = myWorkshop->findPresentedObject(aAISObj);
+ if (!anObject.get())
+ return true;
+
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ // result of parts belongs to PartSet document and can be selected only when PartSet
+ // is active in order to do not select the result of the active part.
+ if (!aResult.get())
+ return true;
+
+ std::string aGroupName = aResult->groupName();// == ModelAPI_ResultPart::group()) {
+ if (myGroupNames.find(aGroupName) != myGroupNames.end())
+ return false; // the object of the filtered type is found
+
+ return true;
+}
+
+
IMPLEMENT_STANDARD_RTTIEXT(PartSet_CirclePointFilter, SelectMgr_Filter);
Standard_Boolean
#include <ModuleBase_ViewerFilters.h>
+#include <set>
+#include <string>
/**
* \class PartSet_GlobalFilter
DEFINE_STANDARD_RTTIEXT(PartSet_GlobalFilter, ModuleBase_ShapeDocumentFilter)
};
+/// \class PartSet_ResultGroupNameFilter
+/// \ingroup Modules
+/// A class which filters results with groupName() result in filter parameters
+DEFINE_STANDARD_HANDLE(PartSet_ResultGroupNameFilter, SelectMgr_Filter);
+class PartSet_ResultGroupNameFilter: public SelectMgr_Filter
+{
+public:
+ /// Constructor
+ /// \param theWorkshop a pointer to workshop
+ PartSet_ResultGroupNameFilter(ModuleBase_IWorkshop* theWorkshop)
+ : SelectMgr_Filter(), myWorkshop(theWorkshop) {}
+
+ void setGroupNames(const std::set<std::string>& theGroupNames);
+
+ /// Returns True if selected presentation can be selected
+ /// \param theOwner an owner of the persentation
+ Standard_EXPORT virtual Standard_Boolean
+ IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const;
+
+ DEFINE_STANDARD_RTTIEXT(PartSet_ResultGroupNameFilter, SelectMgr_Filter)
+
+private:
+ ModuleBase_IWorkshop* myWorkshop;
+ std::set<std::string> myGroupNames;
+};
/// \class PartSet_CirclePointFilter
/// \ingroup GUI
#include <ModuleBase_IViewer.h>
#include <ModuleBase_IViewWindow.h>
#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ISelectionActivate.h>
#include <ModuleBase_WidgetChoice.h>
#include <ModuleBase_WidgetEditor.h>
#include <ModuleBase_WidgetValidated.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Dir.h>
-#include <XGUI_Displayer.h>
-#include <XGUI_Workshop.h>
-#include <XGUI_OperationMgr.h>
-#include <XGUI_PropertyPanel.h>
-#include <XGUI_ModuleConnector.h>
+#include <XGUI_ActiveControlMgr.h>
+#include <XGUI_ActiveControlSelector.h>
+#include <XGUI_ActionsMgr.h>
#include <XGUI_ContextMenuMgr.h>
-#include <XGUI_Tools.h>
-#include <XGUI_ObjectsBrowser.h>
-#include <XGUI_SelectionMgr.h>
+#include <XGUI_CustomPrs.h>
#include <XGUI_DataModel.h>
+#include <XGUI_Displayer.h>
#include <XGUI_ErrorMgr.h>
-#include <XGUI_CustomPrs.h>
+#include <XGUI_FacesPanelSelector.h>
+#include <XGUI_ModuleConnector.h>
+#include <XGUI_ObjectsBrowser.h>
+#include <XGUI_OperationMgr.h>
+#include <XGUI_PropertyPanel.h>
#include <XGUI_SelectionMgr.h>
-#include <XGUI_ActionsMgr.h>
+#include <XGUI_Tools.h>
+#include <XGUI_Workshop.h>
#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_ConstraintLength.h>
return new PartSet_Module(theWshop);
}
+//******************************************************
PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
: ModuleBase_IModule(theWshop),
myVisualLayerId(0),
Events_Loop* aLoop = Events_Loop::loop();
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
- mySelectionFilters.Append(new PartSet_GlobalFilter(myWorkshop));
- mySelectionFilters.Append(new PartSet_FilterInfinite(myWorkshop));
+ registerSelectionFilter(SF_GlobalFilter, new PartSet_GlobalFilter(myWorkshop));
+ registerSelectionFilter(SF_FilterInfinite, new PartSet_FilterInfinite(myWorkshop));
+ Handle(PartSet_ResultGroupNameFilter) aCRFilter = new PartSet_ResultGroupNameFilter(myWorkshop);
+ std::set<std::string> aCRGroupNames;
+ aCRGroupNames.insert(ModelAPI_ResultConstruction::group());
+ aCRFilter->setGroupNames(aCRGroupNames);
+ registerSelectionFilter(SF_ResultGroupNameFilter, aCRFilter);
setDefaultConstraintShown();
Config_PropManager::registerProp("Visualization", "sketch_preview_plane",
"Color of sketch plane", Config_Prop::Color,
PartSet_CustomPrs::OPERATION_SKETCH_PLANE());
+
+ Config_PropManager::registerProp("Visualization", "hidden_face_transparency",
+ "Hidden faces transparency",
+ Config_Prop::Double,
+ "0.8");
}
+//******************************************************
PartSet_Module::~PartSet_Module()
{
- SelectMgr_ListIteratorOfListOfFilter aIt(mySelectionFilters);
- for (; aIt.More(); aIt.Next()) {
- Handle(SelectMgr_Filter) aFilter = aIt.Value();
+ std::map<XGUI_SelectionFilterType, Handle(SelectMgr_Filter)>::const_iterator aFiltersIt =
+ mySelectionFilters.begin();
+ for (; aFiltersIt != mySelectionFilters.end(); aFiltersIt++) {
+ Handle(SelectMgr_Filter) aFilter = aFiltersIt->second;
if (!aFilter.IsNull())
aFilter.Nullify();
}
delete myOverconstraintListener;
}
-void PartSet_Module::activateSelectionFilters()
-{
- SelectMgr_ListIteratorOfListOfFilter aIt(mySelectionFilters);
- for (; aIt.More(); aIt.Next()) {
- Handle(SelectMgr_Filter) aFilter = aIt.Value();
- if (!aFilter.IsNull())
- myWorkshop->viewer()->addSelectionFilter(aFilter);
- }
-}
-
-void PartSet_Module::deactivateSelectionFilters()
-{
- SelectMgr_ListIteratorOfListOfFilter aIt(mySelectionFilters);
- for (; aIt.More(); aIt.Next()) {
- Handle(SelectMgr_Filter) aFilter = aIt.Value();
- if (!aFilter.IsNull())
- myWorkshop->viewer()->removeSelectionFilter(aFilter);
- }
-}
-
+//******************************************************
void PartSet_Module::storeSelection()
{
// cash is used only to restore selection, so it should be filled in storeSelection and
sketchMgr()->storeSelection(PartSet_SketcherMgr::ST_SelectType, myCurrentSelection);
}
+//******************************************************
void PartSet_Module::restoreSelection()
{
// cash is used only to restore selection, so it should be filled in storeSelection and
myCurrentSelection.clear();
}
+//******************************************************
void PartSet_Module::registerValidators()
{
//Registering of validators
aFactory->registerValidator("PartSet_ProjectionSelection", new PartSet_ProjectionSelection);
}
+//******************************************************
void PartSet_Module::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget,
const bool isToConnect)
{
mySketchMgr->connectToPropertyPanel(theWidget, isToConnect);
}
+//******************************************************
void PartSet_Module::operationCommitted(ModuleBase_Operation* theOperation)
{
if (sketchMgr()->isNestedSketchOperation(theOperation)) {
}
}
+//******************************************************
void PartSet_Module::operationAborted(ModuleBase_Operation* theOperation)
{
/// Restart sketcher operations automatically
overconstraintListener()->setActive(false);
}
+//******************************************************
void PartSet_Module::operationStarted(ModuleBase_Operation* theOperation)
{
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
}
}
+//******************************************************
void PartSet_Module::updateSketcherOnStart(ModuleBase_Operation* theOperation)
{
if (PartSet_SketcherMgr::isSketchOperation(theOperation)) {
}
}
+//******************************************************
void PartSet_Module::updatePresentationsOnStart(ModuleBase_Operation* theOperation)
{
ModuleBase_OperationFeature* aFOperation =
}
}
+//******************************************************
void PartSet_Module::operationResumed(ModuleBase_Operation* theOperation)
{
ModuleBase_IModule::operationResumed(theOperation);
}
}
+//******************************************************
void PartSet_Module::operationStopped(ModuleBase_Operation* theOperation)
{
bool isModifiedArgs = myCustomPrs->deactivate(ModuleBase_IModule::CustomizeArguments, false);
}
}
+//******************************************************
ModuleBase_Operation* PartSet_Module::currentOperation() const
{
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
return anOpMgr->currentOperation();
}
+//******************************************************
bool PartSet_Module::canUndo() const
{
bool aCanUndo = false;
return aCanUndo;
}
+//******************************************************
bool PartSet_Module::canRedo() const
{
bool aCanRedo = false;
return aCanRedo;
}
+//******************************************************
bool PartSet_Module::canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const
{
bool aValid = true;
return aValid;
}
+//******************************************************
bool PartSet_Module::canEraseObject(const ObjectPtr& theObject) const
{
// the sketch manager put the restriction to the objects erase
return mySketchMgr->canEraseObject(theObject);
}
+//******************************************************
bool PartSet_Module::canDisplayObject(const ObjectPtr& theObject) const
{
// the sketch manager put the restriction to the objects display
return mySketchMgr->canDisplayObject(theObject);
}
+//******************************************************
bool PartSet_Module::canUsePreselection(const QString& thePreviousOperationKind,
const QString& theStartedOperationKind)
{
mySketchMgr->processHiddenObject(theObjects);
}*/
+//******************************************************
bool PartSet_Module::canActivateSelection(const ObjectPtr& theObject) const
{
bool aCanActivate = ModuleBase_IModule::canActivateSelection(theObject);
return aCanActivate;
}
+//******************************************************
bool PartSet_Module::addViewerMenu(const QMap<QString, QAction*>& theStdActions,
QWidget* theParent,
QMap<int, QAction*>& theMenuActions) const
return myMenuMgr->addViewerMenu(theStdActions, theParent, theMenuActions);
}
+//******************************************************
void PartSet_Module::updateViewerMenu(const QMap<QString, QAction*>& theStdActions)
{
myMenuMgr->updateViewerMenu(theStdActions);
}
+//******************************************************
bool PartSet_Module::isActionEnableStateFixed(const int theActionId) const
{
bool isEnabledFixed = false;
return isEnabledFixed;
}
+//******************************************************
QString PartSet_Module::getFeatureError(const FeaturePtr& theFeature)
{
QString anError = ModuleBase_IModule::getFeatureError(theFeature);
return anError;
}
+//******************************************************
void PartSet_Module::grantedOperationIds(ModuleBase_Operation* theOperation,
QStringList& theIds) const
{
}
}
+//******************************************************
void PartSet_Module::activeSelectionModes(QIntList& theModes)
{
- theModes.clear();
if (mySketchMgr->activeSketch().get())
- PartSet_SketcherMgr::sketchSelectionModes(theModes);
+ PartSet_SketcherMgr::sketchSelectionModes(mySketchMgr->activeSketch(), theModes);
+ else
+ theModes = XGUI_Tools::workshop(myWorkshop)->viewerSelectionModes();
+}
+
+//******************************************************
+void PartSet_Module::moduleSelectionModes(int theModesType, QIntList& theModes)
+{
+ customSubShapesSelectionModes(theModes);
+ //theModes.append(XGUI_Tools::workshop(myWorkshop)->viewerSelectionModes());
+ //myWorkshop->module()->activeSelectionModes(theModes);
+}
+
+//******************************************************
+void PartSet_Module::moduleSelectionFilters(const QIntList& theFilterTypes,
+ SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ bool isSketchActive = mySketchMgr->activeSketch().get();
+
+ std::map<XGUI_SelectionFilterType, Handle(SelectMgr_Filter)>::const_iterator aFiltersIt =
+ mySelectionFilters.begin();
+ for (; aFiltersIt != mySelectionFilters.end(); aFiltersIt++) {
+ int aFilterType = aFiltersIt->first;
+ // do not add not participating filters in given parameters
+ if (!theFilterTypes.contains(aFilterType))
+ continue;
+
+ // using sketch filters only if sketch operation is active
+ if (!isSketchActive &&
+ mySketchMgr->sketchSelectionFilter((XGUI_SelectionFilterType)aFilterType))
+ continue;
+
+ // using filtering of construction results only from faces panel
+ if (aFilterType == SF_ResultGroupNameFilter)
+ continue;
+
+ theSelectionFilters.Append(aFiltersIt->second);
+ }
}
-void PartSet_Module::customSubShapesSelectionModes(QIntList& theTypes)
+//******************************************************
+QIntList PartSet_Module::selectionFilters()
{
- if (theTypes.contains(TopAbs_FACE))
- theTypes.append(SketcherPrs_Tools::Sel_Sketch_Face);
- if (theTypes.contains(TopAbs_WIRE))
- theTypes.append(SketcherPrs_Tools::Sel_Sketch_Wire);
+ QIntList aTypes;
+
+ std::map<XGUI_SelectionFilterType, Handle(SelectMgr_Filter)>::const_iterator aFiltersIt =
+ mySelectionFilters.begin();
+ for (; aFiltersIt != mySelectionFilters.end(); aFiltersIt++)
+ aTypes.append(aFiltersIt->first);
+
+ return aTypes;
}
+//******************************************************
+void PartSet_Module::registerSelectionFilter(const XGUI_SelectionFilterType theFilterType,
+ const Handle(SelectMgr_Filter)& theFilter)
+{
+ mySelectionFilters[theFilterType] = theFilter;
+}
+
+//******************************************************
+Handle(SelectMgr_Filter) PartSet_Module::selectionFilter(const int theType)
+{
+ XGUI_SelectionFilterType aType = (XGUI_SelectionFilterType)theType;
+
+ if (mySelectionFilters.find(aType) != mySelectionFilters.end())
+ return mySelectionFilters[aType];
+ else
+ return Handle(SelectMgr_Filter)();
+}
+
+//******************************************************
+void PartSet_Module::customSubShapesSelectionModes(QIntList& theModes)
+{
+ if (theModes.contains(TopAbs_FACE))
+ theModes.append(SketcherPrs_Tools::Sel_Sketch_Face);
+ if (theModes.contains(TopAbs_WIRE))
+ theModes.append(SketcherPrs_Tools::Sel_Sketch_Wire);
+
+ if (mySketchMgr->activeSketch().get())
+ PartSet_SketcherMgr::sketchSelectionModes(mySketchMgr->activeSketch(), theModes);
+}
+
+//******************************************************
void PartSet_Module::getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theSelected,
ObjectPtr& theObject, AttributePtr& theAttribute)
{
theObject = anObject;
}
+//******************************************************
bool PartSet_Module::isMouseOverWindow()
{
return mySketchMgr->isMouseOverWindow();
}
+//******************************************************
bool PartSet_Module::isSketchNeutralPointActivated() const
{
bool isNeutralPoint = true;
return isNeutralPoint;
}
+//******************************************************
void PartSet_Module::closeDocument()
{
myActivePartIndex = QModelIndex();
}
+//******************************************************
void PartSet_Module::clearViewer()
{
myCustomPrs->clearPrs();
XGUI_Workshop* aWorkshop = getWorkshop();
XGUI_Displayer* aDisplayer = aWorkshop->displayer();
- aDisplayer->deactivateSelectionFilters();
+ aDisplayer->deactivateSelectionFilters(false);
}
+//******************************************************
void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
{
ModuleBase_OperationFeature* aFOperation =
aPanel->activateWidget(aPanel->modelWidgets().first());
}
+//******************************************************
bool PartSet_Module::createWidgets(ModuleBase_Operation* theOperation,
QList<ModuleBase_ModelWidget*>& theWidgets) const
{
return aProcessed;
}
+//******************************************************
void PartSet_Module::onSelectionChanged()
{
ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
}
}
+//******************************************************
void PartSet_Module::onKeyRelease(ModuleBase_IViewWindow* theWnd, QKeyEvent* theEvent)
{
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
anOpMgr->onKeyReleased(theWnd->viewPort(), theEvent);
}
+//******************************************************
ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& theType,
QWidget* theParent,
Config_WidgetAPI* theWidgetApi)
return aWgt;
}
+//******************************************************
ModuleBase_ModelWidget* PartSet_Module::activeWidget() const
{
ModuleBase_ModelWidget* anActiveWidget = 0;
return anActiveWidget;
}
+//******************************************************
bool PartSet_Module::deleteObjects()
{
bool isProcessed = false;
return isProcessed;
}
+//******************************************************
void PartSet_Module::editFeature(FeaturePtr theFeature)
{
storeConstraintsState(theFeature->getKind());
ModuleBase_IModule::editFeature(theFeature);
}
+//******************************************************
bool PartSet_Module::canCommitOperation() const
{
return true;
}
+//******************************************************
void PartSet_Module::launchOperation(const QString& theCmdId, const bool& isStartAfterCommitOnly)
{
myIsOperationIsLaunched = true;
myIsOperationIsLaunched = false;
}
+//******************************************************
void PartSet_Module::storeConstraintsState(const std::string& theFeatureKind)
{
if (myWorkshop->currentOperation() &&
}
}
+//******************************************************
void PartSet_Module::updateConstraintsState(const std::string& theFeatureKind)
{
if (PartSet_SketcherMgr::constraintsIdList().contains(theFeatureKind.c_str()) ||
}
}
+//******************************************************
void PartSet_Module::onObjectDisplayed(ObjectPtr theObject, AISObjectPtr theAIS)
{
Handle(AIS_InteractiveObject) anAIS = theAIS->impl<Handle(AIS_InteractiveObject)>();
if (!aCons.IsNull())
aToUseZLayer = true;
}
- aCtx->SetZLayer(anAIS, myVisualLayerId);
+ if (aToUseZLayer)
+ aCtx->SetZLayer(anAIS, myVisualLayerId);
}
}
+//******************************************************
void PartSet_Module::onBeforeObjectErase(ObjectPtr theObject, AISObjectPtr theAIS)
{
// this is obsolete
// myCustomPrs->redisplay(theObject, false);
}
+//******************************************************
void PartSet_Module::onViewTransformed(int theTrsfType)
{
// Set length of arrows constant in pixel size
}
}
+//******************************************************
bool PartSet_Module::isCustomPrsActivated(const ModuleBase_CustomizeFlag& theFlag) const
{
return myCustomPrs->isActive(theFlag);
}
+//******************************************************
void PartSet_Module::activateCustomPrs(const FeaturePtr& theFeature,
const ModuleBase_CustomizeFlag& theFlag,
const bool theUpdateViewer)
myCustomPrs->activate(theFeature, theFlag, theUpdateViewer);
}
+//******************************************************
void PartSet_Module::deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag,
const bool theUpdateViewer)
{
myCustomPrs->deactivate(theFlag, theUpdateViewer);
}
+//******************************************************
bool PartSet_Module::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
std::shared_ptr<GeomAPI_ICustomPrs> theCustomPrs)
{
return aCustomized;
}
+//******************************************************
bool PartSet_Module::afterCustomisePresentation(std::shared_ptr<ModelAPI_Result> theResult,
AISObjectPtr thePrs,
GeomCustomPrsPtr theCustomPrs)
return aCustomized;
}
+//******************************************************
bool PartSet_Module::customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag,
const bool theUpdateViewer)
{
return isRedisplayed;
}
+//******************************************************
void PartSet_Module::customizeObjectBrowser(QWidget* theObjectBrowser)
{
XGUI_ObjectsBrowser* aOB = dynamic_cast<XGUI_ObjectsBrowser*>(theObjectBrowser);
}
}
+//******************************************************
void PartSet_Module::onActiveDocPopup(const QPoint& thePnt)
{
SessionPtr aMgr = ModelAPI_Session::get();
aMenu.exec(aHeader->mapToGlobal(thePnt));
}
+//******************************************************
Handle(AIS_InteractiveObject) PartSet_Module::createPresentation(const ResultPtr& theResult)
{
return mySketchMgr->createPresentation(theResult);
}
-
+//******************************************************
ObjectPtr PartSet_Module::findPresentedObject(const AISObjectPtr& theAIS) const
{
ObjectPtr anObject;
return anObject;
}
+//******************************************************
bool PartSet_Module::canBeShaded(Handle(AIS_InteractiveObject) theAIS) const
{
bool aCanBeShaged = true;
return aCanBeShaged;
}
+//******************************************************
void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const
{
QObjectPtrList aObjects = myWorkshop->selection()->selectedObjects();
bool hasParameter = false;
bool hasCompositeOwner = false;
bool hasResultInHistory = false;
+ bool hasFolder = false;
ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
- hasCompositeOwner, hasResultInHistory);
+ hasCompositeOwner, hasResultInHistory, hasFolder);
ModuleBase_Operation* aCurrentOp = myWorkshop->currentOperation();
if (aSelected == 1) {
}
}
+//******************************************************
#define EXPAND_PARENT(OBJ) \
QModelIndex aObjIndex = aDataModel->objectIndex(OBJ); \
if (aObjIndex.isValid()) { \
aTreeView->setExpanded(aParent, true); \
}
-
+//******************************************************
void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMessage)
{
if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
}
}
+//******************************************************
void PartSet_Module::onTreeViewDoubleClick(const QModelIndex& theIndex)
{
if (myWorkshop->currentOperation()) // Do not change activation of parts if an operation active
}
}
-
+//******************************************************
void PartSet_Module::onViewCreated(ModuleBase_IViewWindow*)
{
// z layer is created for all started operations in order to visualize operation AIS presentation
}
// if there is an active operation with validated widget,
// the filters of this widget should be activated in the created view
- ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
- if (aOperation) {
- ModuleBase_ModelWidget* anActiveWidget = activeWidget();
- if (anActiveWidget) {
- ModuleBase_WidgetSelector* aWSelector =
- dynamic_cast<ModuleBase_WidgetSelector*>(anActiveWidget);
- if (aWSelector)
- aWSelector->activateSelectionAndFilters(true);
- }
- }
+ myWorkshop->selectionActivate()->updateSelectionFilters();
+ myWorkshop->selectionActivate()->updateSelectionModes();
}
//******************************************************
mySketchMgr->widgetStateChanged(thePreviousState);
}
+//******************************************************
bool PartSet_Module::processEnter(const std::string& thePreviousAttributeID)
{
return mySketchReentrantMgr->processEnter(thePreviousAttributeID);
#include "PartSet.h"
#include "PartSet_Tools.h"
#include "PartSet_OverconstraintListener.h"
+#include "XGUI_SelectionFilterType.h"
#include "PartSet_SketcherMgr.h"
#include <ModuleBase_IModule.h>
//#include <StdSelect_FaceFilter.hxx>
#include <TopoDS_Shape.hxx>
#include <SelectMgr_ListOfFilter.hxx>
+#include <SelectMgr_Filter.hxx>
#include <QMap>
#include <QMenu>
#include <QObject>
#include <QModelIndex>
-#include <string>
-
+#include <map>
#include <memory>
+#include <string>
class ModuleBase_Operation;
class ModuleBase_IViewWindow;
PartSet_Module(ModuleBase_IWorkshop* theWshop);
virtual ~PartSet_Module();
- // Add default selection filters of the module to the current viewer
- virtual void activateSelectionFilters();
- // Remove default selection filters of the module from the current viewer
- virtual void deactivateSelectionFilters();
-
// Stores the current selection
virtual void storeSelection();
virtual void activeSelectionModes(QIntList& theModes);
/// Appends specific selection modes for the module to the list of types
- /// \param theTypes a selection modes to be extended
- virtual void customSubShapesSelectionModes(QIntList& theTypes);
+ /// \param theModesType combination of available selection filters
+ /// \param theModes a selection modes to be extended
+ virtual void moduleSelectionModes(int theModesType, QIntList& theModes);
+
+ /// Appends into container of filters module filters corresponded to the modes type
+ /// \param theFilterTypes container of available selection filters
+ /// \param theSelectionFilters [out] container to be extend by elements
+ virtual void moduleSelectionFilters(const QIntList& theFilterTypes,
+ SelectMgr_ListOfFilter& theSelectionFilters);
+
+ /// Returns types of registered module selection filters
+ /// \param theSelectionFilters [out] container of type value
+ virtual QIntList selectionFilters();
+
+ /// Append selection filter into the module and type of the filter in internal container
+ /// \param theFilterType selection filter type
+ /// \param theFilter added filter
+ void registerSelectionFilter(const XGUI_SelectionFilterType theFilterType,
+ const Handle(SelectMgr_Filter)& theFilter);
+
+ /// Returns selection filter
+ /// \param theType selection filter type
+ /// \param theFilter instance of filter
+ virtual Handle(SelectMgr_Filter) selectionFilter(const int theType);
/// Returns whether the mouse enter the viewer's window
/// \return true if items are added and there is no necessity to provide standard menu
void onChoiceChanged(ModuleBase_ModelWidget* theWidget, int theIndex);
protected:
+ /// Appends specific selection modes for the module to the list of types
+ /// \param theModes a selection modes to be extended
+ virtual void customSubShapesSelectionModes(QIntList& theModes);
+
/// Sets the constraints states in internal map. If the feature kind is a dimensional constraint
/// other dimensions are shown.
/// \param theFeatureKindId a feature kind
private:
bool myIsOperationIsLaunched; /// state of application between launch and stop operation
- SelectMgr_ListOfFilter mySelectionFilters;
+ std::map<XGUI_SelectionFilterType, Handle(SelectMgr_Filter)> mySelectionFilters;
PartSet_SketcherMgr* mySketchMgr;
PartSet_SketcherReentrantMgr* mySketchReentrantMgr;
}
XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
- aDisp->displayAIS(myPlane, true, 1/*shaded*/, false);
+ aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
myPreviewIsDisplayed = true;
}
int aDispMode = 1; // shading
Handle(AIS_InteractiveObject) anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
if (!anAISIO.IsNull()) {
+ //anAISIO->SetInfiniteState(Standard_True);
anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
anAISIO->SetDisplayMode(aDispMode);
}
//
#include "PartSet_SketcherMgr.h"
+
+#include "PartSet_Filters.h"
#include "PartSet_SketcherReentrantMgr.h"
#include "PartSet_Module.h"
#include "PartSet_MouseProcessor.h"
#include <XGUI_Workshop.h>
#include <XGUI_ContextMenuMgr.h>
#include <XGUI_Selection.h>
+#include <XGUI_SelectionActivate.h>
#include <XGUI_SelectionMgr.h>
#include <XGUI_ModuleConnector.h>
#include <XGUI_PropertyPanel.h>
#include <ModuleBase_ViewerPrs.h>
#include <ModuleBase_Tools.h>
#include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_ViewerFilters.h>
#include <GeomDataAPI_Point2D.h>
#include <SketchPlugin_MultiTranslation.h>
#include <SketchPlugin_IntersectionPoint.h>
#include <SketchPlugin_Projection.h>
+#include <SketchPlugin_ConstraintDistanceAlongDir.h>
+#include <SketchPlugin_ConstraintDistanceHorizontal.h>
+#include <SketchPlugin_ConstraintDistanceVertical.h>
#include <SketcherPrs_Tools.h>
myIsConstraintsShown[PartSet_Tools::Expressions] = false;
mySketchPlane = new PartSet_PreviewSketchPlane();
+
+ registerSelectionFilter(SF_SketchCirclePointFilter, new PartSet_CirclePointFilter(anIWorkshop));
+ registerSelectionFilter(SF_SketchPlaneFilter, new ModuleBase_ShapeInPlaneFilter());
}
PartSet_SketcherMgr::~PartSet_SketcherMgr()
{
- if (!myPlaneFilter.IsNull())
- myPlaneFilter.Nullify();
}
void PartSet_SketcherMgr::onEnterViewPort()
connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)),
aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&)));
- connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
- aReentranceMgr, SLOT(onWidgetActivated()));
+ //connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
+ // aReentranceMgr, SLOT(onWidgetActivated()));
}
XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer();
aConstraintIds << SketchPlugin_ConstraintMirror::ID().c_str();
aConstraintIds << SketchPlugin_MultiTranslation::ID().c_str();
aConstraintIds << SketchPlugin_MultiRotation::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintDistanceAlongDir::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintDistanceHorizontal::ID().c_str();
+ aConstraintIds << SketchPlugin_ConstraintDistanceVertical::ID().c_str();
}
return aConstraintIds;
}
-void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)
+void PartSet_SketcherMgr::sketchSelectionModes(const CompositeFeaturePtr& theSketch,
+ QIntList& theModes)
{
- theModes.clear();
+ if (!theSketch.get() || !PartSet_Tools::sketchPlane(theSketch).get())
+ return;
theModes.append(SketcherPrs_Tools::Sel_Dimension_Text);
theModes.append(SketcherPrs_Tools::Sel_Dimension_Line);
return (theKind == SketchPlugin_ConstraintLength::ID()) ||
(theKind == SketchPlugin_ConstraintDistance::ID()) ||
(theKind == SketchPlugin_ConstraintRadius::ID()) ||
- (theKind == SketchPlugin_ConstraintAngle::ID());
+ (theKind == SketchPlugin_ConstraintAngle::ID()) ||
+ (theKind == SketchPlugin_ConstraintDistanceHorizontal::ID()) ||
+ (theKind == SketchPlugin_ConstraintDistanceVertical::ID()) ||
+ (theKind == SketchPlugin_ConstraintDistanceAlongDir::ID());
}
void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
qDebug(QString("startSketch: %1, %2").arg(anInfo.size()).arg(anInfoStr).toStdString().c_str());
#endif
- if(myCirclePointFilter.IsNull()) {
- myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop());
- }
-
- myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);
-
- if (myPlaneFilter.IsNull())
- myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
-
- myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
bool aHasPlane = false;
std::shared_ptr<GeomAPI_Pln> aPln;
aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
- myPlaneFilter->setPlane(aPln);
+ Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter);
+ if (!aFilter.IsNull())
+ Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(aPln);
+
+ workshop()->selectionActivate()->updateSelectionFilters();
+ workshop()->selectionActivate()->updateSelectionModes();
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
- // all displayed objects should be activated in current selection modes according to switched
- // plane filter
- if (aPln.get())
- aConnector->activateModuleSelectionModes();
myExternalPointsMgr = new PartSet_ExternalPointsMgr(myModule->workshop(), myCurrentSketch);
}
// The sketch was aborted
myCurrentSketch = CompositeFeaturePtr();
mySketchPlane->eraseSketchPlane(myModule->workshop());
- // TODO: move this outside of if-else
- myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
// Erase all sketcher objects
QObjectPtrList aObjects = aDisplayer->displayedObjects();
myCurrentSketch = CompositeFeaturePtr();
mySketchPlane->eraseSketchPlane(myModule->workshop());
- myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
-
Events_Loop::loop()->flush(aDispEvent);
}
- // restore the module selection modes, which were changed on startSketch
- aConnector->activateModuleSelectionModes();
+ workshop()->selectionActivate()->updateSelectionFilters();
+ workshop()->selectionActivate()->updateSelectionModes();
}
void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
}
}
-void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)
+bool PartSet_SketcherMgr::sketchSelectionFilter(const XGUI_SelectionFilterType theFilterType)
{
- if (toActivate)
- myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
- else
- myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
+ return mySelectionFilterTypes.find(theFilterType) != mySelectionFilterTypes.end();
+}
+
+void PartSet_SketcherMgr::registerSelectionFilter(const XGUI_SelectionFilterType theFilterType,
+ const Handle(SelectMgr_Filter)& theFilter)
+{
+ mySelectionFilterTypes.insert(theFilterType);
+ myModule->registerSelectionFilter(theFilterType, theFilter);
}
bool PartSet_SketcherMgr::operationActivatedByPreselection()
return isFoundObject;
}
-void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePln)
+void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePlane)
{
- if (myPlaneFilter.IsNull())
- myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
+ Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter);
+ if (!aFilter.IsNull())
+ Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(thePlane);
- myPlaneFilter->setPlane(thePln);
+ workshop()->selectionActivate()->updateSelectionModes();
}
bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,
#include "PartSet.h"
-#include "PartSet_Filters.h"
-#include "PartSet_Tools.h"
#include "PartSet_PreviewSketchPlane.h"
+#include "XGUI_SelectionFilterType.h"
+#include "PartSet_Tools.h"
#include <ModelAPI_Feature.h>
#include <ModelAPI_Attribute.h>
#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_Result.h>
-#include <ModuleBase_ViewerFilters.h>
#include <ModuleBase_Definitions.h>
#include <ModuleBase_ModelWidget.h>
#include <GeomAPI_Pln.h>
+
#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <SelectMgr_ListOfFilter.hxx>
+
#include <TopoDS_Shape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <QList>
#include <QMap>
+#include <set>
+
class PartSet_Module;
class ModuleBase_IViewWindow;
class ModuleBase_ModelWidget;
/// \param theOperation a committed operation
void commitNestedSketch(ModuleBase_Operation* theOperation);
- /// Append the sketch plane filter into the current viewer
- /// \param toActivate state whether the filter should be activated/deactivated
- void activatePlaneFilter(const bool& toActivate);
+ /// Returns true if the filter is created by the sketch manager
+ /// \param theFilterType a checked type
+ /// \return boolean value
+ bool sketchSelectionFilter(const XGUI_SelectionFilterType theFilterType);
+
+ /// Append selection filter into the module and type of the filter in internal container
+ /// \param theFilterType selection filter type
+ /// \param theFilter added filter
+ void registerSelectionFilter(const XGUI_SelectionFilterType theFilterType,
+ const Handle(SelectMgr_Filter)& theFilter);
/// Commit the operation if it is possible. If the operation is dimention constraint,
/// it gives widget editor to input dimention value
static const QStringList& constraintsIdList();
/// Returns a list of modes, where the AIS objects should be activated
+ /// \param theSketch a sketch object, modes are empty if sketch plane is not defined yet
/// \param theModes a list of modes
- static void sketchSelectionModes(QIntList& theModes);
+ static void sketchSelectionModes(const CompositeFeaturePtr& theSketch, QIntList& theModes);
/// Create specific for the module presentation
/// \param theResult an object for presentation
CompositeFeaturePtr myCurrentSketch;
- Handle(PartSet_CirclePointFilter) myCirclePointFilter;
- Handle(ModuleBase_ShapeInPlaneFilter) myPlaneFilter;
+ std::set<XGUI_SelectionFilterType> mySelectionFilterTypes;
+
FeatureToSelectionMap myCurrentSelection;
bool myPreviousUpdateViewerEnabled;
#include "GeomDataAPI_Point2D.h"
#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ISelectionActivate.h>
#include <ModuleBase_OperationFeature.h>
#include <ModuleBase_ModelWidget.h>
#include <ModuleBase_ViewerPrs.h>
#include <ModuleBase_OperationDescription.h>
#include "ModuleBase_ToolBox.h"
#include "ModuleBase_ISelection.h"
+#include "ModuleBase_ISelectionActivate.h"
#include <SketchPlugin_Feature.h>
#include <SketchPlugin_Line.h>
aReentrantMessage->setClickedPoint(myClickedSketchPoint);
}
-void PartSet_SketcherReentrantMgr::onWidgetActivated()
-{
- if (!isActiveMgr())
- return;
- if (!myIsInternalEditOperation)
- return;
-
- PartSet_Module* aModule = module();
- ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget();
- ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel();
- if (aFirstWidget != aPanel->activeWidget()) {
- ModuleBase_WidgetSelector* aWSelector = dynamic_cast<ModuleBase_WidgetSelector*>(aFirstWidget);
- if (aWSelector)
- aWSelector->activateSelectionAndFilters(true);
- }
-}
+//void PartSet_SketcherReentrantMgr::onWidgetActivated()
+//{
+// if (!isActiveMgr())
+// return;
+// if (!myIsInternalEditOperation)
+// return;
+//
+// PartSet_Module* aModule = module();
+// ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget();
+// ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel();
+// if (aFirstWidget != aPanel->activeWidget()) {
+// ModuleBase_WidgetSelector* aWSelector = dynamic_cast<ModuleBase_WidgetSelector*>
+// (aFirstWidget);
+// if (aWSelector) {
+// myWorkshop->selectionActivate()->updateSelectionModesAndFilters(aWSelector);
+// }
+// }
+//}
void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID)
{
connect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped()));
// activate selection filters of the first widget in the viewer
- onWidgetActivated();
+ //onWidgetActivated();
// activate the last active widget in the Property Panel
if (!thePreviousAttributeID.empty()) {
std::cout << "PartSet_SketcherReentrantMgr::deleteInternalFeature: "
<< myInternalFeature->data()->name() << std::endl;
#endif
- if (myInternalActiveWidget) {
- ModuleBase_WidgetSelector* aWSelector =
- dynamic_cast<ModuleBase_WidgetSelector*>(myInternalActiveWidget);
- if (aWSelector)
- aWSelector->activateSelectionAndFilters(false);
+ if (myInternalActiveWidget)
myInternalActiveWidget = 0;
- }
delete myInternalWidget;
myInternalWidget = 0;
private slots:
/// SLOT, that is called by a widget activating in the property panel
/// If the 'internal' edit operation is started, it activates the first widget selection
- void onWidgetActivated();
+ //void onWidgetActivated();
/// SLOT, that is called by no more widget signal emitted by property panel
/// Start an internal edit operation or, if the internal flag is forbided, commits
const std::shared_ptr<GeomAPI_Edge>& theEdge,
ModelAPI_AttributeSelection::CenterType theType,
const CompositeFeaturePtr& theSketch,
- bool theTemporary)
+ bool theTemporary,
+ FeaturePtr& theCreatedFeature)
{
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
if (!aResult.get())
return ResultPtr();
FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID());
+ theCreatedFeature = aProjectionFeature;
AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID()));
anExternalAttr->setValueCenter(aResult, theEdge, theType, theTemporary);
std::set<AttributePtr>::const_iterator anIt;
for (anIt = aRefsList.cbegin(); anIt != aRefsList.cend(); ++anIt) {
FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*anIt)->owner());
- if (aRefFeature->getKind() == theFeatureId)
+ if (aRefFeature && aRefFeature->getKind() == theFeatureId)
return aRefFeature;
}
return FeaturePtr();
const std::shared_ptr<GeomAPI_Edge>& theEdge,
ModelAPI_AttributeSelection::CenterType theType,
const CompositeFeaturePtr& theSketch,
- bool theTemporary = false);
+ bool theTemporary,
+ FeaturePtr& theCreatedFeature);
};
}
//********************************************************************
-bool PartSet_WidgetFeaturePointSelector::activateSelectionAndFilters(bool toActivate)
+void PartSet_WidgetFeaturePointSelector::updateSelectionModesAndFilters(bool toActivate)
{
#ifdef HIGHLIGHT_STAYS_PROBLEM
Handle(AIS_InteractiveContext) aContext =
#endif
- return ModuleBase_WidgetShapeSelector::activateSelectionAndFilters(toActivate);
+ ModuleBase_WidgetShapeSelector::updateSelectionModesAndFilters(toActivate);
}
//********************************************************************
/// Activate or deactivate selection and selection filters
/// \return true if the selection filter of the widget is activated in viewer context
- virtual bool activateSelectionAndFilters(bool toActivate);
+ virtual void updateSelectionModesAndFilters(bool toActivate);
/// Set sketcher
/// \param theSketch a sketcher object
#include <Config_WidgetAPI.h>
+#include <PartSet_CenterPrs.h>
#include <PartSet_Tools.h>
#include <PartSet_ExternalObjectsMgr.h>
#include <SketchPlugin_Feature.h>
//********************************************************************
bool PartSet_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
{
- bool aValid = ModuleBase_WidgetMultiSelector::isValidSelectionCustom(thePrs);
+ bool aValid = false;
+ if (thePrs.get() && thePrs->interactive().get() &&
+ thePrs->interactive()->IsKind(STANDARD_TYPE(PartSet_CenterPrs)))
+ aValid = true; // we should not check acceptSubShape for such presentation
+ else
+ aValid = ModuleBase_WidgetMultiSelector::isValidSelectionCustom(thePrs);
+
if (aValid) {
ObjectPtr anObject = myWorkshop->selection()->getResult(thePrs);
aValid = myExternalObjectMgr->isValidObject(anObject);
GeomShapePtr aShape = theValue->shape();
if (aShape.get() && !aShape->isNull()) {
Handle(V3d_View) aView = myWorkshop->viewer()->activeView();
- double aX, aY;
+ double aX = 0, aY = 0;
const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
if (getPoint2d(aView, aTDShape, aX, aY)) {
fillRefAttribute(aX, aY, theValue);
GeomShapePtr aShape = aValue->shape();
if (aShape.get() && !aShape->isNull()) {
Handle(V3d_View) aView = myWorkshop->viewer()->activeView();
- double aX, aY;
+ double aX = 0, aY = 0;
const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
if (getPoint2d(aView, aTDShape, aX, aY)) {
isDone = setPoint(aX, aY);
return aControls;
}
+//********************************************************************
+void PartSet_WidgetPoint2D::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
+{
+ theModuleSelectionModes = -1;
+ theModes << TopAbs_VERTEX;
+ theModes << TopAbs_EDGE;
+}
+//********************************************************************
void PartSet_WidgetPoint2D::activateCustom()
{
- QIntList aModes;
- aModes << TopAbs_VERTEX;
- aModes << TopAbs_EDGE;
- myWorkshop->activateSubShapesSelection(aModes);
-
if (!isEditingMode()) {
FeaturePtr aFeature = feature();
if (aFeature.get() && aFeature->getKind() == SketchPlugin_Point::ID())
storeValue();
ModuleBase_ModelWidget::deactivate();
- myWorkshop->deactivateSubShapesSelection();
}
bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView,
}
}
if (anExternal) {
- double aX, aY;
+ double aX = 0, aY = 0;
if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
// do not create a constraint to the point, which already used by the feature
// if the feature contains the point, focus is not switched
}
}
if (!anExternal) {
- double aX, aY;
+ double aX = 0, aY = 0;
bool isProcessed = false;
if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
// when the point is selected, the coordinates of the point should be set into the attribute
ResultPtr aFixedObject =
PartSet_Tools::findFixedObjectByExternal(aShape, aAIS->object(), mySketch);
if (!aFixedObject.get())
+ {
+ FeaturePtr aCreatedFeature;
aFixedObject = PartSet_Tools::createFixedByExternalCenter(aAIS->object(), aAIS->edge(),
- aAIS->centerType(), mySketch);
+ aAIS->centerType(), mySketch, false, aCreatedFeature);
+ }
if (aFixedObject.get())
setConstraintToObject(aFixedObject);
// fignal updated should be flushed in order to visualize possible created
// external objects e.g. selection of trihedron axis when input end arc point
updateObject(feature());
- double aX, aY;
+ double aX = 0, aY = 0;
if (getPoint2d(aView, aShape, aX, aY)) {
// do not create a constraint to the point, which already used by the feature
// if the feature contains the point, focus is not switched
else {
// A case when point is taken from mouse event
gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
- double aX, anY;
- PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY);
+ double aX = 0, aY = 0;
+ PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY);
// if the feature contains the point, focus is not switched
- if (!setPoint(aX, anY) || isFeatureContainsPoint(myFeature, aX, anY))
+ if (!setPoint(aX, aY) || isFeatureContainsPoint(myFeature, aX, aY))
return;
emit focusOutWidget(this);
gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
- double aX, anY;
- PartSet_Tools::convertTo2D(aPoint, mySketch, theWindow->v3dView(), aX, anY);
+ double aX = 0, aY = 0;
+ PartSet_Tools::convertTo2D(aPoint, mySketch, theWindow->v3dView(), aX, aY);
if (myState != ModifiedInViewer)
storeCurentValue();
// we need to block the value state change
bool isBlocked = blockValueState(true);
- setPoint(aX, anY);
+ setPoint(aX, aY);
blockValueState(isBlocked);
setValueState(ModifiedInViewer);
}
/// Destructor
virtual ~PartSet_WidgetPoint2D();
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param theModes [out] a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
/// Checks if the selection presentation is valid in widget
/// \param theValue a selected presentation in the view
/// \return a boolean value
//
#include "PartSet_WidgetShapeSelector.h"
+
+#include "PartSet_CenterPrs.h"
#include "PartSet_Module.h"
#include "PartSet_SketcherMgr.h"
}
//********************************************************************
-bool PartSet_WidgetShapeSelector::activateSelectionAndFilters(bool toActivate)
+void PartSet_WidgetShapeSelector::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
{
- bool aHasSelectionFilter = ModuleBase_WidgetShapeSelector::activateSelectionAndFilters
- (toActivate);
+ ModuleBase_WidgetShapeSelector::selectionFilters(theModuleSelectionFilters, theSelectionFilters);
+
if (!myUseSketchPlane) {
- XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
- PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(aWorkshop->module());
- bool isUsePlaneFilterOnly = !toActivate;
- aModule->sketchMgr()->activatePlaneFilter(isUsePlaneFilterOnly);
+ if (theModuleSelectionFilters.contains(SF_SketchPlaneFilter))
+ theModuleSelectionFilters.removeAll(SF_SketchPlaneFilter);
}
- return aHasSelectionFilter;
}
//********************************************************************
bool PartSet_WidgetShapeSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
{
- bool aValid = ModuleBase_WidgetShapeSelector::isValidSelectionCustom(thePrs);
+ bool aValid = false;
+ if (thePrs.get() && thePrs->interactive().get() &&
+ thePrs->interactive()->IsKind(STANDARD_TYPE(PartSet_CenterPrs)))
+ aValid = true; // we should not check acceptSubShape for such presentation
+ else
+ aValid = ModuleBase_WidgetShapeSelector::isValidSelectionCustom(thePrs);
+
if (aValid) {
ObjectPtr anObject = myWorkshop->selection()->getResult(thePrs);
aValid = myExternalObjectMgr->isValidObject(anObject);
/// Retrurns installed sketcher
CompositeFeaturePtr sketch() const { return mySketch; }
- /// Activate or deactivate selection and selection filters
- /// \param toActivate boolean state whether it should be activated/deactivated
- virtual bool activateSelectionAndFilters(bool toActivate);
+ /// Appends into container of workshop selection filters
+ /// \param [out] theModuleSelectionFilters module additional modes, -1 means all default modes
+ /// \param [out] theSelectionFilters selection filters
+ virtual void selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters);
protected:
/// Checks the widget validity. By default, it returns true.
}
//********************************************************************
-void PartSet_WidgetSketchCreator::onSelectionChanged()
+bool PartSet_WidgetSketchCreator::processSelection()
{
QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
bool isDone = setSelection(aSelected, true/*false*/);
+
+ return isDone;
}
//********************************************************************
/// \param theDone a state whether the selection is set
void updateOnSelectionChanged(const bool theDone);
-protected slots:
- /// Slot which is called on selection event
- virtual void onSelectionChanged();
+protected:
+ /// Returns true if envent is processed.
+ virtual bool processSelection();
private:
/// Returns true if the selection mode is active. This is when composition feature has no
#include "SketchPlugin_SketchEntity.h"
-#include <XGUI_Workshop.h>
+#include <XGUI_ActionsMgr.h>
#include <XGUI_Displayer.h>
-#include <XGUI_SelectionMgr.h>
+#include <XGUI_ModuleConnector.h>
+#include <XGUI_SelectionActivate.h>
#include <XGUI_Selection.h>
-#include <XGUI_ViewerProxy.h>
-#include <XGUI_ActionsMgr.h>
+#include <XGUI_SelectionMgr.h>
#include <XGUI_Tools.h>
-#include <XGUI_ModuleConnector.h>
+#include <XGUI_ViewerProxy.h>
+#include <XGUI_Workshop.h>
+
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Tools.h>
#include <ModuleBase_Operation.h>
#include <ModuleBase_ViewerPrs.h>
#include <ModuleBase_Tools.h>
#include <ModuleBase_IModule.h>
-#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_Tools.h>
-
#include <GeomAlgoAPI_FaceBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
#include <GeomDataAPI_Point.h>
return aResult;
}
-void PartSet_WidgetSketchLabel::onSelectionChanged()
+bool PartSet_WidgetSketchLabel::processSelection()
{
+ std::shared_ptr<GeomAPI_Pln> aPlane = plane();
+ if (aPlane.get())
+ return false;
+
QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
if (aSelected.empty())
- return;
+ return false;
ModuleBase_ViewerPrsPtr aPrs = aSelected.first();
bool aDone = setSelectionInternal(aSelected, false);
if (aDone) {
updateByPlaneSelected(aPrs);
updateObject(myFeature);
}
+
+ return aDone;
}
void PartSet_WidgetSketchLabel::onShowConstraint(bool theOn)
if (aRotate) {
myWorkshop->viewer()->setViewProjection(aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aTwist);
}
+ QString aSizeOfViewStr = mySizeOfView->text();
+ if (!aSizeOfViewStr.isEmpty()) {
+ bool isOk;
+ double aSizeOfView = aSizeOfViewStr.toDouble(&isOk);
+ if (isOk && aSizeOfView > 0) {
+ Handle(V3d_View) aView3d = myWorkshop->viewer()->activeView();
+ if (!aView3d.IsNull()) {
+ Bnd_Box aBndBox;
+ double aHalfSize = aSizeOfView/2.0;
+ aBndBox.Update(-aHalfSize, -aHalfSize, -aHalfSize, aHalfSize, aHalfSize, aHalfSize);
+ aView3d->FitAll(aBndBox, 0.01, false);
+ }
+ }
+ }
PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
if (aModule)
aModule->onViewTransformed();
//myLabel->setText("");
//myLabel->setToolTip("");
XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
- disconnect(aWorkshop->selector(), SIGNAL(selectionChanged()),
- this, SLOT(onSelectionChanged()));
- // 4. deactivate face selection filter
- activateFilters(false);
// 5. Clear selection mode and define sketching mode
emit planeSelected(plane());
// after the plane is selected in the sketch, the sketch selection should be activated
// it can not be performed in the sketch label widget because, we don't need to switch off
// the selection by any label deactivation, but need to switch it off by stop the sketch
- activateSelection(true);
+ myWorkshop->selectionActivate()->updateSelectionFilters();
+ myWorkshop->selectionActivate()->updateSelectionModes();
// 6. Update sketcher actions
XGUI_ActionsMgr* anActMgr = aWorkshop->actionsMgr();
std::shared_ptr<GeomAPI_Pln> aPlane = plane();
if (aPlane.get()) {
myStackWidget->setCurrentIndex(1);
- activateSelection(true);
return;
}
// Clear previous selection mode It is necessary for correct activation of preview planes
XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
XGUI_Displayer* aDisp = aWorkshop->displayer();
- aDisp->activateObjects(QIntList(), aDisp->displayedObjects(), false);
+ aWorkshop->selectionActivate()->activateObjects(QIntList(), aDisp->displayedObjects(), false);
if (!aBodyIsVisualized) {
// We have to select a plane before any operation
}
else
mySizeOfViewWidget->setVisible(false);
-
- activateSelection(true);
-
- connect(XGUI_Tools::workshop(myWorkshop)->selector(), SIGNAL(selectionChanged()),
- this, SLOT(onSelectionChanged()));
- activateFilters(true);
}
void PartSet_WidgetSketchLabel::deactivate()
{
- ModuleBase_ModelWidget::deactivate();
+ ModuleBase_WidgetValidated::deactivate();
bool aHidePreview = myPreviewPlanes->isPreviewDisplayed();
myPreviewPlanes->erasePreviewPlanes(myWorkshop);
- activateSelection(false);
- activateFilters(false);
if (aHidePreview)
myWorkshop->viewer()->update();
}
-void PartSet_WidgetSketchLabel::activateSelection(bool toActivate)
+void PartSet_WidgetSketchLabel::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
{
- if (toActivate) {
- QIntList aModes;
- std::shared_ptr<GeomAPI_Pln> aPlane = plane();
- if (aPlane.get()) {
- myWorkshop->module()->activeSelectionModes(aModes);
- }
- else {
- aModes << TopAbs_FACE;
- }
- myWorkshop->activateSubShapesSelection(aModes);
- } else {
- myWorkshop->deactivateSubShapesSelection();
- }
+ theModuleSelectionModes = -1;
+ std::shared_ptr<GeomAPI_Pln> aPlane = plane();
+ if (!aPlane.get())
+ theModes << TopAbs_FACE;
}
+void PartSet_WidgetSketchLabel::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ std::shared_ptr<GeomAPI_Pln> aPlane = plane();
+ if (aPlane.get())
+ return;
+ return ModuleBase_WidgetValidated::selectionFilters(theModuleSelectionFilters,
+ theSelectionFilters);
+}
std::shared_ptr<GeomAPI_Dir>
PartSet_WidgetSketchLabel::setSketchPlane(const TopoDS_Shape& theShape)
virtual bool setSelection(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues,
const bool theToValidate);
+ /// Fills given container with selection modes if the widget has it
+ /// \param [out] theModuleSelectionModes module additional modes, -1 means all default modes
+ /// \param theModes [out] a container of modes
+ virtual void selectionModes(int& theModuleSelectionModes, QIntList& theModes);
+
+ /// Using widget selection filter only if plane is not defined.
+ /// \param [out] theModuleSelectionFilters module additional modes, -1 means all default modes
+ /// \param [out] selection filters
+ virtual void selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters);
+
/// Returns list of widget controls
/// \return a control list
virtual QList<QWidget*> getControls() const;
/// The methiod called when widget is deactivated
virtual void deactivate();
+ /// The method called if widget should be activated always
+ virtual bool needToBeActiated() { return true; }
+
/// Returns sketcher plane
std::shared_ptr<GeomAPI_Pln> plane() const;
bool& isAttributeSetInitializedBlocked,
bool& isAttributeSendUpdatedBlocked);
+ /// Returns true if envent is processed.
+ virtual bool processSelection();
+
/// Set the given wrapped value to the current widget
/// This value should be processed in the widget according to the needs
/// The method is called by the current operation to process the operation preselection.
/// \param thePrs a presentation
bool fillSketchPlaneBySelection(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- protected:
- /// Activate or deactivate selection
- void activateSelection(bool toActivate);
-
- private slots:
- /// Slot on change selection
- void onSelectionChanged();
-
+private slots:
/// A slot called on set sketch plane view
void onSetPlaneView();
/// \param theOn a flag show constraints or not
void onShowConstraint(bool theOn);
- private:
+private:
/// Set sketch plane by shape
/// \param theShape a planar face
std::shared_ptr<GeomAPI_Dir> setSketchPlane(const TopoDS_Shape& theShape);
def body_3():
# Create XOZ sketch
- sketch = model.addSketch(part, "Boolean_1_1/Modified_3")
+ sketch = model.addSketch(part, "Boolean_1_1/Modified_Face_3")
# Create base polygon
H, L, l, r = 28, 40, 8, 12
sketch.setRadius(arc, r)
# Binding
- bottom_e = sketch.addLine("Boolean_1_1/Modified_8&Boolean_1_1/Modified_5")
+ bottom_e = sketch.addLine("Boolean_1_1/Modified_Face_8&Boolean_1_1/Modified_Face_5")
sketch.setCoincident(bottom_e, bottom.startPoint())
sketch.setCoincident(bottom_e.startPoint(), bottom.endPoint())
def body_4():
# Create XOZ 2nd sketch
- sketch = model.addSketch(part, "Boolean_2_1/Modified_4")
+ sketch = model.addSketch(part, "Boolean_2_1/Modified_Face_4")
# Create base polygon
points = [(0, 0), (0, 1), (1, 0)]
left, diagonal, bottom = model.addPolygon(sketch, *geom_points)
# Binding
- bottom_e = sketch.addLine("Boolean_2_1/Modified_3&Boolean_2_1/Modified_4")
+ bottom_e = sketch.addLine("Boolean_2_1/Modified_Face_3&Boolean_2_1/Modified_Face_4")
sketch.setCoincident(bottom_e.endPoint(), bottom.startPoint())
sketch.setCoincident(bottom_e.startPoint(), left.startPoint())
- left_e = sketch.addLine("Boolean_2_1/Modified_6&Boolean_2_1/Modified_7")
+ left_e = sketch.addLine("Boolean_2_1/Modified_Face_6&Boolean_2_1/Modified_Face_7")
sketch.setCoincident(left_e.startPoint(), left.endPoint())
model.do() #!!!
"""Package for Build plugin for the Parametric Geometry API of the Modeler.
"""
-from BuildAPI import addVertex, addEdge, addWire, addFace, addShell
+from BuildAPI import addVertex, addEdge, addWire, addFace, addShell, addSolid, addCompSolid, addCompound
from BuildAPI import addSubShapes
+from BuildAPI import addFilling
aFeatureKind = theFeature.getKind()
if aFeatureKind in self.myFeatures:
# Dump only feature created by user (in history).
+ # Also dump Export features (hard-coded here in order not to change the data model).
# For all other features, just keep their name.
- if theForce or theFeature.isInHistory():
+ if theForce or theFeature.isInHistory() or aFeatureKind=="Export":
self.myFeatures[aFeatureKind](theFeature).dump(self)
else:
self.name(theFeature)
# In case of theFeature is not a constraint, it will not be dumped.
self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self)
+ ## Create wrapper for a folder and dump it
+ def dumpFolder(self, theFolder):
+ if theFolder.ID() in self.myFeatures:
+ self.myFeatures[theFolder.ID()](theFolder).dump(self)
+
## Dump all parameters
def dumpParameter(self, theFeature):
aFeatureKind = theFeature.getKind()
from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addFill
from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes
from FeaturesAPI import addRecover
+from FeaturesAPI import addFillet
from ModelHighAPI import updateFeatures
from ModelHighAPI import undo, redo
from ModelHighAPI import reset
+from ModelHighAPI import addFolder
from ModelHighAPI import ModelHighAPI_Selection as selection
from ModelHighAPI import checkPythonDump as checkPythonDump
assert(shape.isEdge())
assert(name != ""), "String empty"
-def testHaveNamingVertices(theFeature, theModel, thePartDoc) :
- """ Tests if all vertices of result have a unique name
+def testHaveNamingByType(theFeature, theModel, thePartDoc, theSubshapeType) :
+ """ Tests if all sub-shapes of result have a unique name
:param theFeature: feature to test.
+ :param theSubshapeType: type of sub-shape
"""
- # Get feature result/sub-result
- aResult = theFeature.results()[0].resultSubShapePair()[0]
- # Get result/sub-result shape
- shape = aResult.shape()
- # Create shape explorer with desired shape type
- shapeExplorer = GeomAPI_ShapeExplorer(shape, GeomAPI_Shape.VERTEX)
- # Create list, and store selections in it
+ aFirstRes = theFeature.results()[0]
+ # Get number of sub-results
+ hasSubs = True
+ nbSubs = aFirstRes.numberOfSubs()
+ if nbSubs == 0:
+ # no sub-results => treat current result as a sub
+ hasSubs = False
+ nbSubs = 1
+
selectionList = []
shapesList = [] # to append only unique shapes (not isSame)
- while shapeExplorer.more():
- aDuplicate = False
- for alreadyThere in shapesList:
- if alreadyThere.isSame(shapeExplorer.current()):
- aDuplicate = True
- if aDuplicate:
+ for sub in range(0, nbSubs):
+ # Get feature result/sub-result
+ if hasSubs:
+ aResult = aFirstRes.subResult(sub).resultSubShapePair()[0]
+ else:
+ aResult = aFirstRes.resultSubShapePair()[0]
+ # Get result/sub-result shape
+ shape = aResult.shape()
+ # Create shape explorer with desired shape type
+ shapeExplorer = GeomAPI_ShapeExplorer(shape, theSubshapeType)
+ # Create list, and store selections in it
+ while shapeExplorer.more():
+ aDuplicate = False
+ for alreadyThere in shapesList:
+ if alreadyThere.isSame(shapeExplorer.current()):
+ aDuplicate = True
+ if aDuplicate:
+ shapeExplorer.next()
+ continue
+ shapesList.append(shapeExplorer.current())
+ selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
+ selectionList.append(selection)
shapeExplorer.next()
- continue
- shapesList.append(shapeExplorer.current())
- selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
- selectionList.append(selection)
- shapeExplorer.next()
# Create group with this selection list
Group_1 = theModel.addGroup(thePartDoc, selectionList)
theModel.do()
attrSelection = groupSelectionList.value(index)
shape = attrSelection.value()
name = attrSelection.namingName()
- assert(shape.isVertex())
+ if theSubshapeType == GeomAPI_Shape.VERTEX:
+ assert(shape.isVertex())
+ elif theSubshapeType == GeomAPI_Shape.EDGE:
+ assert(shape.isEdge())
+ elif theSubshapeType == GeomAPI_Shape.FACE:
+ assert(shape.isFace())
assert(name != ""), "String empty"
presented_names.add(name)
assert(len(presented_names) == groupSelectionList.size()), "Some names are not unique"
+def testHaveNamingSubshapes(theFeature, theModel, thePartDoc) :
+ """ Tests if all vertices/edges/faces of result have a unique name
+ :param theFeature: feature to test.
+ """
+ testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.VERTEX)
+ testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.EDGE)
+ testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.FACE)
def testNbSubFeatures(theComposite, theKindOfSub, theExpectedCount):
""" Tests number of sub-features of the given type
""" Tests numbers of sub-shapes in results (used in Boolean operations tests)
"""
theModel.testNbResults(theFeature, NbRes)
- theModel.testNbSubResults(theFeature,NbSubRes)
- theModel.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid )
+ theModel.testNbSubResults(theFeature, NbSubRes)
+ theModel.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid)
theModel.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace)
theModel.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge)
theModel.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex)
#include <XGUI_OperationMgr.h>
#include <XGUI_Displayer.h>
#include <XGUI_MenuMgr.h>
+#include <XGUI_FacesPanel.h>
+#include <XGUI_SelectionActivate.h>
#include <ModuleBase_Operation.h>
#include <ModuleBase_Preferences.h>
mySelector = 0;
}
+ myWorkshop->hidePanel(myWorkshop->facesPanel());
//myWorkshop->contextMenuMgr()->disconnectViewer();
SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
{
if (!mySelector) {
mySelector = createSelector(theMgr);
- myWorkshop->module()->activateSelectionFilters();
+ myWorkshop->selectionActivate()->updateSelectionFilters();
+ myWorkshop->selectionActivate()->updateSelectionModes();
myWorkshop->synchronizeViewer();
}
}
TARGET_LINK_LIBRARIES(SamplePanelPlugin ${PROJECT_LIBRARIES})
INCLUDE_DIRECTORIES(
+ ${CAS_INCLUDE_DIRS}
../Config
../Events
../ModelAPI
return;
}
+ // Check all attributes are already dumped. If not, store the constraint as postponed.
+ bool areAttributesDumped = true;
+ for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
+ AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+ if (aRefAttr && aRefAttr->isInitialized())
+ areAttributesDumped = theDumper.isDumped(aRefAttr);
+ }
+ if (!areAttributesDumped) {
+ theDumper.postpone(aBase);
+ return;
+ }
+
bool isAngle = aBase->getKind() == SketchPlugin_ConstraintAngle::ID();
std::string aSetterSuffix;
if (isAngle)
}
}
- AttributeDoublePtr aValueAttr = aBase->real(
- isAngle ? SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID() :SketchPlugin_Constraint::VALUE());
+ AttributeDoublePtr aValueAttr;
+ if (isAngle)
+ aValueAttr = aBase->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+ else if (aBase->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
+ aBase->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
+ aValueAttr = aBase->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID());
+ else
+ aValueAttr = aBase->real(SketchPlugin_Constraint::VALUE());
if (aValueAttr && aValueAttr->isInitialized())
theDumper << ", " << aValueAttr;
FeaturePtr aBase = feature();
const std::string& aSketchName = theDumper.parentName(aBase);
+
AttributeRefAttrPtr aMirrorLine = mirrorLine();
AttributeRefListPtr aMirrorObjects = mirrorList();
+
+ // Check all attributes are already dumped. If not, store the constraint as postponed.
+ if (!theDumper.isDumped(aMirrorLine) || !theDumper.isDumped(aMirrorObjects)) {
+ theDumper.postpone(aBase);
+ return;
+ }
+
theDumper << aBase << " = " << aSketchName << ".addMirror(" << aMirrorLine << ", "
<< aMirrorObjects << ")" << std::endl;
AttributeIntegerPtr aNbCopies = numberOfObjects();
bool isFullValue = valueType()->value() != "SingleAngle";
+ // Check all attributes are already dumped. If not, store the constraint as postponed.
+ if (!theDumper.isDumped(aCenter) || !theDumper.isDumped(aRotObjects)) {
+ theDumper.postpone(aBase);
+ return;
+ }
+
theDumper << aBase << " = " << aSketchName << ".addRotation("
<< aRotObjects << ", " << aCenter << ", " << anAngle << ", " << aNbCopies;
if (isFullValue)
compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID());
fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
- fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
+ fillAttribute(theValue,
+ aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
aFeature->execute();
return InterfacePtr(new ModelHighAPI_Interface(aFeature));
}
compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID());
fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
- fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
+ fillAttribute(theValue,
+ aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
aFeature->execute();
return InterfacePtr(new ModelHighAPI_Interface(aFeature));
}
AttributeIntegerPtr aNbCopies = numberOfObjects();
bool isFullValue = valueType()->value() != "SingleValue";
+ // Check all attributes are already dumped. If not, store the constraint as postponed.
+ if (!theDumper.isDumped(aStart) || !theDumper.isDumped(aEnd) ||
+ !theDumper.isDumped(aTransObjects)) {
+ theDumper.postpone(aBase);
+ return;
+ }
+
theDumper << aBase << " = " << aSketchName << ".addTranslation("
<< aTransObjects << ", " << aStart << ", " << aEnd << ", " << aNbCopies;
if (isFullValue)
TestConstraintTangent.py
TestConstraintAngle.py
TestConstraintMiddlePoint.py
+ TestEdgesOrder.py
TestMirror.py
TestMultiRotation.py
TestMultiTranslation.py
TestTrimLine02.py
Test2229.py
Test2239.py
+ TestDistanceDump.py
TestDistanceSignedVsUnsigned01.py
TestDistanceSignedVsUnsigned02.py
TestDistanceSignedVsUnsigned03.py
Test2273.py
Test2280.py
Test2287.py
+ Test2341.py
)
if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
return;
FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object());
- if (!lastResult().get() && aProjection->lastResult().get()) {
+ if (!lastResult().get()) {
+ bool hasProjResult = aProjection->lastResult().get() != NULL;
ResultConstructionPtr aConstr = document()->createConstruction(data());
- aConstr->setShape(aProjection->lastResult()->shape());
+ if (hasProjResult)
+ aConstr->setShape(aProjection->lastResult()->shape());
aConstr->setIsInHistory(false);
aConstr->setDisplayed(false);
setResult(aConstr);
- aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
+ if (hasProjResult)
+ aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
}
// is sketch plane is changed (issue 1791), attribute of projection is not changed, but
std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
double aRadius = aCircle->radius();
+ double aNormalsDot = aCircle->normal()->dot(aSketchPlane->direction());
+ if (fabs(fabs(aNormalsDot) - 1.0) > tolerance)
+ return; // circle is not in the plane, parallel to the sketch plane
+
std::shared_ptr<GeomAPI_Pnt> aCenter = aSketchPlane->project(aCircle->center());
std::shared_ptr<GeomAPI_Pnt2d> aCenterInSketch = sketch()->to2D(aCenter);
std::shared_ptr<GeomAPI_Pnt> aCenter = aSketchPlane->project(aCircle->center());
std::shared_ptr<GeomAPI_Pnt2d> aCenterInSketch = sketch()->to2D(aCenter);
- bool isInversed = aCircle->normal()->dot(aSketchPlane->direction()) < 0.;
+ double aNormalsDot = aCircle->normal()->dot(aSketchPlane->direction());
+ if (fabs(fabs(aNormalsDot) - 1.0) > tolerance)
+ return; // arc is not in the plane, parallel to the sketch plane
+
+ bool isInversed = aNormalsDot < 0.;
if (!hasPrevProj)
aProjection = sketch()->addFeature(SketchPlugin_Arc::ID());
// coincidence to feature
updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences,
- aFeatureResults, aSplitFeature);
+ aFeatureResults, aSplitFeature, aFeaturesToDelete);
updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature,
const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
const std::set<ResultPtr>& theFeatureResults,
- const FeaturePtr& theSplitFeature)
+ const FeaturePtr& theSplitFeature,
+ std::set<FeaturePtr>& theFeaturesToDelete)
{
if (theCoincidenceToFeature.empty())
return;
for (; aCIt != aCLast; aCIt++) {
FeaturePtr aCoincFeature = aCIt->first;
std::string anAttributeId = aCIt->second.first;
+ std::string aSecondAttribute = anAttributeId == SketchPlugin_Constraint::ENTITY_A() ?
+ SketchPlugin_Constraint::ENTITY_B() : SketchPlugin_Constraint::ENTITY_A();
+
AttributePoint2DPtr aCoincPoint = aCIt->second.second;
std::set<AttributePoint2DPtr>::const_iterator aFCIt = theFurtherCoincidences.begin(),
aFCLast = theFurtherCoincidences.end();
aFeaturePointAttribute = aFCAttribute;
}
if (aFeaturePointAttribute.get()) {
- aCoincFeature->refattr(anAttributeId)->setObject(ResultPtr());
- aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute);
+ // create new constraint and remove the current
+ aCoincFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+ aFeaturePointAttribute, aCoincFeature->refattr(aSecondAttribute)->attr());
+ theFeaturesToDelete.insert(aCIt->first);
// create new coincidences to split feature points
std::set<AttributePoint2DPtr>::const_iterator aSFIt = aNewCoincidencesToSplitFeature.begin(),
aSFLast = aNewCoincidencesToSplitFeature.end();
for (; aSFIt != aSFLast; aSFIt++) {
AttributePoint2DPtr aSFAttribute = *aSFIt;
if (aCoincPnt->isEqual(aSFAttribute->pnt())) {
- std::string aSecondAttribute = SketchPlugin_Constraint::ENTITY_A();
- if (anAttributeId == SketchPlugin_Constraint::ENTITY_A())
- aSecondAttribute = SketchPlugin_Constraint::ENTITY_B();
createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
aSFAttribute, aCoincFeature->refattr(aSecondAttribute)->attr());
}
/// \param theFurtherCoincidences a list of points where coincidences will be build
/// \param theFeatureResults created results after split where constaint might be connected
/// \param theSplitFeature feature created by split, new coincidences to points should be created
+ /// \param theFeaturesToDelete the list of removed features (will be updated here by
+ /// the coincidences to be removed)
/// if theCoincidenceToFeature contains equal points
void updateCoincidenceConstraintsToFeature(
const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature,
const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
const std::set<ResultPtr>& theFeatureResults,
- const FeaturePtr& theSplitFeature);
+ const FeaturePtr& theSplitFeature,
+ std::set<FeaturePtr>& theFeaturesToDelete);
/// Move constraints from base feature to given feature
/// \param theFeature a base feature
anIt != aLast; anIt++) {
AttributePtr anAttribute = *anIt;
- if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
+ if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences, aFeaturesToDelete))
continue;
// move tangency constraint to the nearest feature if possible
}
bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
- const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
+ const std::set<AttributePoint2DPtr>& theFurtherCoincidences,
+ std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete)
{
FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
AttributePoint2DPtr aPointAttribute = (*anIt);
std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
if (aPoint2d->isEqual(aRefPnt2d)) {
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- theAttribute);
- if (aRefAttr.get()) {
- aRefAttr->setAttr(aPointAttribute);
- aFoundPoint = true;
- }
+ // create new coincidence and then remove the old one
+ createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aRefPointAttr, aPointAttribute);
+ theFeaturesToDelete.insert(aFeature);
}
}
return aFoundPoint;
private:
bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
- const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+ const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
+ std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
/// Move tangency constraint to the feature if it is geometrically closely to it
/// \param theAttribute an attribute of a tangent constraint feature
/// \param theFeature a feature that can be set into the attribute
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ Test2341.py
+ Test case for issue #2341 "SIGSEGV when trying to move a point of a projected axis"
+"""
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-5.830951894848558, -7.5, -11, -7.5)
+SketchLine_2 = Sketch_1.addLine(-11, -7.5, -11, -10)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-11, -10, 11, -10)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(11, -10, 11, -7.5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(11, -7.5, 5.8309518948453, -7.5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 2.5)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_4.result(), 2.5)
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_3.result(), 22)
+SketchConstraintLength_3.setName("SketchConstraintLength_5")
+SketchLine_6 = Sketch_1.addLine(-6, 12, 6, 12)
+SketchLine_7 = Sketch_1.addLine(6, 12, 6, 8.121320343559642)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(-6, 12, -6, 7.365459931328117)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.startPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_6.result(), 12)
+SketchConstraintLength_4.setName("SketchConstraintLength_6")
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchProjection_3 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_3 = SketchProjection_3.createdFeature()
+SketchProjection_4 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_4 = SketchProjection_4.createdFeature()
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_4).coordinates(), SketchLine_4.startPoint(), 10)
+SketchProjection_5 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_5 = SketchProjection_5.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, -5.830951894848558, -7.5, -6, 7.365459931328117, True)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchPoint_5.result(), SketchArc_1.center())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 9.5)
+SketchProjection_6 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_6 = SketchProjection_6.createdFeature()
+SketchArc_2 = Sketch_1.addArc(0, 0, 5.8309518948453, -7.5, 7.693909752490621, 5.572589408930978, False)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchPoint_6.result(), SketchArc_2.center())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchArc_2.startPoint())
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_2.results()[1], 9.5)
+SketchArc_3 = Sketch_1.addArc(0, 0, 1.561361948645558, 3.6826822922052, 3.682682292205201, 1.561361948645557, False)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchArc_3.center())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_3.results()[1], 4)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_6.endPoint(), SketchArc_1.center(), 6)
+SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchArc_1.center(), 11)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchArc_1.endPoint())
+SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchLine_8.startPoint(), SketchLine_2.endPoint(), 22)
+SketchLine_9 = Sketch_1.addLine(0, 0, 14.14213562373095, 14.14213562373095)
+SketchLine_9.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_9.startPoint())
+SketchProjection_7 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_10 = SketchProjection_7.createdFeature()
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_10.result(), SketchLine_9.result(), 45)
+SketchLine_11 = Sketch_1.addLine(7.693909752490621, 5.572589408930978, 3.682682292205201, 1.561361948645557)
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_11.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_9.result(), SketchLine_11.result())
+SketchLine_12 = Sketch_1.addLine(6, 8.121320343559642, 1.561361948645558, 3.6826822922052)
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchArc_3.startPoint(), SketchLine_12.endPoint())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_9.result(), SketchLine_12.result())
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchLine_7.endPoint())
+SketchLine_13 = Sketch_1.addLine(3.682682292205201, 1.561361948645557, 1.561361948645558, 3.6826822922052)
+SketchLine_13.setAuxiliary(True)
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchArc_3.startPoint(), SketchLine_13.endPoint())
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_13.result(), 3)
+SketchConstraintLength_5.setName("SketchConstraintLength_7")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_3.endPoint(), SketchLine_9.result(), 1.5, True)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_9.result(), 20)
+SketchConstraintLength_6.setName("SketchConstraintLength_8")
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6r-SketchLine_7r-SketchLine_8f-SketchArc_1_2f-SketchArc_2_2f-SketchArc_3_2r-SketchLine_11f-SketchLine_12r")], model.selection(), 3.5, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchLine_14 = Sketch_2.addLine(6, 0, -6, 0)
+SketchProjection_8 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_7s-SketchLine_6e"), False)
+SketchPoint_7 = SketchProjection_8.createdFeature()
+SketchConstraintCoincidence_20 = Sketch_2.setCoincident(SketchLine_14.startPoint(), SketchPoint_7.result())
+SketchProjection_9 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_6s-SketchLine_8s"), False)
+SketchPoint_8 = SketchProjection_9.createdFeature()
+SketchConstraintCoincidence_21 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchPoint_8.result())
+SketchLine_15 = Sketch_2.addLine(-6, 0, -6, -3.5)
+SketchConstraintCoincidence_22 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchLine_16 = Sketch_2.addLine(-6, -3.5, -6, -10.5)
+SketchConstraintCoincidence_23 = Sketch_2.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchLine_17 = Sketch_2.addLine(5.978225648847096, 0.08643259872215214, 6, -3.5)
+SketchProjection_10 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_9 = SketchProjection_10.createdFeature()
+SketchConstraintCoincidence_24 = Sketch_2.setCoincident(SketchLine_17.endPoint(), SketchPoint_9.result())
+SketchLine_18 = Sketch_2.addLine(6, -3.5, 6, -10.5)
+SketchConstraintCoincidence_25 = Sketch_2.setCoincident(SketchLine_17.endPoint(), SketchLine_18.startPoint())
+SketchConstraintLength_7 = Sketch_2.setLength(SketchLine_18.result(), 7)
+SketchConstraintLength_7.setName("SketchConstraintLength_9")
+SketchProjection_11 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_10 = SketchProjection_11.createdFeature()
+SketchConstraintCoincidence_26 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_10).coordinates(), SketchLine_15.endPoint())
+SketchConstraintVertical_5 = Sketch_2.setVertical(SketchLine_18.result())
+SketchConstraintVertical_6 = Sketch_2.setVertical(SketchLine_16.result())
+SketchLine_19 = Sketch_2.addLine(6, -10.5, -6, -10.5)
+SketchLine_19.setAuxiliary(True)
+SketchConstraintCoincidence_27 = Sketch_2.setCoincident(SketchLine_19.startPoint(), SketchLine_18.endPoint())
+SketchConstraintCoincidence_28 = Sketch_2.setCoincident(SketchLine_19.endPoint(), SketchLine_16.endPoint())
+SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchProjection_12 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_20 = SketchProjection_12.createdFeature()
+model.do()
+
+SketchLine_20 = SketchAPI_Line(SketchLine_20)
+lineStart = [SketchLine_20.startPoint().x(), SketchLine_20.startPoint().y()]
+lineEnd = [SketchLine_20.endPoint().x(), SketchLine_20.endPoint().y()]
+
+# Try to move a line provided by projection of OZ axis
+
+# move start point
+Sketch_2.move(SketchLine_20.startPoint(), lineStart[0] + 1., lineStart[1] + 1.)
+model.do()
+assert(SketchLine_20.startPoint().x() == lineStart[0] and SketchLine_20.startPoint().y() == lineStart[1])
+
+# move end point
+Sketch_2.move(SketchLine_20.endPoint(), lineEnd[0] + 1., lineEnd[1] + 1.)
+model.do()
+assert(SketchLine_20.endPoint().x() == lineEnd[0] and SketchLine_20.endPoint().y() == lineEnd[1])
+
+# move whole line
+Sketch_2.move(SketchLine_20.result(), 50., 50.)
+model.do()
+assert(SketchLine_20.startPoint().x() == lineStart[0] and SketchLine_20.startPoint().y() == lineStart[1])
+assert(SketchLine_20.endPoint().x() == lineEnd[0] and SketchLine_20.endPoint().y() == lineEnd[1])
+
+model.end()
# Test 1.
# =============================================================================
# horizontal distance constraint
-SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(firstPoint, secondPoint, "distance")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(firstPoint, secondPoint, 10)
+SketchConstraintDistanceHorizontal_1.feature().real("ConstraintValue").setText(DistanceParam.name().value())
model.do()
# changing the parameter
# Test 2.
# =============================================================================
# Vertical distance constraint
-SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(firstPoint, secondPoint, "distance")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(firstPoint, secondPoint, 10)
+SketchConstraintDistanceVertical_1.feature().real("ConstraintValue").setText(DistanceParam.name().value())
model.do()
# changing the parameter
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ TestDistanceDump.py
+
+ Check that distances set by parameters are dumped correctly
+"""
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Parameter_1 = model.addParameter(Part_1_doc, "a", "10")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(22.18754371333437, 31.96766851898132, 36.16301361286303, 24.640865178987)
+SketchLine_2 = Sketch_1.addLine(36.16301361286303, 24.640865178987, 45.95667186595785, 26.6618199092043)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(45.95667186595785, 26.6618199092043, 55.95667186595785, 16.6618199092043)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_1.startPoint(), SketchLine_2.result(), Parameter_1.name().value(), True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), Parameter_1.name().value())
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_2.endPoint(), SketchLine_3.endPoint(), Parameter_1.name().value())
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_2.endPoint(), SketchLine_3.endPoint(), Parameter_1.name().value())
+model.do()
+model.end()
+
+def assertEqual(str1, str2):
+ assert(str1 == str2), "{} != {}".format(str1, str2)
+
+assertEqual(SketchConstraintDistance_1.feature().real("ConstraintValue").text(), Parameter_1.name().value())
+assertEqual(SketchConstraintLength_1.feature().real("ConstraintValue").text(), Parameter_1.name().value())
+assertEqual(SketchConstraintDistanceHorizontal_1.feature().real("DistanceValue").text(), Parameter_1.name().value())
+assertEqual(SketchConstraintDistanceVertical_1.feature().real("DistanceValue").text(), Parameter_1.name().value())
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ Verify the order of sketch edges is the same after dump
+"""
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(40, 5, 40, -25)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchLine_2 = Sketch_1.addLine(40, -25, -10, -25)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 50)
+SketchLine_3 = Sketch_1.addLine(-10, -25, -10, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-10, 5, 40, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+
+# Change Length references
+SketchConstraintLength_1.feature().refattr("ConstraintEntityA").setObject(SketchLine_3.feature().lastResult())
+SketchConstraintLength_2.feature().refattr("ConstraintEntityA").setObject(SketchLine_4.feature().lastResult())
+model.do()
+# Remove the first line, then build it and constraints from scratch
+Part_1_doc.removeFeature(SketchConstraintCoincidence_1.feature())
+Part_1_doc.removeFeature(SketchConstraintCoincidence_4.feature())
+Part_1_doc.removeFeature(SketchLine_1.feature())
+SketchLine_1 = Sketch_1.addLine(40, 5, 40, -25)
+Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+Sketch_1.setLength(SketchLine_1.result(), 20)
+Sketch_1.setLength(SketchLine_2.result(), 40)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 10, 0)
+
+# Extrude all lateral faces to check their area
+Extrusion_2 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
+SketchLine_5 = Sketch_2.addLine(0.7346748749771982, 2.736245541082907e-015, 0.7346748749771982, 10.00000000000001)
+SketchProjection_1 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchPoint_1.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchPoint_2.result())
+SketchLine_6 = Sketch_2.addLine(0.7346748749771982, 10.00000000000001, -19.2653251250228, 10.00000000000001)
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_3 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchPoint_3.result())
+SketchLine_7 = Sketch_2.addLine(-19.2653251250228, 10.00000000000001, -19.2653251250228, 2.775557561562891e-015)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_4 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchPoint_4.result())
+SketchLine_8 = Sketch_2.addLine(-19.2653251250228, 2.775557561562891e-015, 0.7346748749771974, 3.386180225106727e-015)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchLine_8.endPoint())
+Extrusion_2.setNestedSketch(Sketch_2)
+
+Extrusion_3 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"))
+SketchLine_9 = Sketch_3.addLine(36.86324678550901, 2.286454635368208e-015, 36.86324678550901, 10)
+SketchProjection_5 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_5 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchPoint_5.result())
+SketchProjection_6 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_6 = SketchProjection_6.createdFeature()
+SketchConstraintCoincidence_14 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchPoint_6.result())
+SketchLine_10 = Sketch_3.addLine(36.86324678550901, 10, -3.136753214490995, 10)
+SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchProjection_7 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_7 = SketchProjection_7.createdFeature()
+SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchPoint_7.result())
+SketchLine_11 = Sketch_3.addLine(-3.136753214490995, 10, -3.136753214490995, 2.275957200481571e-015)
+SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchProjection_8 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_8 = SketchProjection_8.createdFeature()
+SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchPoint_8.result())
+SketchLine_12 = Sketch_3.addLine(-3.136753214490995, 2.275957200481571e-015, 36.86324678550902, 1.387778780781446e-015)
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchLine_12.endPoint())
+Extrusion_3.setNestedSketch(Sketch_3)
+
+Extrusion_4 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
+SketchLine_13 = Sketch_4.addLine(22.60959895285982, 4.420942808558057e-016, 22.60959895285982, 10)
+SketchProjection_9 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_9 = SketchProjection_9.createdFeature()
+SketchConstraintCoincidence_21 = Sketch_4.setCoincident(SketchLine_13.startPoint(), SketchPoint_9.result())
+SketchProjection_10 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_10 = SketchProjection_10.createdFeature()
+SketchConstraintCoincidence_22 = Sketch_4.setCoincident(SketchLine_13.endPoint(), SketchPoint_10.result())
+SketchLine_14 = Sketch_4.addLine(22.60959895285982, 10, -7.390401047140179, 10)
+SketchConstraintCoincidence_23 = Sketch_4.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchProjection_11 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_11 = SketchProjection_11.createdFeature()
+SketchConstraintCoincidence_24 = Sketch_4.setCoincident(SketchLine_14.endPoint(), SketchPoint_11.result())
+SketchLine_15 = Sketch_4.addLine(-7.390401047140179, 10, -7.390401047140179, 8.881784197001252e-016)
+SketchConstraintCoincidence_25 = Sketch_4.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchProjection_12 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_12 = SketchProjection_12.createdFeature()
+SketchConstraintCoincidence_26 = Sketch_4.setCoincident(SketchLine_15.endPoint(), SketchPoint_12.result())
+SketchLine_16 = Sketch_4.addLine(-7.390401047140179, 8.881784197001252e-016, 22.60959895285983, 0)
+SketchConstraintCoincidence_27 = Sketch_4.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchConstraintCoincidence_28 = Sketch_4.setCoincident(SketchLine_13.startPoint(), SketchLine_16.endPoint())
+Extrusion_4.setNestedSketch(Sketch_4)
+
+Extrusion_5 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+SketchLine_17 = Sketch_5.addLine(-10.64977324988603, -1.185841873934692e-016, -10.64977324988603, -10)
+SketchProjection_13 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_13 = SketchProjection_13.createdFeature()
+SketchConstraintCoincidence_29 = Sketch_5.setCoincident(SketchLine_17.startPoint(), SketchPoint_13.result())
+SketchProjection_14 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_14 = SketchProjection_14.createdFeature()
+SketchConstraintCoincidence_30 = Sketch_5.setCoincident(SketchLine_17.endPoint(), SketchPoint_14.result())
+SketchLine_18 = Sketch_5.addLine(-10.64977324988603, -10, 39.35022675011398, -10)
+SketchConstraintCoincidence_31 = Sketch_5.setCoincident(SketchLine_17.endPoint(), SketchLine_18.startPoint())
+SketchProjection_15 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), False)
+SketchPoint_15 = SketchProjection_15.createdFeature()
+SketchConstraintCoincidence_32 = Sketch_5.setCoincident(SketchLine_18.endPoint(), SketchPoint_15.result())
+SketchLine_19 = Sketch_5.addLine(39.35022675011398, -10, 39.35022675011398, 4.440892098500626e-016)
+SketchConstraintCoincidence_33 = Sketch_5.setCoincident(SketchLine_18.endPoint(), SketchLine_19.startPoint())
+SketchProjection_16 = Sketch_5.addProjection(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_1"), False)
+SketchPoint_16 = SketchProjection_16.createdFeature()
+SketchConstraintCoincidence_34 = Sketch_5.setCoincident(SketchLine_19.endPoint(), SketchPoint_16.result())
+SketchLine_20 = Sketch_5.addLine(39.35022675011398, 4.440892098500626e-016, -10.64977324988603, 0)
+SketchConstraintCoincidence_35 = Sketch_5.setCoincident(SketchLine_19.endPoint(), SketchLine_20.startPoint())
+SketchConstraintCoincidence_36 = Sketch_5.setCoincident(SketchLine_17.startPoint(), SketchLine_20.endPoint())
+Extrusion_5.setNestedSketch(Sketch_5)
+model.do()
+model.end()
+
+# check volumes
+model.testResultsVolumes(Extrusion_2, [4000])
+model.testResultsVolumes(Extrusion_3, [3000])
+model.testResultsVolumes(Extrusion_4, [5000])
+model.testResultsVolumes(Extrusion_5, [2000])
+
+assert(model.checkPythonDump())
+
+# check volumes after dump and restore
+model.testResultsVolumes(Extrusion_2, [4000])
+model.testResultsVolumes(Extrusion_3, [3000])
+model.testResultsVolumes(Extrusion_4, [5000])
+model.testResultsVolumes(Extrusion_5, [2000])
# =============================================================================
# Test 3. Constrain center of circle and move it again
# =============================================================================
-SketchConstraintDistanceHorizontal_3 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchArc_1.startPoint(), -30)
+SketchConstraintDistanceHorizontal_3 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchArc_1.startPoint(), 30)
model.do()
# move center
delta = [1., 1.]
<!-- SketchConstraintMirror -->
<feature
id="SketchConstraintMirror"
- title="Mirror" icon="icons/Sketch/mirror.png"
+ title="Mirror copy" icon="icons/Sketch/mirror.png"
tooltip="Create constraint, mirroring group of objects">
<sketch_shape_selector id="ConstraintEntityA"
label="Mirror line" tooltip="Select mirror line" shape_types="edge">
<!-- SketchMultiTranslation -->
<feature
id="SketchMultiTranslation"
- title="Translation" icon="icons/Sketch/translate.png"
- tooltip="Multiple translation">
+ title="Linear copy" icon="icons/Sketch/translate.png"
+ tooltip="Copy objects and move">
<sketch_multi_selector id="MultiTranslationList"
label="Segments:"
tooltip="Select list of objects to be translated"
<!-- SketchMultiRotation -->
<feature
id="SketchMultiRotation"
- title="Rotation" icon="icons/Sketch/rotate.png"
- tooltip="Multiple rotation">
+ title="Angular copy" icon="icons/Sketch/rotate.png"
+ tooltip="Copy objects and rotate">
<sketch_multi_selector id="MultiRotationList"
label="Segments:"
tooltip="Select list of objects to be rotated"
for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
aRefIt != aRefs.end(); ++aRefIt) {
FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
- if (anOwner->getKind() == theFeatureKind)
+ if (anOwner && anOwner->getKind() == theFeatureKind)
return true;
}
return false;
void SketchSolver_ConstraintMovement::moveTo(
const std::shared_ptr<GeomAPI_Pnt2d>& theDestinationPoint)
{
+ if (!myMovedFeature)
+ return; // nothing to move
+
double aDelta[2] = { theDestinationPoint->x() - myStartPoint->x(),
theDestinationPoint->y() - myStartPoint->y() };
#endif
/// Step between icons
-static const double MyDist = 0.02;
+static const double MyDist = 0.015;
//**************************************************************
SET(PROJECT_HEADERS
XGUI.h
XGUI_ActionsMgr.h
+ XGUI_ActiveControlMgr.h
+ XGUI_ActiveControlSelector.h
XGUI_ColorDialog.h
XGUI_ContextMenuMgr.h
XGUI_CustomPrs.h
XGUI_Displayer.h
XGUI_ErrorDialog.h
XGUI_ErrorMgr.h
+ XGUI_FacesPanel.h
+ XGUI_FacesPanelSelector.h
XGUI_HistoryMenu.h
XGUI_MenuGroup.h
XGUI_MenuMgr.h
XGUI_OperationMgr.h
XGUI_PropertyDialog.h
XGUI_PropertyPanel.h
+ XGUI_PropertyPanelSelector.h
XGUI_QtEvents.h
XGUI_SalomeConnector.h
XGUI_Selection.h
+ XGUI_SelectionActivate.h
+ XGUI_SelectionFilterType.h
XGUI_SelectionMgr.h
XGUI_Tools.h
XGUI_TransparencyWidget.h
SET(PROJECT_MOC_HEADERS
XGUI_ActionsMgr.h
+ XGUI_ActiveControlMgr.h
+ XGUI_ActiveControlSelector.h
XGUI_ColorDialog.h
XGUI_ContextMenuMgr.h
XGUI_DataModel.h
XGUI_Displayer.h
XGUI_ErrorDialog.h
XGUI_ErrorMgr.h
+ XGUI_FacesPanel.h
+ XGUI_FacesPanelSelector.h
XGUI_HistoryMenu.h
XGUI_ModuleConnector.h
XGUI_ObjectsBrowser.h
XGUI_OperationMgr.h
XGUI_PropertyDialog.h
XGUI_PropertyPanel.h
+ XGUI_PropertyPanelSelector.h
XGUI_SelectionMgr.h
XGUI_TransparencyWidget.h
XGUI_ViewerProxy.h
SET(PROJECT_SOURCES
XGUI_ActionsMgr.cpp
+ XGUI_ActiveControlMgr.cpp
XGUI_ColorDialog.cpp
XGUI_ContextMenuMgr.cpp
XGUI_CustomPrs.cpp
XGUI_Displayer.cpp
XGUI_ErrorDialog.cpp
XGUI_ErrorMgr.cpp
+ XGUI_FacesPanel.cpp
+ XGUI_FacesPanelSelector.cpp
XGUI_HistoryMenu.cpp
XGUI_MenuGroup.cpp
XGUI_MenuMgr.cpp
XGUI_OperationMgr.cpp
XGUI_PropertyDialog.cpp
XGUI_PropertyPanel.cpp
+ XGUI_PropertyPanelSelector.cpp
XGUI_QtEvents.cpp
XGUI_SalomeConnector.cpp
XGUI_Selection.cpp
+ XGUI_SelectionActivate.cpp
XGUI_SelectionMgr.cpp
XGUI_Tools.cpp
XGUI_TransparencyWidget.cpp
// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
//
-/*
- * XGUI_ActionsMgr.h
- */
-
-#ifndef XGUI_ACTIONSMGR_H_
-#define XGUI_ACTIONSMGR_H_
+#ifndef XGUI_ActionsMgr_H
+#define XGUI_ActionsMgr_H
#include "XGUI.h"
class ModuleBase_Operation;
class QAction;
-/**
-* \ingroup GUI
-* A class for management of actions (features) activation/deactivation
-*/
+/// class XGUI_ActionsMgr
+/// \ingroup GUI
+/// A class for management of actions (features) activation/deactivation
class XGUI_EXPORT XGUI_ActionsMgr : public QObject, public Events_Listener
{
Q_OBJECT
Preview = 6
};
- //! Add a command in the manager.
- //! Please note that nested commands in the Salome mode (No AppElements_Command, pure QActions)
- //! won't be extracted and should be added manually using the addNestedCommands method.
+ /// Add a command in the manager.
+ /// Please note that nested commands in the Salome mode (No AppElements_Command, pure QActions)
+ /// won't be extracted and should be added manually using the addNestedCommands method.
void addCommand(QAction* theCmd);
- //! Sets relation between the command (with given Id) and it's nested actions.
+ /// Sets relation between the command (with given Id) and it's nested actions.
void addNestedCommands(const QString& theId, const QStringList& theCommands);
- //! Returns list of nested commands by parent command Id
- //! \param theId a parent command Id
+ /// Returns list of nested commands by parent command Id
+ /// \param theId a parent command Id
QStringList nestedCommands(const QString& theId) const;
/// Returns True if the given Id is an Id of nested command
/// \param theKeySequence - string that contain a key sequence to register
QKeySequence registerShortcut(const QString& theKeySequence);
- //! Redefinition of Events_Listener method
+ /// Redefinition of Events_Listener method
virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
- //! Return property panel's action like ok, cancel, help.
- //! If there is no such action, it will be created.
+ /// Return property panel's action like ok, cancel, help.
+ /// If there is no such action, it will be created.
QAction* operationStateAction(OperationStateActionId theId);
/// Return an action by the given id, if it was registered in the manager
ActionInfo actionInfoById(const QString& theId);
private:
- //! Update workbench actions according to OperationMgr state:
- //! No active operations: all actions but nested are available
- //! There is active operation: current operation + it's nested
- //! are enabled, all the rest is disabled. All active commands is checked.
+ /// Update workbench actions according to OperationMgr state:
+ /// No active operations: all actions but nested are available
+ /// There is active operation: current operation + it's nested
+ /// are enabled, all the rest is disabled. All active commands is checked.
void updateCommandsStatus();
- //! Sets all commands checked if it's operation is active.
+ /// Sets all commands checked if it's operation is active.
void updateCheckState();
- //! Updates actions according to current selection in the viewer
+ /// Updates actions according to current selection in the viewer
void updateOnViewSelection();
- //! Sets all actions to enabled state.
+ /// Sets all actions to enabled state.
void setAllEnabled();
- //! Sets all nested actions to isEnabled state for the command with given ID.
- //! If ID is empty - all nested actions will be affected.
+ /// Sets all nested actions to isEnabled state for the command with given ID.
+ /// If ID is empty - all nested actions will be affected.
void setNestedCommandsEnabled(bool isEnabled, const QString& theParent = QString());
- //! Sets to enabled state all siblings of the given operation and it's parents recursively
+ /// Sets to enabled state all siblings of the given operation and it's parents recursively
void setNestedStackEnabled(ModuleBase_Operation* theOperation);
- //! Sets the action with theId to theChecked state.
+ /// Sets the action with theId to theChecked state.
void setActionChecked(const QString& theId, const bool theChecked);
- //! Sets the action with theId to theEnabled state.
+ /// Sets the action with theId to theEnabled state.
void setActionEnabled(const QString& theId, const bool theEnabled);
- //! Updates actions according to their "document" tag
+ /// Updates actions according to their "document" tag
void updateByDocumentKind();
- //! Asks plugins about their features state, using the Events system
+ /// Asks plugins about their features state, using the Events system
void updateByPlugins(FeaturePtr theActiveFeature);
+ /// Returns names of nested action for the feature of given operation
+ /// \param theOperation an operation
QStringList allNestedCommands(ModuleBase_Operation* theOperation);
private:
friend class XGUI_Workshop;
};
-#endif /* XGUI_ACTIONSMGR_H_ */
+#endif /* XGUI_ActionsMgr_H */
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "XGUI_ActiveControlMgr.h"
+#include "XGUI_ActiveControlSelector.h"
+#include "XGUI_SelectionActivate.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_Workshop.h"
+
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IWorkshop.h>
+
+//#define DEBUG_ACTIVE_SELECTOR
+
+#ifdef DEBUG_ACTIVE_SELECTOR
+void debugInfo(const QString& theMessage, XGUI_ActiveControlSelector* theSelector)
+{
+ std::cout << theMessage.toStdString().c_str() << ", active: "
+ << (theSelector ? theSelector->getType().toStdString().c_str() : "NULL") << std::endl;
+}
+#endif
+
+//********************************************************************
+XGUI_ActiveControlMgr::XGUI_ActiveControlMgr(ModuleBase_IWorkshop* theWorkshop)
+: myWorkshop(theWorkshop), myActiveSelector(0), myIsBlocked(false)
+{
+ connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::addSelector(XGUI_ActiveControlSelector* theSelector)
+{
+ mySelectors.append(theSelector);
+ connect(theSelector, SIGNAL(activated()), this, SLOT(onSelectorActivated()));
+ connect(theSelector, SIGNAL(deactivated()), this, SLOT(onSelectorDeactivated()));
+}
+
+//********************************************************************
+XGUI_ActiveControlSelector* XGUI_ActiveControlMgr::getSelector(const QString& theType)
+{
+ XGUI_ActiveControlSelector* aSelector;
+ for (int i = 0, aCount = mySelectors.count(); i < aCount; i++)
+ {
+ if (mySelectors[i]->getType() != theType)
+ continue;
+ aSelector = mySelectors[i];
+ break;
+ }
+ return aSelector;
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::onSelectorActivated()
+{
+ XGUI_ActiveControlSelector* aSelector = qobject_cast<XGUI_ActiveControlSelector*>(sender());
+ if (!aSelector || aSelector == myActiveSelector)
+ return;
+
+ if (myIsBlocked) // we've come here from the same method
+ return;
+ myIsBlocked = true;
+ if (myActiveSelector) {
+ myActiveSelector->setActive(false);
+ }
+ activateSelector(aSelector);
+ XGUI_Tools::workshop(myWorkshop)->selectionActivate()->updateSelectionModes();
+ XGUI_Tools::workshop(myWorkshop)->selectionActivate()->updateSelectionFilters();
+
+#ifdef DEBUG_ACTIVE_SELECTOR
+ debugInfo("onSelectorActivated", myActiveSelector);
+#endif
+ myIsBlocked = false;
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::onSelectorDeactivated()
+{
+ XGUI_ActiveControlSelector* aSelector = qobject_cast<XGUI_ActiveControlSelector*>(sender());
+ if (!aSelector || aSelector != myActiveSelector || !myActiveSelector)
+ return;
+
+ if (myIsBlocked) // we've come here from the same method
+ return;
+ myIsBlocked = true;
+
+ myActiveSelector->setActive(false);
+ activateSelector(NULL);
+
+ XGUI_ActiveControlSelector* aSelectorToBeActivated = 0;
+ for (int i = 0, aCount = mySelectors.count(); i < aCount; i++)
+ {
+ if (!mySelectors[i]->needToBeActiated())
+ continue;
+ aSelectorToBeActivated = mySelectors[i];
+ break;
+ }
+ if (aSelectorToBeActivated)
+ activateSelector(aSelectorToBeActivated);
+
+ XGUI_Tools::workshop(myWorkshop)->selectionActivate()->updateSelectionModes();
+ XGUI_Tools::workshop(myWorkshop)->selectionActivate()->updateSelectionFilters();
+#ifdef DEBUG_ACTIVE_SELECTOR
+ debugInfo("onSelectorDeactivated", myActiveSelector);
+#endif
+ myIsBlocked = false;
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::onSelectionChanged()
+{
+ if (!myActiveSelector)
+ return;
+
+ myActiveSelector->processSelection();
+#ifdef DEBUG_ACTIVE_SELECTOR
+ debugInfo("onSelectionChanged", myActiveSelector);
+#endif
+}
+
+//********************************************************************
+void XGUI_ActiveControlMgr::activateSelector(XGUI_ActiveControlSelector* theSelector)
+{
+ myActiveSelector = theSelector;
+ if (myActiveSelector)
+ myActiveSelector->setActive(true);
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_ActiveControlMgr_H
+#define XGUI_ActiveControlMgr_H
+
+#include "XGUI.h"
+
+#include <QList>
+#include <QObject>
+
+
+class XGUI_ActiveControlSelector;
+class ModuleBase_IWorkshop;
+
+/**
+* Interface of providing only one active control for workshop.
+* It has container of selectors, where only one might be active at the moment.
+* Selection in 3D view is processed by the active selector.
+*/
+class XGUI_ActiveControlMgr : public QObject
+{
+ Q_OBJECT
+public:
+ /// Constructor
+ /// \param theWorkshop the current workshop instance
+ XGUI_EXPORT XGUI_ActiveControlMgr(ModuleBase_IWorkshop* theWorkshop);
+
+ XGUI_EXPORT virtual ~XGUI_ActiveControlMgr() {};
+
+ /// Register selector to process activation of control
+ void addSelector(XGUI_ActiveControlSelector* theSelector);
+
+ /// Returns selector by type name
+ /// \param theType a selector type
+ /// \return selector instance
+ XGUI_EXPORT XGUI_ActiveControlSelector* getSelector(const QString& theType);
+
+ /// Returns the active selector
+ /// \return selector instance
+ XGUI_ActiveControlSelector* activeSelector() const { return myActiveSelector; }
+
+protected slots:
+ /// Deactivates active selector and set the sender selector as active
+ void onSelectorActivated();
+ /// Deactivate the active selector
+ void onSelectorDeactivated();
+ /// Listens workshop selection and pass it to the active selector
+ void onSelectionChanged();
+
+protected:
+ void activateSelector(XGUI_ActiveControlSelector* theSelector);
+
+protected:
+ ModuleBase_IWorkshop* myWorkshop; ///< the current workshop
+
+ QList<XGUI_ActiveControlSelector*> mySelectors; ///< workshop selectors
+ XGUI_ActiveControlSelector* myActiveSelector; ///< active selector
+
+ bool myIsBlocked; ///< blocking flag to avoid cycling signals processing
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_ActiveControlSelector_H
+#define XGUI_ActiveControlSelector_H
+
+#include "XGUI.h"
+
+#include <QObject>
+
+/**
+* Interface to have an active control and process selection by the control.
+* Activation of control may set selection modes and selection filters of the control.
+*/
+class XGUI_ActiveControlSelector : public QObject
+{
+ Q_OBJECT
+
+public:
+ /// Constructor
+ /// \param theWorkshop the current workshop instance
+ XGUI_EXPORT XGUI_ActiveControlSelector() {};
+ /// Destructor
+ XGUI_EXPORT virtual ~XGUI_ActiveControlSelector() {};
+
+ /// Returns name of the selector
+ XGUI_EXPORT virtual QString getType() = 0;
+
+ /// Clear need to be activated widget if it exists
+ XGUI_EXPORT virtual void reset() {}
+
+ /// Sets enable/disable state of the selector. If disable, it will not react to selection
+ /// \param theEnabled if true, selector is enabled
+ XGUI_EXPORT void setEnable(const bool& theEnabled) { myIsEnabled = theEnabled; }
+
+ /// Returns whether the selector is enabled or not
+ /// \return boolean result
+ XGUI_EXPORT bool isEnabled() const { return myIsEnabled; }
+
+ /// Sets control active. It should activates/deactivates selection and selection filters.
+ /// \param isActive if true, the control becomes active
+ XGUI_EXPORT virtual void setActive(const bool& isActive) = 0;
+
+ /// Returns whether the selector should be activated as soon as possible (by deactivatate other)
+ /// \return boolean result
+ XGUI_EXPORT virtual bool needToBeActiated() const { return false; }
+
+ /// Processes current selection of workshop. Reaction to selection change in workshop.
+ XGUI_EXPORT virtual void processSelection() = 0;
+
+signals:
+ /// control is activated
+ void activated();
+ /// control is deactivated
+ void deactivated();
+
+protected:
+ bool myIsEnabled; ///< enable state of the selector
+};
+
+#endif
#include "XGUI_SelectionMgr.h"
#include "XGUI_Displayer.h"
#include "XGUI_ViewerProxy.h"
-#include "XGUI_Selection.h"
#include "XGUI_SalomeConnector.h"
+#include "XGUI_Selection.h"
+#include "XGUI_SelectionActivate.h"
#include "XGUI_DataModel.h"
#include "XGUI_OperationMgr.h"
#include "XGUI_Tools.h"
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_ResultField.h>
+#include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
#include <Config_DataModelReader.h>
XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
: QObject(theParent),
myWorkshop(theParent),
- mySeparator(0)
+ mySeparator1(0), mySeparator2(0), mySeparator3(0)
{
}
aDesktop);
addAction("WIREFRAME_CMD", aAction);
- mySeparator = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
- mySeparator->setSeparator(true);
+ mySeparator1 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+ mySeparator1->setSeparator(true);
+
+ mySeparator2 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+ mySeparator2->setSeparator(true);
+
+ mySeparator3 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+ mySeparator3->setSeparator(true);
//mySelectActions = new QActionGroup(this);
//mySelectActions->setExclusive(true);
addAction("TINSPECTOR_VIEW", aAction);
#endif
+ // Features folders actions
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/create_folder.png"),
+ tr("Insert a folder before"), aDesktop);
+ addAction("INSERT_FOLDER_CMD", aAction);
+
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/insert_folder_before.png"),
+ tr("Move into the previous folder"), aDesktop);
+ addAction("ADD_TO_FOLDER_BEFORE_CMD", aAction);
+
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/insert_folder_after.png"),
+ tr("Move into the next folder"), aDesktop);
+ addAction("ADD_TO_FOLDER_AFTER_CMD", aAction);
+
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_out_before.png"),
+ tr("Move out before the folder"), aDesktop);
+ addAction("ADD_OUT_FOLDER_BEFORE_CMD", aAction);
+
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_out_after.png"),
+ tr("Move out after the folder"), aDesktop);
+ addAction("ADD_OUT_FOLDER_AFTER_CMD", aAction);
+
buildObjBrowserMenu();
buildViewerMenu();
}
bool hasParameter = false;
bool hasCompositeOwner = false;
bool hasResultInHistory = false;
+ bool hasFolder = false;
ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
- hasCompositeOwner, hasResultInHistory);
+ hasCompositeOwner, hasResultInHistory, hasFolder);
//Process Feature
- if (aSelected == 1) {
+ if (aSelected == 1) { // single selection
ObjectPtr aObject = aObjects.first();
if (aObject) {
if (hasResult && myWorkshop->canBeShaded(aObject)) {
(hasFeature || hasParameter));
}
}
- } else {
+ // end single selection
+ } else { // multiselection
// parameter is commented because the actions are not in the list of result parameter actions
if (hasResult /*&& (!hasParameter)*/) {
action("SHOW_CMD")->setEnabled(true);
action("SHADING_CMD")->setEnabled(true);
action("WIREFRAME_CMD")->setEnabled(true);
}
- }
+ } // end multiselection
+
+ // Check folder management commands state if only features are selected
+ if ((!hasResult) && hasFeature && (!hasParameter) && (!hasCompositeOwner) &&
+ (!hasResultInHistory) && (!hasFolder)) {
+ std::list<FeaturePtr> aFeatures = aSelMgr->getSelectedFeatures();
+ if (aFeatures.size() > 0) { // Check that features do not include Parts
+ QModelIndexList aIndexes = aSelMgr->selection()->selectedIndexes();
+ QModelIndex aFirstIdx = aIndexes.first();
+ QModelIndex aLastIdx = aIndexes.last();
+ QModelIndex aParentIdx = aFirstIdx.parent();
+
+ // if all selected are from the same level
+ bool isSameParent = true;
+ foreach(QModelIndex aIdx, aIndexes) {
+ if (aIdx.parent() != aParentIdx) {
+ isSameParent = false;
+ break;
+ }
+ }
+ if (isSameParent) {
+ // Check is selection continuous
+ XGUI_DataModel* aModel = myWorkshop->objectBrowser()->dataModel();
+ DocumentPtr aDoc = aMgr->activeDocument();
+ std::list<FeaturePtr> aFeatures = aSelMgr->getSelectedFeatures();
+
+ bool isContinuos = true;
+ if (aSelected > 1) {
+ int aId = -1;
+ foreach(FeaturePtr aF, aFeatures) {
+ if (aId == -1)
+ aId = aDoc->index(aF);
+ else {
+ aId++;
+ if (aId != aDoc->index(aF)) {
+ isContinuos = false;
+ break;
+ }
+ }
+ }
+ }
+ if (isContinuos) {
+ ObjectPtr aDataObj = aModel->object(aParentIdx);
+
+ ObjectPtr aPrevObj;
+ if (aFirstIdx.row() > 0) {
+ QModelIndex aPrevIdx = aFirstIdx.sibling(aFirstIdx.row() - 1, 0);
+ aPrevObj = aModel->object(aPrevIdx);
+ }
+
+ ObjectPtr aNextObj;
+ if (aLastIdx.row() < (aModel->rowCount(aParentIdx) - 1)) {
+ QModelIndex aNextIdx = aFirstIdx.sibling(aLastIdx.row() + 1, 0);
+ aNextObj = aModel->object(aNextIdx);
+ }
+
+ bool isPrevFolder = (aPrevObj.get() &&
+ (aPrevObj->groupName() == ModelAPI_Folder::group()));
+ bool isNextFolder = (aNextObj.get() &&
+ (aNextObj->groupName() == ModelAPI_Folder::group()));
+ bool isInFolder = (aDataObj.get() &&
+ (aDataObj->groupName() == ModelAPI_Folder::group()));
+ bool isOutsideFolder = !isInFolder;
+
+ bool hasFirst = false;
+ bool hasLast = false;
+ if (isInFolder) {
+ FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aDataObj);
+ FeaturePtr aFirstFeatureInFolder;
+ AttributeReferencePtr aFirstFeatAttr =
+ aFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ if (aFirstFeatAttr)
+ aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+ hasFirst = (aFirstFeatureInFolder == aFeatures.front());
+
+ FeaturePtr aLastFeatureInFolder;
+ AttributeReferencePtr aLastFeatAttr =
+ aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (aLastFeatAttr)
+ aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+ hasLast = (aLastFeatureInFolder == aFeatures.back());
+ }
+ action("INSERT_FOLDER_CMD")->setEnabled(isOutsideFolder);
+ action("ADD_TO_FOLDER_BEFORE_CMD")->setEnabled(isOutsideFolder && isPrevFolder);
+ action("ADD_TO_FOLDER_AFTER_CMD")->setEnabled(isOutsideFolder && isNextFolder);
+ action("ADD_OUT_FOLDER_BEFORE_CMD")->setEnabled(isInFolder && hasFirst);
+ action("ADD_OUT_FOLDER_AFTER_CMD")->setEnabled(isInFolder && hasLast);
+ }
+ }
+ }
+ } // end folder management commands
+
bool allActive = true;
foreach( ObjectPtr aObject, aObjects )
if( aMgr->activeDocument() != aObject->document() ) {
action("SHOW_RESULTS_CMD")->setEnabled(hasFeature);
action("SHOW_FEATURE_CMD")->setEnabled(hasResult && hasResultInHistory);
- }
+ } // end selection processing
// Show/Hide command has to be disabled for objects from non active document
bool aDeactivate = false;
#endif
// Update selection menu
- QIntList aModes = aDisplayer->activeSelectionModes();
+ QIntList aModes = myWorkshop->selectionActivate()->activeSelectionModes();
action("SELECT_VERTEX_CMD")->setEnabled(true);
action("SELECT_EDGE_CMD")->setEnabled(true);
action("SELECT_FACE_CMD")->setEnabled(true);
aList.append(action("SHOW_CMD"));
aList.append(action("HIDE_CMD"));
aList.append(action("SHOW_ONLY_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator1);
aList.append(action("RENAME_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.clear();
aList.append(action("WIREFRAME_CMD"));
aList.append(action("SHADING_CMD"));
- aList.append(mySeparator); // this separator is not shown as this action is added after show only
+ aList.append(mySeparator1); // this separator is not shown as this action is added after show only
// qt list container contains only one instance of the same action
aList.append(action("SHOW_CMD"));
aList.append(action("HIDE_CMD"));
aList.append(action("SHOW_ONLY_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator2);
aList.append(action("RENAME_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("RENAME_CMD"));
aList.append(action("SHOW_RESULTS_CMD"));
aList.append(action("MOVE_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator1);
+ aList.append(action("INSERT_FOLDER_CMD"));
+ aList.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
+ aList.append(action("ADD_TO_FOLDER_AFTER_CMD"));
+ aList.append(mySeparator2);
+ aList.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+ aList.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+ aList.append(mySeparator3);
aList.append(action("CLEAN_HISTORY_CMD"));
aList.append(action("DELETE_CMD"));
myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
aList.clear();
aList.append(action("RENAME_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator1);
aList.append(action("CLEAN_HISTORY_CMD"));
aList.append(action("DELETE_CMD"));
myObjBrowserMenus[ModelAPI_ResultParameter::group()] = aList;
//-------------------------------------
+
+ aList.clear();
+ aList.append(action("DELETE_CMD"));
+ myObjBrowserMenus[ModelAPI_Folder::group()] = aList;
+
}
void XGUI_ContextMenuMgr::buildViewerMenu()
// Result construction menu
aList.append(action("HIDE_CMD"));
aList.append(action("SHOW_ONLY_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator1);
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
#ifdef USE_TRANSPARENCY
aList.clear();
aList.append(action("WIREFRAME_CMD"));
aList.append(action("SHADING_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator1);
aList.append(action("HIDE_CMD"));
aList.append(action("SHOW_ONLY_CMD"));
- aList.append(mySeparator);
+ aList.append(mySeparator2);
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
#ifdef USE_TRANSPARENCY
} else if (aSelected > 1) {
aActions.append(action("WIREFRAME_CMD"));
aActions.append(action("SHADING_CMD"));
- aActions.append(mySeparator);
+ aActions.append(mySeparator1);
aActions.append(action("SHOW_CMD"));
aActions.append(action("HIDE_CMD"));
aActions.append(action("SHOW_ONLY_CMD"));
- aActions.append(mySeparator);
+ aActions.append(mySeparator2);
+ aActions.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
+ aActions.append(action("ADD_TO_FOLDER_AFTER_CMD"));
+ aActions.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+ aActions.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+ aActions.append(mySeparator3);
//aActions.append(action("MOVE_CMD"));
aActions.append(action("COLOR_CMD"));
aActions.append(action("DEFLECTION_CMD"));
// Create selection menu
XGUI_OperationMgr* aOpMgr = myWorkshop->operationMgr();
- QIntList aModes;
- myWorkshop->module()->activeSelectionModes(aModes);
- if ((!aOpMgr->hasOperation()) && aModes.isEmpty()) {
+ if (!aOpMgr->hasOperation() &&
+ myWorkshop->selectionActivate()->activeSelectionPlace() == XGUI_SelectionActivate::Workshop) {
QMenu* aSelMenu = new QMenu(tr("Selection mode"), theMenu);
aSelMenu->addAction(action("SELECT_VERTEX_CMD"));
aSelMenu->addAction(action("SELECT_EDGE_CMD"));
/**
* \ingroup GUI
- * A claas wihich provides manement of context menu
+ * A class wihich provides managent of context menu
*/
class XGUI_EXPORT XGUI_ContextMenuMgr : public QObject
{
//QActionGroup* mySelectActions;
- QAction* mySeparator;
+ QAction* mySeparator1;
+ QAction* mySeparator2;
+ QAction* mySeparator3;
};
#endif
#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_ResultField.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
#include <Config_FeatureMessage.h>
#include <Config_DataModelReader.h>
/// Returns pointer on document if the given object is document object
ModelAPI_Document* getSubDocument(void* theObj)
{
- ModelAPI_Document* aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+ ModelAPI_Document* aDoc = 0;
+ try {
+ aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+ } catch(...) {}
return aDoc;
}
// Insert new object
int aRow = aRootDoc->size(aObjType) - 1;
if (aRow != -1) {
- if (aObjType == aRootType) {
+ if ((aObjType == aRootType) || (aObjType == ModelAPI_Folder::group())) {
insertRow(aRow + aNbFolders + 1);
} else {
int aFolderId = myXMLReader->rootFolderId(aObjType);
}
}
}
- int aRow = aDoc->index(aObject);
+ int aRow = aDoc->index(aObject, true);
if (aRow != -1) {
int aNbSubFolders = foldersCount(aDoc.get());
- if (aObjType == aSubType) {
+ if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) {
// List of objects under document root
insertRow(aRow + aNbSubFolders, aDocRoot);
} else {
for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
std::string aGroup = (*aIt);
if (aDoc == aRootDoc) { // If root objects
- int aRow = aRootDoc->size(aGroup);
- if (aGroup == aRootType) {
+ int aRow = aRootDoc->size(aGroup, true);
+ if ((aGroup == aRootType) || (aGroup == ModelAPI_Folder::group())) {
// Process root folder
removeRow(aRow + aNbFolders);
rebuildBranch(aNbFolders, aRow);
// Check that some folders could erased
QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
- if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0)) {
+ if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup, true) == 0)) {
// Appears first object in folder which can not be shown empty
removeRow(myXMLReader->rootFolderId(aGroup));
removeShownFolder(aRootDoc, aNotEmptyFolder);
// Remove row for sub-document
QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
if (aDocRoot.isValid()) {
- int aRow = aDoc->size(aGroup);
+ int aRow = aDoc->size(aGroup, true);
int aNbSubFolders = foldersCount(aDoc.get());
- if (aGroup == aSubType) {
+ if ((aGroup == aSubType) || (aGroup == ModelAPI_Folder::group())) {
// List of objects under document root
removeRow(aRow + aNbSubFolders, aDocRoot);
rebuildBranch(aNbSubFolders, aRow, aDocRoot);
}
// Check that some folders could disappear
QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
- int aSize = aDoc->size(aGroup);
+ int aSize = aDoc->size(aGroup, true);
foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
if ((aNotEmptyFolder.toStdString() == aGroup) && (aSize == 0)) {
// Appears first object in folder which can not be shown empty
std::set<ObjectPtr> aObjects = aUpdMsg->objects();
std::set<ObjectPtr>::const_iterator aIt;
- std::string aObjType;
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
ObjectPtr aObject = (*aIt);
if (aObject->data()->isValid()) {
QModelIndex aIndex = objectIndex(aResult, 0);
removeRows(0, aResult->stepsSize(), aIndex);
} else {
- QModelIndex aIndex = objectIndex(aObject, 0);
- if (aIndex.isValid()) {
- emit dataChanged(aIndex, aIndex);
+ if (aObject->groupName() == ModelAPI_Folder::group()) {
+ rebuildDataTree();
+ } else {
+ QModelIndex aIndex = objectIndex(aObject, 0);
+ if (aIndex.isValid()) {
+ emit dataChanged(aIndex, aIndex);
+ }
}
}
} else {
{
if (theIndex.internalId() == 0) // this is a folder
return ObjectPtr();
- ModelAPI_Object* aObj =
- dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
+ ModelAPI_Object* aObj = 0;
+ try {
+ aObj = dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
+ } catch(...) {}
+
if (!aObj)
return ObjectPtr();
if (getSubDocument(aObj)) // the selected index is a folder of sub-document
{
std::string aType = theObject->groupName();
DocumentPtr aDoc = theObject->document();
- int aRow = aDoc->index(theObject);
+ int aRow = aDoc->index(theObject, true);
if (aRow == -1) {
// it could be a part of complex object
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
}
}
}
+ int aFRow = -1;
+ FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow);
+ if (aFolder.get())
+ aRow = aFRow;
} else {
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
if (aResult.get()) {
}
SessionPtr aSession = ModelAPI_Session::get();
DocumentPtr aRootDoc = aSession->moduleDocument();
- if (aDoc == aRootDoc && myXMLReader->rootType() == aType) {
+ if (aDoc == aRootDoc &&
+ ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) {
// The object from root document
aRow += foldersCount();
- } else if (myXMLReader->subType() == aType) {
+ } else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) {
// The object from sub document
aRow += foldersCount(aDoc.get());
}
}
}
} else {
- ModelAPI_Object* aObj =
- dynamic_cast<ModelAPI_Object*>((ModelAPI_Entity*)theIndex.internalPointer());
+ ObjectPtr aObj = object(theIndex);
if (aObj) {
switch (theRole) {
case Qt::DisplayRole:
{
if (aObj->groupName() == ModelAPI_ResultParameter::group()) {
- ModelAPI_ResultParameter* aParam = dynamic_cast<ModelAPI_ResultParameter*>(aObj);
+ ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObj);
AttributeDoublePtr aValueAttribute =
aParam->data()->real(ModelAPI_ResultParameter::VALUE());
QString aVal = QString::number(aValueAttribute->value());
}
QString aSuffix;
if (aObj->groupName() == myXMLReader->subType()) {
- ResultPartPtr aPartRes = getPartResult(aObj);
+ ResultPartPtr aPartRes = getPartResult(aObj.get());
if (aPartRes.get()) {
if (aPartRes->partDoc().get() == NULL)
aSuffix = " (Not loaded)";
return aObj->data()->name().c_str() + aSuffix;
}
case Qt::DecorationRole:
- return ModuleBase_IconFactory::get()->getIcon(object(theIndex));
+ {
+ if (aObj->groupName() == ModelAPI_Folder::group())
+ return QIcon(":pictures/features_folder.png");
+ else
+ return ModuleBase_IconFactory::get()->getIcon(aObj);
+ }
}
} else {
switch (theRole) {
int aNbItems = 0;
std::string aType = myXMLReader->rootType();
if (!aType.empty())
- aNbItems = aRootDoc->size(aType);
+ aNbItems = aRootDoc->size(aType, true);
return aNbFolders + aNbItems;
}
int aNbSubItems = 0;
std::string aSubType = myXMLReader->subType();
if (!aSubType.empty())
- aNbSubItems = aSubDoc->size(aSubType);
+ aNbSubItems = aSubDoc->size(aSubType, true);
return aNbSubItems + aNbSubFolders;
} else {
// Check for composite object
ModelAPI_ResultField* aFieldRes = dynamic_cast<ModelAPI_ResultField*>(aObj);
if (aFieldRes)
return aFieldRes->stepsSize();
+ ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aObj);
+ if (aFolder)
+ return getNumberOfFolderItems(aFolder);
}
}
}
else { // return object under root index
std::string aType = myXMLReader->rootType();
int aObjId = theRow - aNbFolders;
- if (aObjId < aRootDoc->size(aType)) {
- ObjectPtr aObj = aRootDoc->object(aType, aObjId);
+ if (aObjId < aRootDoc->size(aType, true)) {
+ ObjectPtr aObj = aRootDoc->object(aType, aObjId, true);
aIndex = objectIndex(aObj, theColumn);
}
}
if (aId == 0) { // return object index inside of first level of folders
std::string aType = myXMLReader->rootFolderType(aParentPos);
if (theRow < aRootDoc->size(aType)) {
- ObjectPtr aObj = aRootDoc->object(aType, theRow);
+ ObjectPtr aObj = aRootDoc->object(aType, theRow, true);
aIndex = objectIndex(aObj, theColumn);
}
} else {
} else {
// this is an object under sub document root
std::string aType = myXMLReader->subType();
- ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders);
+ ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders, true);
aIndex = objectIndex(aObj, theColumn);
}
} else {
dynamic_cast<ModelAPI_ResultField*>(aParentObj);
if (aFieldRes) {
aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow));
+ } else {
+ ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aParentObj);
+ ObjectPtr aObj = getObjectInFolder(aFolder, theRow);
+ if (aObj.get())
+ aIndex = objectIndex(aObj, theColumn);
}
}
}
}
ObjectPtr aObj = object(theIndex);
if (!aObj.get()) {
- // It can b e a step of a field
- ModelAPI_ResultField::ModelAPI_FieldStep* aStep =
- dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
- ((ModelAPI_Entity*)theIndex.internalPointer());
+ // It can be a step of a field
+ ModelAPI_ResultField::ModelAPI_FieldStep* aStep = 0;
+ try {
+ aStep = dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
+ ((ModelAPI_Entity*)theIndex.internalPointer());
+ } catch(...) {}
+
if (aStep) {
ModelAPI_ResultField* aField = aStep->field();
DocumentPtr aDoc = aSession->activeDocument();
if (aCompFea.get()) {
return objectIndex(aCompFea);
}
+ DocumentPtr aDoc = aFeature->document();
+ int aRow;
+ FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow);
+ if (aFolder.get())
+ return objectIndex(aFolder);
}
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
if (aResult.get()) {
DocumentPtr aRootDoc = aSession->moduleDocument();
DocumentPtr aSubDoc = aObj->document();
if (aSubDoc == aRootDoc) {
- if (aType == myXMLReader->rootType())
+ if ((aType == myXMLReader->rootType()) || (aType == ModelAPI_Folder::group()))
return QModelIndex();
else {
// return first level of folder index
return createIndex(aFolderId, 1, (void*)Q_NULLPTR);
}
} else {
- if (aType == myXMLReader->subType())
+ if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group()))
return findDocumentRootIndex(aSubDoc.get());
else {
// return first level of folder index
}
}
} else { // If document is attached to feature
- int aNb = aRootDoc->size(ModelAPI_Feature::group());
+ int aNb = aRootDoc->size(ModelAPI_Feature::group(), true);
ObjectPtr aObj;
ResultPartPtr aPartRes;
for (int i = 0; i < aNb; i++) {
- aObj = aRootDoc->object(ModelAPI_Feature::group(), i);
+ aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true);
aPartRes = getPartResult(aObj.get());
if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) {
int aRow = i;
}
}
+//******************************************************
+bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex)
+{
+ return getVisibilityState(theIndex) == Hidden;
+}
+
//******************************************************
int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const
{
}
return NoneState;
}
+
+
+int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const
+{
+ DocumentPtr aDoc = theFolder->document();
+
+ FeaturePtr aFirstFeatureInFolder;
+ AttributeReferencePtr aFirstFeatAttr =
+ theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ if (aFirstFeatAttr)
+ aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+ if (!aFirstFeatureInFolder.get())
+ return 0;
+
+ FeaturePtr aLastFeatureInFolder;
+ AttributeReferencePtr aLastFeatAttr =
+ theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+ if (aLastFeatAttr)
+ aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+ if (!aLastFeatureInFolder.get())
+ return 0;
+
+ int aFirst = aDoc->index(aFirstFeatureInFolder);
+ int aLast = aDoc->index(aLastFeatureInFolder);
+ return aLast - aFirst + 1;
+}
+
+ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const
+{
+ DocumentPtr aDoc = theFolder->document();
+
+ FeaturePtr aFirstFeatureInFolder;
+ AttributeReferencePtr aFirstFeatAttr =
+ theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+ if (aFirstFeatAttr)
+ aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+ if (!aFirstFeatureInFolder.get())
+ return ObjectPtr();
+
+ int aFirst = aDoc->index(aFirstFeatureInFolder);
+ return aDoc->object(ModelAPI_Feature::group(), aFirst + theId);
+}
/// Do not processing anymore events of model loop
//bool blockEventsProcessing(const bool theState);
+ /// Returns true if the data model item has Hidden visual state
+ /// \param theIndex a tree model item
+ /// \return boolean value
+ bool hasHiddenState(const QModelIndex& theIndex);
+
signals:
/// Signal about tree had been rebuilt
void treeRebuilt();
/// \param fromRoot - root document flag
QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const;
+ int getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const;
+ ObjectPtr getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const;
+
VisibilityState getVisibilityState(const QModelIndex& theIndex) const;
void addShownFolder(DocumentPtr theDoc, QString theFolder)
//
#include "XGUI_Displayer.h"
-#include "XGUI_Workshop.h"
-#include "XGUI_ViewerProxy.h"
-#include "XGUI_SelectionMgr.h"
-#include "XGUI_Selection.h"
+
#include "XGUI_CustomPrs.h"
+#include "XGUI_FacesPanel.h"
+#include "XGUI_Selection.h"
+#include "XGUI_SelectionActivate.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_ViewerProxy.h"
+#include "XGUI_Workshop.h"
#ifndef HAVE_SALOME
#include <AppElements_Viewer.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_ResultCompSolid.h>
+#include <ModuleBase_BRepOwner.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_Preferences.h>
#include <ModuleBase_ResultPrs.h>
#include <ModuleBase_Tools.h>
-#include <ModuleBase_IModule.h>
#include <ModuleBase_ViewerPrs.h>
-#include <ModuleBase_Preferences.h>
#include <GeomAPI_Shape.h>
#include <GeomAPI_IPresentable.h>
#include <AIS_Point.hxx>
#endif
#include <AIS_Selection.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <SelectMgr_ListOfFilter.hxx>
-#include <SelectMgr_ListIteratorOfListOfFilter.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_IsoAspect.hxx>
+#include <SelectMgr_ListOfFilter.hxx>
+#include <SelectMgr_ListIteratorOfListOfFilter.hxx>
#include <SelectMgr_SelectionManager.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <StdSelect_ViewerSelector3d.hxx>
/// defines the local context mouse selection sensitivity
const int MOUSE_SENSITIVITY_IN_PIXEL = 10;
-//#define DEBUG_ACTIVATE_OBJECTS
-//#define DEBUG_DEACTIVATE
-//#define DEBUG_ACTIVATE_AIS
-//#define DEBUG_DEACTIVATE_AIS
-
//#define DEBUG_DISPLAY
//#define DEBUG_FEATURE_REDISPLAY
//#define DEBUG_SELECTION_FILTERS
#define CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
+//#define DEBUG_VIEWER_BLOCKED_COUNT
+
+//**************************************************************
void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
{
// Get from null point
return anInfo.join(theSeparator);
}
-void deselectPresentation(const Handle(AIS_InteractiveObject) theObject,
- const Handle(AIS_InteractiveContext)& theContext)
-{
- NCollection_List<Handle(SelectBasics_EntityOwner)> aResultOwners;
-
- for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected()) {
- Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
- if (anOwner.IsNull()) // TODO: check why it is possible
- continue;
- if (anOwner->Selectable() == theObject && anOwner->IsSelected())
- aResultOwners.Append(anOwner);
- }
- NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (aResultOwners);
- Handle(SelectMgr_EntityOwner) anOwner;
- for (; anOwnersIt.More(); anOwnersIt.Next()) {
- anOwner = Handle(SelectMgr_EntityOwner)::DownCast(anOwnersIt.Value());
- if (!anOwner.IsNull())
- theContext->AddOrRemoveSelected(anOwner, false);
- }
-}
-
+//**************************************************************
XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
- : myWorkshop(theWorkshop), myNeedUpdate(false),
- myIsTrihedronActive(true), myViewerBlockedRecursiveCount(0),
- myIsFirstAISContextUse(true)
+: myWorkshop(theWorkshop), myNeedUpdate(false),
+ myViewerBlockedRecursiveCount(0), myIsFirstAISContextUse(true)
{
myCustomPrs = std::shared_ptr<GeomAPI_ICustomPrs>(new XGUI_CustomPrs(theWorkshop));
}
+//**************************************************************
XGUI_Displayer::~XGUI_Displayer()
{
}
+//**************************************************************
bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
{
return myResult2AISObjectMap.contains(theObject);
}
+//**************************************************************
bool XGUI_Displayer::display(ObjectPtr theObject, bool theUpdateViewer)
{
bool aDisplayed = false;
return aDisplayed;
}
+//**************************************************************
bool canBeShaded(Handle(AIS_InteractiveObject) theAIS, ModuleBase_IModule* theModule)
{
Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS);
return false;
}
+//**************************************************************
bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS,
bool isShading, bool theUpdateViewer)
{
aDisplayed = true;
emit objectDisplayed(theObject, theAIS);
- activate(anAISIO, myActiveSelectionModes, theUpdateViewer);
+ selectionActivate()->activate(anAISIO, theUpdateViewer);
}
if (theUpdateViewer)
updateViewer();
return aDisplayed;
}
+//**************************************************************
bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer)
{
bool aErased = false;
return aErased;
}
+//**************************************************************
bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer)
{
bool aRedisplayed = false;
myWorkshop->module()->storeSelection();
#ifdef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
- deselectPresentation(aAISIO, aContext);
+ myWorkshop->selector()->deselectPresentation(aAISIO);
#endif
aContext->Redisplay(aAISIO, false);
return aRedisplayed;
}
+//**************************************************************
void XGUI_Displayer::redisplayObjects()
{
// redisplay objects visualized in the viewer
Events_Loop::loop()->flush(EVENT_DISP);
}
-void XGUI_Displayer::deactivate(ObjectPtr theObject, const bool theUpdateViewer)
-{
-#ifdef DEBUG_DEACTIVATE
- QString anInfoStr = ModuleBase_Tools::objectInfo(theObject);
- qDebug(QString("deactivate: myActiveSelectionModes[%1]: %2, objects = ").
- arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)).
- arg(anInfoStr).
- toStdString().c_str());
-#endif
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (!aContext.IsNull() && isVisible(theObject)) {
- AISObjectPtr anObj = myResult2AISObjectMap[theObject];
- Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
-
- deactivateAIS(anAIS);
- // the selection from the previous activation modes should be cleared manually (#26172)
-#ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
- deselectPresentation(anAIS, aContext);
-#endif
- if (theUpdateViewer)
- updateViewer();
- }
-}
-
+//**************************************************************
void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList,
const bool theUpdateViewer)
{
QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end();
for (; anIt != aLast; anIt++) {
- deactivate(*anIt, false);
+ selectionActivate()->deactivate(*anIt, false);
}
//VSV It seems that there is no necessity to update viewer on deactivation
//if (theUpdateViewer)
// updateViewer();
}
-void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes)
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (aContext.IsNull() || !isVisible(theObject))
- return;
-
- AISObjectPtr aAISObj = getAISObject(theObject);
-
- if (aAISObj.get() != NULL) {
- Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
- TColStd_ListOfInteger aTColModes;
- aContext->ActivatedModes(anAISIO, aTColModes);
- TColStd_ListIteratorOfListOfInteger itr( aTColModes );
- for (; itr.More(); itr.Next() ) {
- theModes.append(itr.Value());
- }
- }
-}
-
-int XGUI_Displayer::getSelectionMode(int theShapeType)
-{
- return (theShapeType > TopAbs_SHAPE) ? theShapeType :
- AIS_Shape::SelectionMode((TopAbs_ShapeEnum)theShapeType);
-}
-
+//**************************************************************
bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& theObject)
{
bool aVisible = false;
return aVisible;
}
-#ifdef DEBUG_ACTIVATE_OBJECTS
-QString getModeInfo(const int theMode)
-{
- QString anInfo = "Undefined";
- switch(theMode) {
- case 0: anInfo = "SHAPE(0)"; break;
- case 1: anInfo = "VERTEX(1)"; break;
- case 2: anInfo = "EDGE(2)"; break;
- case 3: anInfo = "WIRE(3)"; break;
- case 4: anInfo = "FACE(4)"; break;
- case 5: anInfo = "SHELL(5)"; break;
- case 6: anInfo = "SOLID(6)"; break;
- case 7: anInfo = "COMPSOLID(7)"; break;
- case 8: anInfo = "COMPOUND(8)"; break;
- case 100: anInfo = "Sel_Mode_First(100)"; break; //SketcherPrs_Tools
- case 101: anInfo = "Sel_Constraint(101)"; break;
- case 102: anInfo = "Sel_Dimension_All(102)"; break;
- case 103: anInfo = "Sel_Dimension_Line(103)"; break;
- case 104: anInfo = "Sel_Dimension_Text(104)"; break;
- default: break;
- }
- return anInfo;
-}
-
-QString getModesInfo(const QIntList& theModes)
-{
- QStringList aModesInfo;
- for (int i = 0, aSize = theModes.size(); i < aSize; i++)
- aModesInfo.append(getModeInfo(theModes[i]));
- return QString("[%1] = %2").arg(aModesInfo.size()).arg(aModesInfo.join(", "));
-}
-#endif
-
-void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList,
- const bool theUpdateViewer)
-{
- // Convert shape types to selection types
- QIntList aModes;
- foreach(int aType, theModes) {
- aModes.append(getSelectionMode(aType));
- }
-
-#ifdef DEBUG_ACTIVATE_OBJECTS
- QStringList anInfo;
- QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end();
- for (; anIt != aLast; ++anIt) {
- anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
- }
- QString anInfoStr = anInfo.join(", ");
-
- qDebug(QString("activateObjects: new modes%1, active modes%2, objects[%3] = %4").
- arg(getModesInfo(aModes)).
- arg(getModesInfo(myActiveSelectionModes)).
- arg(theObjList.size()).
- arg(anInfoStr).
- toStdString().c_str());
-#endif
- // In order to avoid doblications of selection modes
- QIntList aNewModes;
- foreach (int aMode, aModes) {
- if (!aNewModes.contains(aMode))
- aNewModes.append(aMode);
- }
- myActiveSelectionModes = aNewModes;
- Handle(AIS_InteractiveContext) aContext = AISContext();
- // Open local context if there is no one
- if (aContext.IsNull())
- return;
-
- //aContext->UseDisplayedObjects();
- //myUseExternalObjects = true;
-
- Handle(AIS_InteractiveObject) anAISIO;
- AIS_ListOfInteractive aPrsList;
- //if (aObjList.isEmpty())
- // return;
- //else {
- foreach(ObjectPtr aObj, theObjList) {
- if (myResult2AISObjectMap.contains(aObj))
- aPrsList.Append(myResult2AISObjectMap[aObj]->impl<Handle(AIS_InteractiveObject)>());
- }
- //}
-
- // Add trihedron because it has to partisipate in selection
- Handle(AIS_InteractiveObject) aTrihedron;
- if (isTrihedronActive()) {
- aTrihedron = getTrihedron();
- if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron))
- aPrsList.Append(aTrihedron);
- }
- if (aPrsList.Extent() == 0)
- return;
-
- AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
- bool isActivationChanged = false;
- for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
- anAISIO = aLIt.Value();
- if (activate(anAISIO, myActiveSelectionModes, false))
- isActivationChanged = true;
- }
-}
-
-bool XGUI_Displayer::isActive(ObjectPtr theObject) const
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (aContext.IsNull() || !isVisible(theObject))
- return false;
-
- AISObjectPtr anObj = myResult2AISObjectMap[theObject];
- Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
-
- TColStd_ListOfInteger aModes;
- aContext->ActivatedModes(anAIS, aModes);
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->ActivatedModes(anAIS, aModes);
- #endif
-
- return aModes.Extent() > 0;
-}
-
-
+//**************************************************************
void XGUI_Displayer::setSelected(const QList<ModuleBase_ViewerPrsPtr>& theValues,
bool theUpdateViewer)
{
updateViewer();
}
+//**************************************************************
void XGUI_Displayer::clearSelected(const bool theUpdateViewer)
{
Handle(AIS_InteractiveContext) aContext = AISContext();
}
}
+//**************************************************************
bool XGUI_Displayer::eraseAll(const bool theUpdateViewer)
{
bool aErased = false;
return aErased;
}
-void deactivateObject(Handle(AIS_InteractiveContext) theContext,
- Handle(AIS_InteractiveObject) theObject
-#ifdef TINSPECTOR
- , Handle(VInspectorAPI_CallBack) theCallBack
-#endif
- )
-{
- if (!theObject.IsNull()) {
- theContext->Deactivate(theObject);
- #ifdef TINSPECTOR
- if (theCallBack) theCallBack->Deactivate(theObject);
- #endif
- }
-}
-
-void XGUI_Displayer::deactivateTrihedron(const bool theUpdateViewer) const
-{
- Handle(AIS_InteractiveObject) aTrihedron = getTrihedron();
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron)) {
- Handle(AIS_Trihedron) aTrie = Handle(AIS_Trihedron)::DownCast(aTrihedron);
- deactivateObject(aContext, aTrie
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
-
- /// #1136 hidden axis are selected in sketch
-#ifdef BEFORE_TRIHEDRON_PATCH
- deactivateObject(aContext, aTrie->XAxis()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
- deactivateObject(aContext, aTrie->YAxis()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
- deactivateObject(aContext, aTrie->Axis()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
- deactivateObject(aContext, aTrie->Position()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
-
- deactivateObject(aContext, aTrie->XYPlane()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
- deactivateObject(aContext, aTrie->XZPlane()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
- deactivateObject(aContext, aTrie->YZPlane()
- #ifdef TINSPECTOR
- , getCallBack()
- #endif
- );
-#endif
- if (theUpdateViewer)
- updateViewer();
- }
-}
-
-Handle(AIS_InteractiveObject) XGUI_Displayer::getTrihedron() const
-{
- return myWorkshop->viewer()->trihedron();
-}
-
-/*void XGUI_Displayer::openLocalContext()
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- // Open local context if there is no one
- if (!aContext.IsNull() && !aContext->HasOpenedContext()) {
- // Preserve selected objects
- //AIS_ListOfInteractive aAisList;
- //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent())
- // aAisList.Append(aContext->Current());
-
- // get the filters from the global context and append them to the local context
- // a list of filters in the global context is not cleared and should be cleared here
- SelectMgr_ListOfFilter aFilters;
- aFilters.Assign(aContext->Filters());
- // it is important to remove the filters in the global context, because there is a code
- // in the closeLocalContex, which restore the global context filters
- aContext->RemoveFilters();
-
- //aContext->ClearCurrents();
- aContext->OpenLocalContext();
- //deactivateTrihedron();
- //aContext->NotUseDisplayedObjects();
-
- //myUseExternalObjects = false;
-
- SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
- for (;aIt.More(); aIt.Next()) {
- aContext->AddFilter(aIt.Value());
- }
- // Restore selection
- //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
- //for(; aIt2.More(); aIt2.Next()) {
- // aContext->SetSelected(aIt2.Value(), false);
- //}
- }
-}*/
-
-/*void XGUI_Displayer::closeLocalContexts(const bool theUpdateViewer)
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (!aContext.IsNull() && aContext->HasOpenedContext()) {
- // Preserve selected objects
- //AIS_ListOfInteractive aAisList;
- //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
- // aAisList.Append(aContext->SelectedInteractive());
-
- // get the filters from the local context and append them to the global context
- // a list of filters in the local context is cleared
- SelectMgr_ListOfFilter aFilters;
- aFilters.Assign(aContext->Filters());
-
- //aContext->ClearSelected();
- aContext->CloseAllContexts(false);
-
- // From the moment when the AIS_DS_Displayed flag is used in the Display of AIS object,
- // this code is obsolete. It is temporaty commented and should be removed after
- // the test campaign.
- // Redisplay all object if they were displayed in localContext
- /*Handle(AIS_InteractiveObject) aAISIO;
- foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
- aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
- if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
- aContext->Display(aAISIO, false);
- aContext->SetDisplayMode(aAISIO, Shading, false);
- }
- }*+/
-
- // Append the filters from the local selection in the global selection context
- SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
- for (;aIt.More(); aIt.Next()) {
- Handle(SelectMgr_Filter) aFilter = aIt.Value();
- aContext->AddFilter(aFilter);
- }
-
- if (theUpdateViewer)
- updateViewer();
- //myUseExternalObjects = false;
-
- // Restore selection
- //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
- //for(; aIt2.More(); aIt2.Next()) {
- // if (aContext->IsDisplayed(aIt2.Value()))
- // aContext->SetCurrentObject(aIt2.Value(), false);
- //}
- }
-}*/
+//**************************************************************
AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
{
AISObjectPtr anIO;
return anIO;
}
+//**************************************************************
ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
{
Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
return getObject(aRefAIS);
}
+//**************************************************************
ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
{
ObjectPtr anObject;
return anObject;
}
+//**************************************************************
bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled)
{
bool aWasEnabled = isUpdateEnabled();
else
myViewerBlockedRecursiveCount++;
+#ifdef DEBUG_VIEWER_BLOCKED_COUNT
+ std::cout << "myViewerBlockedRecursiveCount = " << myViewerBlockedRecursiveCount << std::endl;
+#endif
+
if (myNeedUpdate && isUpdateEnabled()) {
updateViewer();
myNeedUpdate = false;
return aWasEnabled;
}
+//**************************************************************
bool XGUI_Displayer::isUpdateEnabled() const
{
return myViewerBlockedRecursiveCount == 0;
}
+//**************************************************************
void XGUI_Displayer::updateViewer() const
{
Handle(AIS_InteractiveContext) aContext = AISContext();
+
+#ifdef DEBUG_VIEWER_BLOCKED_COUNT
+ std::cout << "updateViewer: " << (myViewerBlockedRecursiveCount == 0 ? " done" : " later")
+ << std::endl;
+#endif
+
if (!aContext.IsNull() && isUpdateEnabled()) {
//myWorkshop->viewer()->Zfitall();
aContext->UpdateCurrentViewer();
}
}
-void XGUI_Displayer::activateAIS(const Handle(AIS_InteractiveObject)& theIO,
- const int theMode, const bool theUpdateViewer) const
-{
- Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
- if (!theIO.IsNull() && theIO == getTrihedron()) {
- if (theMode != AIS_Shape::SelectionType(TopAbs_EDGE) &&
- theMode != AIS_Shape::SelectionType(TopAbs_VERTEX))
- return;
- }
- if (!aContext.IsNull()) {
- if (myWorkshop->module()) {
- int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode);
- aContext->Activate(theIO, theMode, false);
- } else
- aContext->Activate(theIO, theMode, false);
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->Activate(theIO, theMode);
- #endif
-
- // the fix from VPA for more suitable selection of sketcher lines
- if (theIO->Width() > 1) {
- double aPrecision = theIO->Width() + 2;
- if (theMode == getSelectionMode(TopAbs_VERTEX))
- aPrecision = ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
- "point-selection-sensitivity",
- 12);
- else if ((theMode == getSelectionMode(TopAbs_EDGE)) ||
- (theMode == getSelectionMode(TopAbs_WIRE)))
- aPrecision = theIO->Width() +
- ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
- "edge-selection-sensitivity", 2);
- aContext->SetSelectionSensitivity(theIO, theMode, aPrecision);
- }
-
-#ifdef DEBUG_ACTIVATE_AIS
- ObjectPtr anObject = getObject(theIO);
- anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
- qDebug(QString("activateAIS: theMode = %1, object = %2").arg(theMode)
- .arg(anInfo).toStdString().c_str());
-#endif
- if (theUpdateViewer)
- updateViewer();
- }
-}
-
-void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO,
- const int theMode) const
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (!aContext.IsNull()) {
- if (theMode == -1) {
- aContext->Deactivate(theIO);
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->Deactivate(theIO);
- #endif
- }
- else {
- aContext->Deactivate(theIO, theMode);
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->Deactivate(theIO, theMode);
- #endif
- }
-
-#ifdef DEBUG_DEACTIVATE_AIS
- ObjectPtr anObject = getObject(theIO);
- anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
- qDebug(QString("deactivateAIS: theMode = %1, object = %2").arg(theMode)
- .arg(anInfo).toStdString().c_str());
-#endif
- }
-}
-
+//**************************************************************
Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
{
Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
if (!aContext.IsNull() && myIsFirstAISContextUse/*&& !aContext->HasOpenedContext()*/) {
XGUI_Displayer* aDisplayer = (XGUI_Displayer*)this;
aDisplayer->myIsFirstAISContextUse = false;
- //aContext->OpenLocalContext();
- if (!isTrihedronActive())
- deactivateTrihedron(true);
+ if (!myWorkshop->selectionActivate()->isTrihedronActive())
+ selectionActivate()->deactivateTrihedron(true);
aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0);
aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0);
}
return aContext;
}
+//**************************************************************
Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
{
Handle(AIS_InteractiveContext) aContext = AISContext();
return myAndFilter;
}
+//**************************************************************
bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes,
const Standard_Integer theDisplayMode, bool theUpdateViewer)
{
#ifdef TINSPECTOR
if (getCallBack()) getCallBack()->Load(anAISIO);
#endif
- if (toActivateInSelectionModes) {
- if (myActiveSelectionModes.size() == 0)
- activateAIS(anAISIO, 0, theUpdateViewer);
- else {
- foreach(int aMode, myActiveSelectionModes) {
- activateAIS(anAISIO, aMode, theUpdateViewer);
- }
- }
- }
+ if (toActivateInSelectionModes)
+ myWorkshop->selectionActivate()->activateOnDisplay(anAISIO, theUpdateViewer);
+
if (theUpdateViewer)
updateViewer();
}
return aDisplayed;
}
+//**************************************************************
bool XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool theUpdateViewer)
{
bool aErased = false;
return aErased;
}
-
+//**************************************************************
void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool theUpdateViewer)
{
if (theMode == NoMode)
updateViewer();
}
+//**************************************************************
XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
{
Handle(AIS_InteractiveContext) aContext = AISContext();
return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
}
-void XGUI_Displayer::deactivateSelectionFilters()
+//**************************************************************
+void XGUI_Displayer::deactivateSelectionFilters(const bool theAddFilterOnly)
{
Handle(AIS_InteractiveContext) aContext = AISContext();
if (!myAndFilter.IsNull()) {
}
}
+//**************************************************************
void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
{
Handle(AIS_InteractiveContext) aContext = AISContext();
}
}
+//**************************************************************
void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
{
Handle(AIS_InteractiveContext) aContext = AISContext();
}
}
+//**************************************************************
bool XGUI_Displayer::hasSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
{
bool aFilterFound = false;
return aFilterFound;
}
+//**************************************************************
void XGUI_Displayer::removeFilters()
{
Handle(AIS_InteractiveContext) aContext = AISContext();
aCompositeFilter->Clear();
}
+//**************************************************************
void XGUI_Displayer::showOnly(const QObjectPtrList& theList)
{
QObjectPtrList aDispList = myResult2AISObjectMap.keys();
updateViewer();
}
+//**************************************************************
bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const
{
if (!isVisible(theObject))
return ::canBeShaded(anAIS, myWorkshop->module());
}
-bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
- const QIntList& theModes,
- const bool theUpdateViewer) const
-{
- Handle(AIS_InteractiveContext) aContext = AISContext();
- if (aContext.IsNull() || theIO.IsNull())
- return false;
-
- bool isActivationChanged = false;
- // deactivate object in all modes, which are not in the list of activation
- // It seems that after the IO deactivation the selected state of the IO's owners
- // is modified in OCC(version: 6.8.0) and the selection of the object later is lost.
- // By this reason, the number of the IO deactivate is decreased and the object is deactivated
- // only if there is a difference in the current modes and the parameters modes.
- // If the selection problem happens again, it is possible to write a test scenario and create
- // a bug. The bug steps are the following:
- // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both,
- // with clicked SHIFT select the second object.
- // The result is the selection of the first IO is lost.
- TColStd_ListOfInteger aTColModes;
- aContext->ActivatedModes(theIO, aTColModes);
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->ActivatedModes(theIO, aTColModes);
- #endif
- TColStd_ListIteratorOfListOfInteger itr( aTColModes );
- QIntList aModesActivatedForIO;
- bool isDeactivated = false;
- bool aHasValidMode = false;
- for (; itr.More(); itr.Next() ) {
- Standard_Integer aMode = itr.Value();
- aHasValidMode = aHasValidMode || aMode != -1;
- int aShapeMode = (aMode > 8)? aMode : AIS_Shape::SelectionType(aMode);
- if (!theModes.contains(aMode)) {
- deactivateAIS(theIO, aMode);
- isDeactivated = true;
- }
- else {
- aModesActivatedForIO.append(aMode);
- }
- }
- if (isDeactivated) {
- // the selection from the previous activation modes should be cleared manually (#26172)
- //theIO->ClearSelected();
- //#ifdef TINSPECTOR
- //if (getCallBack()) getCallBack()->ClearSelected(theIO);
- //#endif
-#ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
- deselectPresentation(theIO, aContext);
-#endif
- // For performance issues
- //if (theUpdateViewer)
- // updateViewer();
- isActivationChanged = true;
- }
-
- // loading the interactive object allowing the decomposition
- if (aTColModes.IsEmpty() || !aHasValidMode) {
- aContext->Load(theIO, -1, true);
- Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
- if (!aTrihedron.IsNull()) {
- // Workaround for Trihedron. It should be loaded using the next Load method to
- // add this object to myGlobal map of selection manager
- // it is important to activate trihedron in two selection modes: edges and vertices
- aContext->SelectionManager()->Load(theIO);
- }
-
- #ifdef TINSPECTOR
- if (getCallBack()) getCallBack()->Load(theIO);
- #endif
- }
-
- // trihedron AIS check should be after the AIS loading.
- // If it is not loaded, it is steel selectable in the viewer.
- Handle(AIS_Trihedron) aTrihedron;
- if (!isTrihedronActive())
- aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
- if (aTrihedron.IsNull()) {
- // In order to clear active modes list
- if (theModes.size() == 0) {
- activateAIS(theIO, 0, theUpdateViewer);
- } else {
- foreach(int aMode, theModes) {
- if (!aModesActivatedForIO.contains(aMode)) {
- activateAIS(theIO, aMode, theUpdateViewer);
- isActivationChanged = true;
- }
- }
- }
- }
- return isActivationChanged;
-}
-
+//**************************************************************
bool XGUI_Displayer::customizeObject(ObjectPtr theObject)
{
AISObjectPtr anAISObj = getAISObject(theObject);
aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs);
isCustomized = myWorkshop->module()->afterCustomisePresentation(aResult, anAISObj, myCustomPrs)
|| isCustomized;
+
+ // update presentation state if faces panel is active
+ if (anAISObj.get() && myWorkshop->facesPanel())
+ isCustomized = myWorkshop->facesPanel()->customizeObject(theObject, anAISObj) || isCustomized;
+
return isCustomized;
}
-
+//**************************************************************
QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject,
const QColor& theColor,
bool theUpdateViewer)
return QColor(aR, aG, aB);
}
+//**************************************************************
void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS)
{
myResult2AISObjectMap[theObject] = theAIS;
}
#ifdef _DEBUG
+//**************************************************************
std::string XGUI_Displayer::getResult2AISObjectMapInfo() const
{
QStringList aContent;
}
#endif
+//**************************************************************
void XGUI_Displayer::getPresentations(const ObjectPtr& theObject,
NCollection_Map<Handle(AIS_InteractiveObject)>& thePresentations)
{
}
}
-void XGUI_Displayer::activateTrihedron(bool theIsActive)
-{
- myIsTrihedronActive = theIsActive;
- if (!myIsTrihedronActive) {
- deactivateTrihedron(true);
- }
-}
-
+//**************************************************************
void XGUI_Displayer::displayTrihedron(bool theToDisplay) const
{
Handle(AIS_InteractiveContext) aContext = AISContext();
Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron();
+ XGUI_SelectionActivate* aSelectionActive = selectionActivate();
if (theToDisplay) {
if (!aContext->IsDisplayed(aTrihedron))
aContext->Display(aTrihedron,
if (getCallBack()) getCallBack()->Display(aTrihedron);
#endif
- if (!isTrihedronActive())
- deactivateTrihedron(false);
+ if (!aSelectionActive->isTrihedronActive())
+ aSelectionActive->deactivateTrihedron(false);
else
- activate(aTrihedron, myActiveSelectionModes, false);
+ aSelectionActive->activate(aTrihedron, false);
} else {
- deactivateTrihedron(false);
+ aSelectionActive->deactivateTrihedron(false);
aContext->Erase(aTrihedron, Standard_True);
#ifdef TINSPECTOR
updateViewer();
}
-QIntList XGUI_Displayer::activeSelectionModes() const
-{
- QIntList aModes;
- foreach (int aMode, myActiveSelectionModes) {
- // aMode < 9 is a Shape Enum values
- aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode);
- }
- return aModes;
-}
-
+//**************************************************************
void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
const NCollection_DataMap<TopoDS_Shape,
NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected)
theContext->AddOrRemoveSelected(anIt.Value(), Standard_False);
}
}
+
+//**************************************************************
+XGUI_SelectionActivate* XGUI_Displayer::selectionActivate() const
+{
+ return myWorkshop->selectionActivate();
+}
#include "XGUI.h"
#include <GeomAPI_AISObject.h>
-#include <TopoDS_Shape.hxx>
-#include <AIS_InteractiveObject.hxx>
-#include <AIS_InteractiveContext.hxx>
-#include <NCollection_Map.hxx>
-#include <NCollection_DataMap.hxx>
+#include <GeomAPI_ICustomPrs.h>
#include <ModelAPI_Result.h>
#include <ModuleBase_Definitions.h>
-#include <GeomAPI_ICustomPrs.h>
-
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_DataMap.hxx>
#include <SelectMgr_AndFilter.hxx>
+#include <TopoDS_Shape.hxx>
-#include <QString>
+#include <QColor>
#include <QMap>
#include <QObject>
-#include <QColor>
+#include <QString>
class ModuleBase_ViewerPrs;
class ModelAPI_Feature;
+class XGUI_SelectionActivate;
class XGUI_Workshop;
#ifdef TINSPECTOR
public:
/// \enum DisplayMode display mode
enum DisplayMode {
- /// Mode is not defined
- NoMode = -1,
- /// Wireframe display mode
- Wireframe,
- /// Shading display mode
- Shading
+ NoMode = -1, ///< Mode is not defined
+ Wireframe, ///< Wireframe display mode
+ Shading ///< Shading display mode
};
/// Constructor
/// \return true if the object visibility state is changed
bool eraseAll(const bool theUpdateViewer = true);
- /// Deactivates selection of sub-shapes
- /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
- //void closeLocalContexts(const bool theUpdateViewer = true);
-
/// Remove default selection filters of the module from the current viewer
- void deactivateSelectionFilters();
+ /// \param theAddFilterOnly if is not 'true' it will deactivate all fiters in viewer
+ void deactivateSelectionFilters(const bool theAddFilterOnly = true);
/// \brief Add selection filter
/// \param theFilter a filter instance
/// Updates the viewer
void updateViewer() const;
- /// Activate interactive context
- /// \param theIO an interactive object
- /// \param theMode activation mode
- /// \param theUpdateViewer update viewer flag
- void activateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode,
- const bool theUpdateViewer) const;
-
- /// Activate interactive context. It is necessary to call ClearOutdatedSelection
- /// after deactivation
- /// \param theIO an interactive object
- /// \param theMode a mode to deactivate. When theMode=-1 then all modes will be deactivated
- void deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode = -1) const;
-
/// Searches the interactive object by feature
/// \param theObject the object or presentable feature
/// \return theIO an interactive object
void deactivateObjects(const QObjectPtrList& theObjList,
const bool theUpdateViewer = true);
- /// Returns the modes of activation
- /// \param theObject the feature or NULL if it not visualized
- /// \param theModes - modes on which it is activated (can be empty)
- void getModesOfActivation(ObjectPtr theObject, QIntList& theModes);
-
- /// Returns true if the given object can be selected
- /// \param theObject object to check
- bool isActive(ObjectPtr theObject) const;
-
- /// Activates in local context displayed outside of the context.
- /// \param theModes - modes on which it has to be activated (can be empty)
- /// \param theObjList - list of objects which has to be activated.
- /// \param theUpdateViewer an update viewer flag
- void activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList,
- const bool theUpdateViewer = true);
-
/// Sets display mode for the given object if this object is displayed
void setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool theUpdateViewer = true);
/// \return previously defined color on the object
QColor setObjectColor(ObjectPtr theObject, const QColor& theColor, bool theUpdateViewer = true);
- /// Returns Trihedron object if it is displayed
- Handle(AIS_InteractiveObject) getTrihedron() const;
-
- /// Set trihedron active (used in selection) or non active
- void activateTrihedron(bool theIsActive);
-
/// Displays/erases thrihedron in current modes. It will be activated or deactivated
/// depending on the trihedron visible state and displayer active trihedron state
void displayTrihedron(bool theToDisplay) const;
- /// Returns true if the trihedron should be activated in current selection modes
- bool isTrihedronActive() const { return myIsTrihedronActive; }
-
- /// Returns list of currently active selection modes
- /// Selection modes will be returned according to TopAbs_ShapeEnum
- QIntList activeSelectionModes() const;
-
#ifdef TINSPECTOR
void setCallBack(const Handle(VInspectorAPI_CallBack)& theCallBack)
{ myVCallBack = theCallBack; }
Handle(VInspectorAPI_CallBack) getCallBack() const { return myVCallBack; }
#endif
- /// Converts shape type (TopAbs_ShapeEnum) to selection mode
- /// \param theShapeType a shape type from TopAbs_ShapeEnum
- static int getSelectionMode(int theShapeType);
/// Return true if the object is visible. If the object is feature, it returns true
/// if all results of the feature are shown
bool theUpdateViewer = true);
private:
- /// Activates the interactive object in the local context.
- /// \param theIO an interactive object
- /// \param theModes - modes on which it has to be activated (can be empty)
- /// \return a flag is object activated or not
- bool activate(const Handle(AIS_InteractiveObject)& theIO, const QIntList& theModes,
- const bool theUpdateViewer) const;
-
- /// Deactivates the given object (not allow selection)
- /// \param theObject object to deactivate
- void deactivate(ObjectPtr theObject, const bool theUpdateViewer);
-
- /// Find a trihedron in a list of displayed presentations and deactivate it.
- /// \param theUpdateViewer an update viewer flag
- void deactivateTrihedron(const bool theUpdateViewer) const;
-
/// Update the object presentable properties such as color, lines width and other
/// If the object is result with the color attribute value set, it is used,
/// otherwise the customize is applyed to the object's feature if it is a custom prs
/// owner is selected if it is found there.
/// Only first owner is processed(according to OCCT logic)
static void AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
- const NCollection_DataMap<TopoDS_Shape,
- NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected);
+ const NCollection_DataMap<TopoDS_Shape,
+ NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected);
- protected:
- /// Reference to workshop
- XGUI_Workshop* myWorkshop;
+protected:
+ XGUI_SelectionActivate* selectionActivate() const;
+
+protected:
+ XGUI_Workshop* myWorkshop; ///< Reference to workshop
#ifdef TINSPECTOR
Handle(VInspectorAPI_CallBack) myVCallBack;
#endif
- /// A container for selection filters
- Handle(SelectMgr_AndFilter) myAndFilter;
+ Handle(SelectMgr_AndFilter) myAndFilter; ///< A container for selection filters
/// A default custom presentation, which is used if the displayed feature is not
/// a custom presentation
/// Definition of a type of map which defines correspondance between objects and presentations
typedef QMap<ObjectPtr, AISObjectPtr> ResultToAISMap;
+ ResultToAISMap myResult2AISObjectMap; ///< A map of displayed objects
- /// A map of displayed objects
- ResultToAISMap myResult2AISObjectMap;
-
- /// Selection modes installed for external objects in local context
- QIntList myActiveSelectionModes;
-
- /// Number of blocking of the viewer update. The viewer is updated only if it equals zero
+ /// Number of blocking of the viewer update. The viewer is updated only if it is zero
int myViewerBlockedRecursiveCount;
- /// Flag: first asking of AIS context: trihedron activation
- bool myIsFirstAISContextUse;
-
- /// Flag: use trihedgon for selection or not
- bool myIsTrihedronActive;
-
- /// A flag that update was requested but not done
- mutable bool myNeedUpdate;
+ bool myIsFirstAISContextUse; ///< Flag: first asking of AIS context: trihedron activation
+ mutable bool myNeedUpdate; ///< A flag that update was requested but not done
};
#endif
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "XGUI_FacesPanel.h"
+
+#include <Config_PropManager.h>
+#include <Events_Loop.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
+
+#include <ModelAPI_Events.h>
+
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_ISelection.h>
+#include "ModuleBase_IWorkshop.h"
+#include "ModuleBase_ListView.h"
+#include "ModuleBase_ResultPrs.h"
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_ViewerPrs.h"
+
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_SelectionFilterType.h"
+#include "XGUI_Tools.h"
+#include "XGUI_Workshop.h"
+
+#include <QAction>
+#include <QCheckBox>
+#include <QFocusEvent>
+#include <QGridLayout>
+#include <QListWidget>
+#include <QMainWindow>
+
+static const int LayoutMargin = 3;
+
+//********************************************************************
+XGUI_FacesPanel::XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop)
+ : QDockWidget(theParent), myIsActive(false), myWorkshop(theWorkshop)
+{
+ setWindowTitle(tr("Hide Faces"));
+ QAction* aViewAct = toggleViewAction();
+ setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
+
+ QWidget* aContent = new QWidget(this);
+ QGridLayout* aMainLayout = new QGridLayout(aContent);
+ aMainLayout->setContentsMargins(LayoutMargin, LayoutMargin, LayoutMargin, LayoutMargin);
+ setWidget(aContent);
+
+ myHiddenOrTransparent = new QCheckBox(tr("Transparent"), aContent);
+ connect(myHiddenOrTransparent, SIGNAL(toggled(bool)), SLOT(onTransparencyChanged()));
+
+ myListView = new ModuleBase_ListView(aContent, "", "Hidden/transparent faces in 3D view");
+ connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem()));
+
+ aMainLayout->addWidget(myHiddenOrTransparent, 0, 0);
+ aMainLayout->addWidget(myListView->getControl(), 1, 0);
+
+ myListView->getControl()->setFocusPolicy(Qt::StrongFocus);
+ myListView->getControl()->viewport()->installEventFilter(this);
+}
+
+//********************************************************************
+void XGUI_FacesPanel::reset(const bool isToFlushRedisplay)
+{
+ if (myLastItemIndex == 0) // do nothing because there was no activity in the pane after reset
+ return;
+
+ // clear internal containers
+ myListView->getControl()->clear();
+ myItems.clear();
+
+ // restore previous view of presentations
+ bool isModified = redisplayObjects(myItemObjects);
+ std::set<std::shared_ptr<ModelAPI_Object> > aHiddenObjects = myHiddenObjects;
+ isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects) || isModified;
+ if (isModified)// && isToFlushRedisplay) // flush signal immediatelly until container is filled
+ flushRedisplay();
+
+ updateProcessedObjects(myItems, myItemObjects);
+ myHiddenObjects.clear();
+ myLastItemIndex = 0; // it should be after redisplay as flag used in customize
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::isEmpty() const
+{
+ return myItems.size() == 0;
+}
+
+//********************************************************************
+void XGUI_FacesPanel::selectionModes(QIntList& theModes)
+{
+ theModes.append(TopAbs_FACE);
+}
+
+//********************************************************************
+void XGUI_FacesPanel::selectionFilters(SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ ModuleBase_IModule* aModule = myWorkshop->module();
+ QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
+
+ theSelectionFilters.Append(aModule->selectionFilter(SF_GlobalFilter));
+ theSelectionFilters.Append(aModule->selectionFilter(SF_FilterInfinite));
+ theSelectionFilters.Append(aModule->selectionFilter(SF_ResultGroupNameFilter));
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::eventFilter(QObject* theObject, QEvent *theEvent)
+{
+ QWidget* aWidget = qobject_cast<QWidget*>(theObject);
+ if (theEvent->type() == QEvent::MouseButtonRelease)
+ {
+ if (myListView->getControl()->viewport() == aWidget)
+ setActivePanel(true);
+ }
+ // pass the event on to the parent class
+ return QObject::eventFilter(theObject, theEvent);
+}
+
+//********************************************************************
+void XGUI_FacesPanel::setActivePanel(const bool theIsActive)
+{
+ if (myIsActive == theIsActive)
+ return;
+
+ ModuleBase_Tools::setShadowEffect(myListView->getControl(), theIsActive);
+ myIsActive = theIsActive;
+
+ if (myIsActive) {
+ emit activated();
+ // selection should be cleared after emit of signal to do not process selection change
+ // event by the previous selector
+ // the selection is cleared by activating selection control
+ XGUI_Tools::workshop(myWorkshop)->selector()->clearSelection();
+ }
+ else
+ emit deactivated();
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::useTransparency() const
+{
+ return myHiddenOrTransparent->isChecked();
+}
+
+//********************************************************************
+void XGUI_FacesPanel::restoreObjects(const std::set<ObjectPtr>& theHiddenObjects)
+{
+ std::set<int> anIndicesToBeRemoved;
+ for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anItemsIt = myItems.begin();
+ anItemsIt != myItems.end(); anItemsIt++)
+ {
+ ModuleBase_ViewerPrsPtr aPrs = anItemsIt.value();
+ ObjectPtr anObject = aPrs->object();
+ if (theHiddenObjects.find(anObject) == theHiddenObjects.end()) // not found
+ continue;
+ anIndicesToBeRemoved.insert(anItemsIt.key());
+ }
+
+ // remove from myItes container
+ for (std::set<int>::const_iterator aToBeRemovedIt = anIndicesToBeRemoved.begin();
+ aToBeRemovedIt != anIndicesToBeRemoved.end(); aToBeRemovedIt++)
+ {
+ myItems.remove(*aToBeRemovedIt);
+ }
+ if (!anIndicesToBeRemoved.empty()) // means that myItems has been changed
+ updateProcessedObjects(myItems, myItemObjects);
+ myListView->removeItems(anIndicesToBeRemoved);
+
+ // remove from container of hidden objects
+ for (std::set<ObjectPtr>::const_iterator aHiddenIt = theHiddenObjects.begin();
+ aHiddenIt != theHiddenObjects.end(); aHiddenIt++)
+ {
+ if (myHiddenObjects.find(*aHiddenIt) != myHiddenObjects.end()) /// found objects
+ myHiddenObjects.erase(*aHiddenIt);
+ }
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::processAction(ModuleBase_ActionType theActionType)
+{
+ switch (theActionType) {
+ //case ActionEnter:
+ // return processEnter();
+ case ActionEscape:
+ setActivePanel(false);
+ return true;
+ case ActionDelete:
+ return processDelete();
+ //case ActionUndo:
+ //case ActionRedo:
+ default:
+ return false;
+ }
+}
+
+//********************************************************************
+void XGUI_FacesPanel::processSelection()
+{
+ QList<ModuleBase_ViewerPrsPtr> aSelected = myWorkshop->selection()->getSelected(
+ ModuleBase_ISelection::Viewer);
+ bool isModified = false;
+ static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+
+ std::map<ObjectPtr, NCollection_List<TopoDS_Shape> > anObjectToShapes;
+ std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
+ for (int i = 0; i < aSelected.size(); i++) {
+ ModuleBase_ViewerPrsPtr aPrs = aSelected[i];
+ ObjectPtr anObject = aPrs->object();
+ if (!anObject.get())
+ continue;
+ if (ModuleBase_Tools::getSelectedShape(aPrs).ShapeType() != TopAbs_FACE)
+ continue;
+
+ Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
+ aPrs->interactive());
+ if (aResultPrs.IsNull())
+ continue;
+
+ myItems.insert(myLastItemIndex, aPrs);
+ myListView->addItem(generateName(aPrs), myLastItemIndex);
+ myLastItemIndex++;
+ isModified = true;
+
+ if (anObjectToShapes.find(anObject) != anObjectToShapes.end())
+ anObjectToShapes.at(anObject).Append(ModuleBase_Tools::getSelectedShape(aPrs));
+ else {
+ NCollection_List<TopoDS_Shape> aListOfShapes;
+ aListOfShapes.Append(ModuleBase_Tools::getSelectedShape(aPrs));
+ anObjectToShapes[anObject] = aListOfShapes;
+ anObjectToPrs[anObject] = aResultPrs;
+ }
+ }
+ for (std::map<ObjectPtr, NCollection_List<TopoDS_Shape> >::const_iterator
+ anIt = anObjectToShapes.begin(); anIt != anObjectToShapes.end(); anIt++) {
+ ObjectPtr anObject = anIt->first;
+ if (!anObject.get() || anObjectToPrs.find(anObject) == anObjectToPrs.end())
+ continue;
+ Handle(ModuleBase_ResultPrs) aResultPrs = anObjectToPrs.at(anObject);
+
+ if (aResultPrs->hasSubShapeVisible(anIt->second) || useTransparency()) // redisplay
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
+ else { // erase object because it is entirely hidden
+ anObject->setDisplayed(false);
+ myHiddenObjects.insert(anObject);
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
+ }
+ }
+ if (isModified) {
+ updateProcessedObjects(myItems, myItemObjects);
+ flushRedisplay();
+ }
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::processDelete()
+{
+ //appendFirstSelectionInHistory();
+ QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes();
+
+ std::set<int> aSelectedIds;
+ myListView->getSelectedIndices(aSelectedIds);
+ if (aSelectedIds.empty())
+ return false;
+
+ bool isModified = false;
+ std::set<ObjectPtr> aRestoredObjects;
+ for (std::set<int>::const_iterator anIt = aSelectedIds.begin(); anIt != aSelectedIds.end();
+ anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = myItems[*anIt];
+ if (aRestoredObjects.find(aPrs->object()) == aRestoredObjects.end())
+ aRestoredObjects.insert(aPrs->object());
+ myItems.remove(*anIt);
+ isModified = true;
+ }
+ if (isModified) {
+ bool isRedisplayed = redisplayObjects(aRestoredObjects);
+ isRedisplayed = displayHiddenObjects(aRestoredObjects, myHiddenObjects)
+ || isRedisplayed;
+ if (isRedisplayed)
+ flushRedisplay();
+ // should be after flush of redisplay to have items object to be updated
+ updateProcessedObjects(myItems, myItemObjects);
+ }
+
+ myListView->removeSelectedItems();
+ // Restore selection
+ myListView->restoreSelection(anIndices);
+ //appendSelectionInHistory();
+ return true;
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::redisplayObjects(
+ const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects)
+{
+ if (theObjects.empty())
+ return false;
+
+ bool isModified = false;
+ static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ for (std::set<ObjectPtr>::const_iterator anIt = theObjects.begin(); anIt != theObjects.end();
+ anIt++)
+ {
+ ObjectPtr anObject = *anIt;
+ if (!anObject->isDisplayed())
+ continue;
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
+ isModified = true;
+ }
+ return isModified;
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::displayHiddenObjects(
+ const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects,
+ std::set<std::shared_ptr<ModelAPI_Object> >& theHiddenObjects)
+{
+ if (theObjects.empty())
+ return false;
+
+ bool isModified = false;
+ static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+
+ for (std::set<ObjectPtr>::const_iterator anIt = theObjects.begin(); anIt != theObjects.end();
+ anIt++)
+ {
+ ObjectPtr anObject = *anIt;
+ // if the object was hidden by this panel
+ if (anObject->isDisplayed() || theHiddenObjects.find(anObject) == theHiddenObjects.end())
+ continue;
+ theHiddenObjects.erase(anObject);
+ anObject->setDisplayed(true); // it means that the object is hidden by hide all faces
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
+ isModified = true;
+ }
+ return isModified;
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::hideEmptyObjects()
+{
+ bool isModified = false;
+ static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ std::map<ObjectPtr, NCollection_List<TopoDS_Shape> > anObjectToShapes;
+ std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
+
+ for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anIt = myItems.begin();
+ anIt != myItems.end(); anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = anIt.value();
+ ObjectPtr anObject = aPrs->object();
+ if (!anObject.get() || !anObject->isDisplayed())
+ continue;
+
+ Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
+ aPrs->interactive());
+ if (aResultPrs.IsNull())
+ continue;
+
+ if (anObjectToShapes.find(anObject) != anObjectToShapes.end())
+ anObjectToShapes.at(anObject).Append(ModuleBase_Tools::getSelectedShape(aPrs));
+ else {
+ NCollection_List<TopoDS_Shape> aListOfShapes;
+ aListOfShapes.Append(ModuleBase_Tools::getSelectedShape(aPrs));
+ anObjectToShapes[anObject] = aListOfShapes;
+ anObjectToPrs[anObject] = aResultPrs;
+ }
+ }
+ for (std::map<ObjectPtr, NCollection_List<TopoDS_Shape> >::const_iterator
+ anIt = anObjectToShapes.begin(); anIt != anObjectToShapes.end(); anIt++) {
+ ObjectPtr anObject = anIt->first;
+ if (!anObject.get() || anObjectToPrs.find(anObject) == anObjectToPrs.end())
+ continue;
+ Handle(ModuleBase_ResultPrs) aResultPrs = anObjectToPrs.at(anObject);
+
+ if (!aResultPrs->hasSubShapeVisible(anIt->second)) {
+ // erase object because it is entirely hidden
+ anObject->setDisplayed(false);
+ myHiddenObjects.insert(anObject);
+ ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
+ isModified = true;
+ }
+ }
+ return isModified;
+}
+
+//********************************************************************
+void XGUI_FacesPanel::updateProcessedObjects(QMap<int, ModuleBase_ViewerPrsPtr> theItems,
+ std::set<ObjectPtr>& theObjects)
+{
+ theObjects.clear();
+ for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anIt = theItems.begin();
+ anIt != theItems.end(); anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = anIt.value();
+ ObjectPtr anObject = aPrs.get() ? aPrs->object() : ObjectPtr();
+ if (anObject.get() && theObjects.find(anObject) != theObjects.end())
+ continue;
+ theObjects.insert(anObject);
+ }
+}
+
+//********************************************************************
+void XGUI_FacesPanel::closeEvent(QCloseEvent* theEvent)
+{
+ QDockWidget::closeEvent(theEvent);
+ emit closed();
+}
+
+//********************************************************************
+QString XGUI_FacesPanel::generateName(const ModuleBase_ViewerPrsPtr& thePrs)
+{
+ if (!thePrs.get() || !thePrs->object().get())
+ return "Undefined";
+
+ GeomShapePtr aContext;
+ ObjectPtr anObject = thePrs->object();
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ if (aResult.get())
+ aContext = aResult->shape();
+ else {
+ // TODO if there is this case
+ }
+
+ QString aName = anObject->data()->name().c_str();
+ if (aContext.get()) {
+ GeomShapePtr aSubShape(new GeomAPI_Shape());
+ aSubShape->setImpl(new TopoDS_Shape(ModuleBase_Tools::getSelectedShape(thePrs)));
+ if (!aSubShape->isEqual(aContext))
+ aName += QString("_%1").arg(GeomAlgoAPI_CompoundBuilder::id(aContext, aSubShape));
+ }
+ return aName;
+}
+
+//********************************************************************
+bool XGUI_FacesPanel::customizeObject(const ObjectPtr& theObject,
+ const AISObjectPtr& thePresentation)
+{
+ if (myLastItemIndex == 0) // do nothing because there was no activity in the pane after reset
+ return false;
+
+ if (thePresentation.get() == NULL)
+ return false;
+
+ if (myItemObjects.find(theObject) == myItemObjects.end()) // not found
+ return false;
+
+ // if the object is displayed, the hidden faces are collected and set to the presentation
+ bool isModified = false;
+ NCollection_List<TopoDS_Shape> aHiddenSubShapes;
+ for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anIt = myItems.begin();
+ anIt != myItems.end(); anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = anIt.value();
+ if (aPrs.get() && aPrs->object() != theObject)
+ continue;
+ TopoDS_Shape aShape = ModuleBase_Tools::getSelectedShape(aPrs);
+ if (!aHiddenSubShapes.Contains(aShape))
+ aHiddenSubShapes.Append(aShape);
+ }
+
+ Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
+ thePresentation->impl<Handle(AIS_InteractiveObject)>());
+ if (aResultPrs.IsNull())
+ return false;
+
+ isModified = aResultPrs->setSubShapeHidden(aHiddenSubShapes);
+
+ double aTransparency = !useTransparency() ? 1
+ : Config_PropManager::real("Visualization", "hidden_face_transparency");
+ isModified = aResultPrs->setHiddenSubShapeTransparency(aTransparency) || isModified;
+
+ return isModified;
+}
+
+//********************************************************************
+void XGUI_FacesPanel::onDeleteItem()
+{
+ processDelete();
+}
+
+//********************************************************************
+void XGUI_FacesPanel::onTransparencyChanged()
+{
+ bool isModified = false;
+ if (useTransparency()) {
+ std::set<std::shared_ptr<ModelAPI_Object> > aHiddenObjects = myHiddenObjects;
+ isModified = displayHiddenObjects(aHiddenObjects, myHiddenObjects);
+ }
+ else
+ isModified = hideEmptyObjects();
+
+ isModified = redisplayObjects(myItemObjects) || isModified;
+ if (isModified)
+ flushRedisplay();
+}
+
+//********************************************************************
+void XGUI_FacesPanel::onClosed()
+{
+ setActivePanel(false);
+ reset(true);
+}
+
+//********************************************************************
+void XGUI_FacesPanel::flushRedisplay() const
+{
+ Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ // Necessary for update visibility icons in ObjectBrowser
+ XGUI_ObjectsBrowser* anObjectBrowser = XGUI_Tools::workshop(myWorkshop)->objectBrowser();
+ if (anObjectBrowser)
+ anObjectBrowser->updateAllIndexes();
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_FacesPanel_H_
+#define XGUI_FacesPanel_H_
+
+#include "XGUI.h"
+
+#include <ModelAPI_Object.h>
+
+#include <ModuleBase_ActionType.h>
+#include <ModuleBase_Definitions.h>
+#include <ModuleBase_ViewerPrs.h>
+
+#include <SelectMgr_ListOfFilter.hxx>
+
+#include <QDockWidget>
+#include <QObject>
+#include <QMap>
+
+#include <set>
+
+class AIS_InteractiveObject;
+
+class GeomAPI_AISObject;
+
+class ModuleBase_IWorkshop;
+class ModuleBase_ListView;
+
+class QAction;
+class QCheckBox;
+class QEvent;
+
+/**
+* \ingroup GUI
+* A Hide Faces panel for making it possible to hide faces in the 3D view.
+* The panel has multi-selector filled by faces elements. When the control is active
+* it is possible to select faces in the viewer. The selected faces are hidden/transparent
+* after selection and the corresponding item is appeared in the multi selector.
+*
+* In order to redisplay a face, it is enough to click delete on the name of this face
+* in the multiselector.
+* When the panel is opened, the multiselector is empty.
+* When the panel is closed, the multiselector is emptied and the faces are displayed again.
+* The default position by of this dockable window is to the right of the view (in SALOME mode).
+* If no feature is processed (in neutral point), this panel can be activated too.
+* On feature edition start or finish, movement of the history line, undo/redo and other
+* modification of the model, the multiselector is emptied.
+*/
+class XGUI_EXPORT XGUI_FacesPanel : public QDockWidget
+{
+ Q_OBJECT
+public:
+ /// Constructor
+ /// \param theParent is a parent of the property panel
+ XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop);
+ ~XGUI_FacesPanel() {}
+
+ /// Clear content of list widget
+ /// \param isToFlushRedisplay flag if redisplay should be flushed immediatelly
+ virtual void reset(const bool isToFlushRedisplay);
+
+ /// Returns whether faces panel contains elements
+ /// \return boolean value
+ bool isEmpty() const;
+
+ /// Fills container with the panel selection mode: FACE
+ // \param theModes [out] a container of modes
+ void selectionModes(QIntList& theModes);
+
+ /// Appends into container of workshop selection filters
+ /// \param [out] selection filters
+ void selectionFilters(SelectMgr_ListOfFilter& theSelectionFilters);
+
+ /// Returns whether the panel is active or not
+ bool isActivePanel() const { return myIsActive; }
+
+ /// Stores the state if panel is active and highlight the panel in an active color
+ /// \param theIsActive state whether the panel should be activated or deactivated
+ void setActivePanel(const bool theIsActive);
+
+ /// Returns true if transparency choice is checked
+ /// \return boolean value
+ bool useTransparency() const;
+
+ /// Returns true if the object is in internal container of hidden objects by this panel
+ /// \param theObject a checked object
+ /// \return boolean value
+ bool isObjectHiddenByPanel(const std::shared_ptr<ModelAPI_Object>& theObject) const
+ { return myHiddenObjects.find(theObject) != myHiddenObjects.end(); }
+
+ /// Removed faces of the objects from the panel
+ /// \param container of objects
+ void restoreObjects(const std::set<std::shared_ptr<ModelAPI_Object> >& theHiddenObjects);
+
+ /// Returns true if the event is processed. The default implementation is empty, returns false.
+ virtual bool processAction(ModuleBase_ActionType theActionType);
+
+ /// Append selected item in the list and customize presentations to hide faces
+ void processSelection();
+
+ /// Deletes item in a list of elements
+ /// \return whether the delete action is processed
+ bool processDelete();
+
+ /// Processing focus in/out for the faces control
+ /// \param theObject source object of event
+ /// \param theEvent an event
+ virtual bool eventFilter(QObject* theObject, QEvent *theEvent);
+
+ /// Hide/show faces of the object if:
+ /// - face selector is active
+ /// - object is mentioned in the list of selected elements
+ /// If the object is displayed, all panel faces selected on it will be moved into presentation
+ /// or, if redisplayed, fuction return if the object should be redisplayed or not
+ /// \param theObject a customized object
+ /// \param thePresentation visualized presentation of the object
+ /// \return true if the presentation is customized
+ bool customizeObject(const std::shared_ptr<ModelAPI_Object>& theObject,
+ const std::shared_ptr<GeomAPI_AISObject>& thePresentation);
+
+protected:
+ /// Reimplementation to emit a signal about the panel close
+ virtual void closeEvent(QCloseEvent* theEvent);
+
+signals:
+ /// Signal about activating pane
+ void activated();
+ /// Signal about deactivating pane
+ void deactivated();
+ /// Signal is emitted by the top widget cross button click
+ void closed();
+
+private:
+ /// Redisplay objects.
+ /// \param theObjects container of objects
+ /// \return true if some of objects was redisplayed
+ static bool redisplayObjects(const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects);
+
+ /// Display objects if the objects are in a container of hidden by this pane.
+ /// \param theObjects container of objects
+ /// \param theHiddenObjects hidden objects, if object is in the container, it should be removed
+ /// \return true if some of objects was redisplayed
+ static bool displayHiddenObjects(const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects,
+ std::set<std::shared_ptr<ModelAPI_Object> >& theHiddenObjects);
+
+ /// Iterates by items and hide objects where all sub-shapes are hidden
+ /// \return true if some of objects was redisplayed
+ bool hideEmptyObjects();
+
+ /// Container of objects participating in the panel, it is filled by internal container
+ /// \param theItems container of selected values
+ /// \param theObjects [out] container of objects
+ static void updateProcessedObjects(QMap<int, std::shared_ptr<ModuleBase_ViewerPrs> > theItems,
+ std::set<std::shared_ptr<ModelAPI_Object> >& theObjects);
+
+ /// Generates a presentation name in form: <object_name>/<face>_<face_index>
+ /// \param thePrs a presentation
+ /// \return string value
+ static QString generateName(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
+
+protected slots:
+ /// Deletes element in list of items
+ void onDeleteItem();
+
+ /// Upates hidden faces to be hidden or transparent
+ void onTransparencyChanged();
+
+ /// Closes faces panel restore all hidden faces by calling reset()
+ void onClosed();
+
+private:
+ /// Flushes redisplay event and perform update of object browser icons
+ /// (objects might be hidden/shown)
+ void flushRedisplay() const;
+
+protected:
+ QCheckBox* myHiddenOrTransparent; ///< if checked - transparent, else hidden
+ ModuleBase_ListView* myListView; ///< list control of processed faces
+ ModuleBase_IWorkshop* myWorkshop; ///< workshop
+
+ bool myIsActive; ///< current state about the panel is active
+ int myLastItemIndex; ///< last index to be used in the map of items for the next added item
+
+ QMap<int, std::shared_ptr<ModuleBase_ViewerPrs> > myItems; ///< selected face items
+ std::set<std::shared_ptr<ModelAPI_Object> > myItemObjects; ///< cached objects of myItems
+ std::set<std::shared_ptr<ModelAPI_Object> > myHiddenObjects; ///< hidden objects
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_FacesPanelSelector.h>
+
+#include <XGUI_FacesPanel.h>
+
+//********************************************************************
+XGUI_FacesPanelSelector::XGUI_FacesPanelSelector(XGUI_FacesPanel* thePanel)
+: myPanel(thePanel)
+{
+ connect(myPanel, SIGNAL(activated()), this, SIGNAL(activated()));
+ connect(myPanel, SIGNAL(deactivated()), this, SIGNAL(deactivated()));
+}
+
+//********************************************************************
+void XGUI_FacesPanelSelector::reset()
+{
+ myPanel->reset(true);
+}
+
+//********************************************************************
+void XGUI_FacesPanelSelector::setActive(const bool& isActive)
+{
+ myPanel->setActivePanel(isActive);
+}
+
+//********************************************************************
+void XGUI_FacesPanelSelector::processSelection()
+{
+ myPanel->processSelection();
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_FacesPanelSelector_H
+#define XGUI_FacesPanelSelector_H
+
+#include "XGUI.h"
+
+#include <XGUI_ActiveControlSelector.h>
+
+class XGUI_FacesPanel;
+
+/**
+* Processing selection by the faces panel.
+*/
+class XGUI_FacesPanelSelector : public XGUI_ActiveControlSelector
+{
+ Q_OBJECT
+
+public:
+ /// Constructor
+ /// \param thePanel the workshop faces panel
+ XGUI_EXPORT XGUI_FacesPanelSelector(XGUI_FacesPanel* thePanel);
+ /// Destructor
+ XGUI_EXPORT virtual ~XGUI_FacesPanelSelector() {};
+
+ /// Returns name of the selector
+ XGUI_EXPORT static QString Type() { return "XGUI_FacesPanelSelector"; }
+
+ /// Returns name of the selector
+ XGUI_EXPORT virtual QString getType() { return Type(); }
+
+ /// Set empty widget that need to be activated widget if it is not empty
+ XGUI_EXPORT virtual void reset();
+
+ /// Sets control active. It should activates/deactivates selection and selection filters.
+ /// \param isActive if true, the control becomes active
+ XGUI_EXPORT virtual void setActive(const bool& isActive);
+
+ /// Processes current selection of workshop. Reaction to selection change in workshop.
+ XGUI_EXPORT virtual void processSelection();
+
+protected:
+ XGUI_FacesPanel* myPanel; ///< processed panel
+};
+
+#endif
#include "XGUI_ModuleConnector.h"
#include "XGUI_Workshop.h"
#include "XGUI_ViewerProxy.h"
-#include "XGUI_SelectionMgr.h"
#include "XGUI_Selection.h"
+#include "XGUI_SelectionActivate.h"
+#include "XGUI_SelectionMgr.h"
#include "XGUI_OperationMgr.h"
#include "XGUI_Displayer.h"
#include "XGUI_PropertyPanel.h"
return myWorkshop->errorMgr();
}
+ModuleBase_ISelectionActivate* XGUI_ModuleConnector::selectionActivate() const
+{
+ return myWorkshop->selectionActivate();
+}
+
ModuleBase_Operation* XGUI_ModuleConnector::currentOperation() const
{
return myWorkshop->operationMgr()->currentOperation();
return aActiveOPbjects;
}
-void XGUI_ModuleConnector::activateSubShapesSelection(const QIntList& theTypes)
-{
- QIntList aTypes = theTypes;
-
- XGUI_Displayer* aDisp = myWorkshop->displayer();
- myWorkshop->module()->customSubShapesSelectionModes(aTypes);
- aDisp->activateObjects(aTypes, activeObjects(aDisp->displayedObjects()));
-}
-
-void XGUI_ModuleConnector::deactivateSubShapesSelection()
-{
- // Clear selection modes
- activateModuleSelectionModes();
-}
-
-void XGUI_ModuleConnector::activateModuleSelectionModes()
-{
- XGUI_Displayer* aDisp = myWorkshop->displayer();
- myWorkshop->activateObjectsSelection(activeObjects(aDisp->displayedObjects()));
-}
-
AISObjectPtr XGUI_ModuleConnector::findPresentation(const ObjectPtr& theObject) const
{
XGUI_Displayer* aDisp = myWorkshop->displayer();
//! Returns list of currently selected data objects
virtual ModuleBase_ISelection* selection() const;
- /// Activate sub-shapes selection (opens local context if it was not opened)
- /// Types has to be dined according to TopAbs_ShapeEnum
- virtual void activateSubShapesSelection(const QIntList& theTypes);
-
- /// Activate objects in the module selection modes(opens local context)
- virtual void activateModuleSelectionModes();
-
- /// Deactivate sub-shapes selection (closes local context)
- virtual void deactivateSubShapesSelection();
-
//! Returns instance of loaded module
virtual ModuleBase_IModule* module() const;
//! Returns error manager
virtual ModuleBase_IErrorMgr* errorMgr() const;
+ /// A selection activate in 3D View handler
+ virtual ModuleBase_ISelectionActivate* selectionActivate() const;
+
//! Returns currently active operation
virtual ModuleBase_Operation* currentOperation() const;
#include <ModelAPI_Data.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Document.h>
+#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_Tools.h>
#include <ModuleBase_Tools.h>
+#include <XGUI_Workshop.h>
+
#include <QLayout>
#include <QLineEdit>
#include <QPixmap>
ObjectPtr aObj = aModel->object(theIndex);
if (aObj.get()) {
ResultPtr aResObj = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+ XGUI_ObjectsBrowser* aObjBrowser = qobject_cast<XGUI_ObjectsBrowser*>(parent());
if (aResObj.get()) {
- aResObj->setDisplayed(!aResObj->isDisplayed());
+ std::set<ObjectPtr> anObjects;
+ anObjects.insert(aResObj);
+
+ bool hasHiddenState = aModel->hasHiddenState(theIndex);
+ if (aObjBrowser && hasHiddenState && !aObjBrowser->workshop()->prepareForDisplay(anObjects))
+ return;
+ if (hasHiddenState) // #issue 2335(hide all faces then show solid problem)
+ aResObj->setDisplayed(true);
+ else
+ aResObj->setDisplayed(!aResObj->isDisplayed());
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
update(theIndex);
}
// Update list of selected objects because this event happens after
// selection event in object browser
- XGUI_ObjectsBrowser* aObjBrowser = qobject_cast<XGUI_ObjectsBrowser*>(parent());
if (aObjBrowser) {
aObjBrowser->onSelectionChanged();
}
myTreeView->setExpanded(aIdx, (*aIt));
}
}
+
+void XGUI_ObjectsBrowser::updateAllIndexes(int theColumn, const QModelIndex& theParent)
+{
+ int aNb = myDocModel->rowCount(theParent);
+ for (int i = 0; i < aNb; i++) {
+ QModelIndex aIdx = myDocModel->index(i, theColumn, theParent);
+ if (aIdx.isValid()) {
+ myTreeView->update(aIdx);
+ updateAllIndexes(theColumn, aIdx);
+ }
+ }
+}
void onSelectionChanged();
+ /// Updates all items of object browser
+ /// \param theColumn - column of items
+ /// \param theParent - a parent item (by default from root)
+ void updateAllIndexes(int theColumn = 0, const QModelIndex& theParent = QModelIndex());
public slots:
//! Called on Edit command request
//
#include "XGUI_OperationMgr.h"
+
+#include "XGUI_ActiveControlMgr.h"
+#include "XGUI_ActiveControlSelector.h"
+#include "XGUI_FacesPanelSelector.h"
#include "XGUI_ModuleConnector.h"
#include "XGUI_Workshop.h"
#include "XGUI_ErrorMgr.h"
+#include "XGUI_FacesPanel.h"
#include "XGUI_Tools.h"
#include "XGUI_ObjectsBrowser.h"
#include "XGUI_ContextMenuMgr.h"
if (anActiveWgt)
isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape);
}
+ if (!isAccepted)
+ {
+ XGUI_ActiveControlSelector* anActiveSelector =
+ XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector();
+ if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
+ isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionEscape);
+ }
// default Escape button functionality
if (!isAccepted && aOperation) {
onAbortOperation();
if (!aOperation)
return isAccepted;
ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ if (!aPanel)
+ return isAccepted;
// the next code is obsolete as we want to process Enter in property panel always
// only property panel enter is processed in order to do not process enter in application dialogs
//bool isPPChild = isChildObject(theObject, aPanel);
}
}
}
+ if (!isAccepted)
+ {
+ XGUI_ActiveControlSelector* anActiveSelector =
+ XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector();
+ if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
+ isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionDelete);
+ }
if (!isAccepted) {
// after widget, object browser and viewer should process delete
/// other widgets such as line edit controls should not lead to
/// Enumeration of kind of message that is used when trying to stop the active operation
enum XGUI_MessageKind
{
- XGUI_AbortOperationMessage, //< warns and give possibility to abort current operation
- XGUI_InformationMessage //< ask to apply the current operation before performing something
+ XGUI_AbortOperationMessage, ///< warns and give possibility to abort current operation
+ XGUI_InformationMessage ///< ask to apply the current operation before performing something
};
public:
// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
//
-#include <XGUI_PropertyPanel.h>
#include <XGUI_ActionsMgr.h>
+#include <XGUI_ActiveControlMgr.h>
+#include <XGUI_SelectionActivate.h>
+#include <XGUI_ActiveControlSelector.h>
+#include <XGUI_PropertyPanel.h>
+#include <XGUI_PropertyPanelSelector.h>
#include <XGUI_OperationMgr.h>
+#include <XGUI_Tools.h>
+#include <XGUI_Workshop.h>
+
//#include <AppElements_Constants.h>
#include <ModuleBase_WidgetMultiSelector.h>
#include <ModuleBase_Tools.h>
if (myActiveWidget)
myActiveWidget->deactivate();
+ XGUI_ActiveControlSelector* aPPSelector = XGUI_Tools::workshop(myOperationMgr->workshop())->
+ activeControlMgr()->getSelector(XGUI_PropertyPanelSelector::Type());
+ aPPSelector->reset(); // it removes need to be updated widget link
+
/// as the widgets are deleted later, it is important that the signals
/// of these widgets are not processed. An example of the error is issue 986.
/// In the given case, the property panel is firstly filled by new widgets
myWidgets.clear();
myPanelPage->clearPage();
myActiveWidget = NULL;
+ emit propertyPanelDeactivated();
+ myOperationMgr->workshop()->selectionActivate()->updateSelectionModes();
+ myOperationMgr->workshop()->selectionActivate()->updateSelectionFilters();
#ifdef DEBUG_ACTIVE_WIDGET
std::cout << "myActiveWidget = NULL" << std::endl;
#endif
bool isFirstControl = !theIsNext;
QWidget* aLastFocusControl = myActiveWidget->getControlAcceptingFocus(isFirstControl);
if (aFocusWidget == aLastFocusControl) {
- setActiveWidget(NULL);
+ setActiveWidget(NULL, false);
}
}
aPreviosAttributeID = myActiveWidget->attributeID();
// Avoid activation of already actve widget. It could happen on focusIn event many times
- if (setActiveWidget(theWidget) && theEmitSignal) {
- emit widgetActivated(myActiveWidget);
- if (!myActiveWidget && !isEditingMode()) {
- emit noMoreWidgets(aPreviosAttributeID);
- }
- }
+ setActiveWidget(theWidget, theEmitSignal);
}
-bool XGUI_PropertyPanel::setActiveWidget(ModuleBase_ModelWidget* theWidget)
+bool XGUI_PropertyPanel::setActiveWidget(ModuleBase_ModelWidget* theWidget, const bool isEmitSignal)
{
// Avoid activation of already actve widget. It could happen on focusIn event many times
if (theWidget == myActiveWidget) {
return false;
}
std::string aPreviosAttributeID;
+ ModuleBase_ModelWidget* aDeactivatedWidget = NULL, *anActivatedWidget = NULL;
if(myActiveWidget) {
aPreviosAttributeID = myActiveWidget->attributeID();
myActiveWidget->processValueState();
myActiveWidget->deactivate();
myActiveWidget->setHighlighted(false);
+ aDeactivatedWidget = myActiveWidget;
}
if(theWidget) {
emit beforeWidgetActivated(theWidget);
theWidget->setHighlighted(true);
theWidget->activate();
+ anActivatedWidget = theWidget;
}
myActiveWidget = theWidget;
+
#ifdef DEBUG_ACTIVE_WIDGET
std::cout << "myActiveWidget = " << (theWidget ? theWidget->context().c_str() : "") << std::endl;
#endif
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
- Events_Loop::loop()->flush(anEvent);
-
+ bool aHasMoreWidgets = true;
+ if (isEmitSignal) {
+ //emit widgetActivated(myActiveWidget);
+ if (!myActiveWidget && !isEditingMode()) {
+ aHasMoreWidgets = false;
+ emit noMoreWidgets(aPreviosAttributeID);
+ }
+ }
+ if (myActiveWidget)
+ emit propertyPanelActivated();
+ else
+ emit propertyPanelDeactivated();
+ myOperationMgr->workshop()->selectionActivate()->updateSelectionModes();
+ myOperationMgr->workshop()->selectionActivate()->updateSelectionFilters();
+
+ if (aHasMoreWidgets && aDeactivatedWidget)
+ aDeactivatedWidget->updateAfterDeactivation();
+ if (aHasMoreWidgets && anActivatedWidget)
+ anActivatedWidget->updateAfterActivation();
+
+ if (aHasMoreWidgets && myActiveWidget)
+ {
+ // restore widget selection should be done after selection modes of widget activating
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
+ Events_Loop::loop()->flush(anEvent);
+ }
return true;
}
/**
* Makes the given widget active, highlights it and removes
* highlighting from the previous active widget
- * emits widgetActivated(theWidget) signal
* \param theWidget which has to be activated
* \param theEmitSignal a flag to prohibit signal emit
*/
/// \param theObject a sender of the event
void enterClicked(QObject* theObject);
+ /// Emits on deactivating property panel (e.g. by clearContent)
+ void propertyPanelDeactivated();
+ /// Emits on widget activating
+ void propertyPanelActivated();
+
protected:
/// Makes the widget active, deactivate the previous, activate and hightlight the given one
/// \param theWidget a widget
- bool setActiveWidget(ModuleBase_ModelWidget* theWidget);
+ /// \param isEmitSignal flag whether panel signals should be emitted
+ bool setActiveWidget(ModuleBase_ModelWidget* theWidget, const bool isEmitSignal);
/// The parent method that processes the "Tab"/"SHIF + Tab" keyboard events
/// Emits a signal about focus change
/// If theIsNext is true, this function searches forward, if next is false, it searches backward.
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include <XGUI_PropertyPanelSelector.h>
+#include <XGUI_PropertyPanel.h>
+
+//********************************************************************
+XGUI_PropertyPanelSelector::XGUI_PropertyPanelSelector(XGUI_PropertyPanel* thePanel)
+: myPanel(thePanel), myWidgetToBeActivated (NULL)
+{
+ connect(myPanel, SIGNAL(propertyPanelActivated()), this, SIGNAL(activated()));
+ connect(myPanel, SIGNAL(propertyPanelDeactivated()), this, SIGNAL(deactivated()));
+}
+
+//********************************************************************
+void XGUI_PropertyPanelSelector::reset()
+{
+ myWidgetToBeActivated = NULL;
+}
+
+//********************************************************************
+void XGUI_PropertyPanelSelector::setActive(const bool& isActive)
+{
+ if (isActive && myWidgetToBeActivated) {
+ // e.g. widget sketch label
+ myPanel->activateWidget(myWidgetToBeActivated, true);
+ myWidgetToBeActivated = NULL;
+ return;
+ }
+
+ if (!isActive) { // on deactivating, store previous active widget
+ ModuleBase_ModelWidget* aWidget = myPanel->activeWidget();
+ if (aWidget && aWidget->needToBeActiated())
+ {
+ myWidgetToBeActivated = aWidget;
+ }
+ myPanel->activateWidget(NULL, false);
+ }
+}
+
+//********************************************************************
+bool XGUI_PropertyPanelSelector::needToBeActiated() const
+{
+ return myWidgetToBeActivated != NULL;
+}
+
+//********************************************************************
+void XGUI_PropertyPanelSelector::processSelection()
+{
+ ModuleBase_ModelWidget* aWidget = myPanel->activeWidget();
+ if (!aWidget)
+ return;
+
+ aWidget->processAction(ActionSelection);
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_PropertyPanelSelector_H
+#define XGUI_PropertyPanelSelector_H
+
+#include "XGUI.h"
+
+#include <XGUI_ActiveControlSelector.h>
+
+class ModuleBase_ModelWidget;
+class XGUI_PropertyPanel;
+
+/**
+* Processing selection by the property panel.
+*/
+class XGUI_PropertyPanelSelector : public XGUI_ActiveControlSelector
+{
+ Q_OBJECT
+
+public:
+ /// Constructor
+ /// \param thePanel the workshop property panel
+ XGUI_EXPORT XGUI_PropertyPanelSelector(XGUI_PropertyPanel* thePanel);
+ /// Destructor
+ XGUI_EXPORT virtual ~XGUI_PropertyPanelSelector() {};
+
+ /// Returns name of the selector
+ XGUI_EXPORT static QString Type() { return "XGUI_PropertyPanelSelector"; }
+
+ /// Returns name of the selector
+ XGUI_EXPORT virtual QString getType() { return Type(); }
+
+ /// Clear need to be activated widget if it exists
+ XGUI_EXPORT virtual void reset();
+
+ /// Sets control active. It should activates/deactivates selection and selection filters.
+ /// \param isActive if true, the control becomes active
+ XGUI_EXPORT virtual void setActive(const bool& isActive);
+
+ /// Returns whether the selector should be activated as soon as possible (by deactivatate other)
+ /// \return boolean result
+ XGUI_EXPORT virtual bool needToBeActiated() const;
+
+ /// Processes current selection of workshop. Reaction to selection change in workshop.
+ XGUI_EXPORT virtual void processSelection();
+
+protected:
+ XGUI_PropertyPanel* myPanel; ///< processed panel
+ ModuleBase_ModelWidget* myWidgetToBeActivated; ///< used as need to be activated back
+
+};
+
+#endif
/**
* \ingroup GUI
- * An interface which provides a connection of XGUI functionality
+ * An interface which provides a connection of XGUI functionality
* with functionality of SALOME module interface.
*/
class XGUI_EXPORT XGUI_SalomeConnector
#include "XGUI_ViewerProxy.h"
#include "XGUI_ObjectsBrowser.h"
+#include "ModuleBase_BRepOwner.h"
#include "ModuleBase_ResultPrs.h"
-#include <ModuleBase_ViewerPrs.h>
+#include "ModuleBase_ViewerPrs.h"
#include <ModelAPI_Feature.h>
#include <ModelAPI_Tools.h>
return QObjectPtrList();
}
-void XGUI_Selection::setSelectedObjects( const QObjectPtrList& theObjects ) const
-{
- return myWorkshop->objectBrowser()->setObjectsSelected( theObjects );
-}
-
QObjectPtrList XGUI_Selection::selectedPresentations() const
{
QObjectPtrList aSelectedList;
return myWorkshop->objectBrowser()->selectedIndexes();
}
-//**************************************************************
-void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const
-{
- theList.Clear();
-
- Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
- if (!aContext.IsNull()) {
- for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
- theList.Append(aContext->SelectedInteractive());
- }
-}
-
//**************************************************************
ObjectPtr XGUI_Selection::getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const
{
class SelectMgr_EntityOwner;
class ModuleBase_ViewerPrs;
-/**
-* \ingroup GUI
-* Implementation of \ref ModuleBase_ISelection interface.
-*/
+/// \ingroup GUI
+/// Implementation of \ref ModuleBase_ISelection interface.
class XGUI_EXPORT XGUI_Selection : public ModuleBase_ISelection
{
public:
/// \return list of presentations
virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getHighlighted() const;
- /**
- * Returns list of currently selected objects in object browser
- */
+ /// Returns list of currently selected objects in object browser
virtual QObjectPtrList selectedObjects() const;
- virtual void setSelectedObjects( const QObjectPtrList& ) const;
-
- /**
- * Returns list of currently selected results
- */
+ /// Returns list of currently selected results
virtual QObjectPtrList selectedPresentations() const;
- //! Returns list of currently selected QModelIndexes
+ /// Returns list of currently selected QModelIndexes
virtual QModelIndexList selectedIndexes() const;
- //! Returns list of currently selected QModelIndexes
- ObjectPtr getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner);
-
- //! Returns list of currently selected AIS objects
- virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const;
-
- //! Return a selectable object by the entity owner. It founds AIS object in the viewer
- //! and returns the corresponded object
- /// \param theOwner an entity owner
- /// \return a found object or NULL
- ObjectPtr getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const;
-
- //! Returns list of currently selected owners
+ /// Returns list of currently selected owners
/// \return list of owners
void selectedOwners(SelectMgr_IndexedMapOfOwner& theSelectedOwners) const;
- //! Returns a list of selection entity owners of the interactive object
+ /// Returns a list of selection entity owners of the interactive object
/// It depends on the modes, in which the object is activated in the context
/// \param theObject an object
/// \param theOwners a map of entity owners
void entityOwners(const Handle_AIS_InteractiveObject& theObject,
SelectMgr_IndexedMapOfOwner& theOwners) const;
- //! Return the IO from the viewer presentation.
- //! \param thePrs a selected object
- //! \return an interactive object
+ /// Return the IO from the viewer presentation.
+ /// \param thePrs a selected object
+ /// \return an interactive object
virtual Handle(AIS_InteractiveObject) getIO(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
protected:
+ /// Return a selectable object by the entity owner. It founds AIS object in the viewer
+ /// and returns the corresponded object
+ /// \param theOwner an entity owner
+ /// \return a found object or NULL
+ ObjectPtr getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const;
+
/// Fills the list of presentations by objects selected in the viewer.
/// \param thePresentations an output list of presentation
void getSelectedInViewer(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& thePresentations) const;
+
/// Fills the list of presentations by objects selected in the object browser.
/// ViewerPrs contains only object parameter not empty.
/// If the given list of presentations already has a viewer presentation with the same object
#endif
private:
- XGUI_Workshop* myWorkshop;
+ XGUI_Workshop* myWorkshop; ///< current workshop
};
#endif
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "XGUI_SelectionActivate.h"
+
+#include "ModelAPI_Object.h"
+
+#include "ModuleBase_IModule.h"
+#include "ModuleBase_IViewer.h"
+#include "ModuleBase_ModelWidget.h"
+#include "ModuleBase_Preferences.h"
+
+#include "XGUI_ActiveControlMgr.h"
+#include "XGUI_ActiveControlSelector.h"
+#include "XGUI_Displayer.h"
+#include "XGUI_FacesPanel.h"
+#include "XGUI_FacesPanelSelector.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_Workshop.h"
+
+#include <SUIT_ResourceMgr.h>
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_Shape.hxx>
+#include <AIS_Trihedron.hxx>
+
+#include <SelectMgr_SelectionManager.hxx>
+
+//#define DEBUG_ACTIVATE_OBJECTS
+//#define DEBUG_DEACTIVATE
+//#define DEBUG_ACTIVATE_AIS
+//#define DEBUG_DEACTIVATE_AIS
+
+#define CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
+
+//**************************************************************
+XGUI_SelectionActivate::XGUI_SelectionActivate(ModuleBase_IWorkshop* theWorkshop)
+ : ModuleBase_ISelectionActivate(theWorkshop), myIsTrihedronActive(true)
+{
+}
+
+//**************************************************************
+XGUI_SelectionActivate::SelectionPlace XGUI_SelectionActivate::activeSelectionPlace() const
+{
+ XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
+ XGUI_ActiveControlSelector* anActiveSelector = aWorkshop->activeControlMgr()->activeSelector();
+ if (!anActiveSelector)
+ return Workshop;
+
+ if (anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
+ return FacesPanel;
+ else
+ return PropertyPanel;
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::updateSelectionModes()
+{
+ QIntList aModes;
+ switch (activeSelectionPlace()) {
+ case Workshop:
+ myWorkshop->module()->activeSelectionModes(aModes);
+ break;
+ case PropertyPanel: {
+ ModuleBase_ModelWidget* anActiveWidget = myWorkshop->module()->activeWidget();
+ if (anActiveWidget)
+ getSelectionModes(anActiveWidget, aModes);
+ else
+ myWorkshop->module()->activeSelectionModes(aModes); //using module modes
+ }
+ break;
+ case FacesPanel: {
+ XGUI_Tools::workshop(myWorkshop)->facesPanel()->selectionModes(aModes);
+ myWorkshop->module()->moduleSelectionModes(-1/*all modes*/, aModes);
+ }
+ break;
+ default: break;
+ }
+ activateObjects(aModes, getDisplayer()->displayedObjects(), true);
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::updateSelectionFilters()
+{
+ SelectMgr_ListOfFilter aSelectionFilters;
+ switch (activeSelectionPlace()) {
+ case Workshop: {
+ QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
+ myWorkshop->module()->moduleSelectionFilters(aModuleSelectionFilters, aSelectionFilters);
+ }
+ break;
+ case PropertyPanel: {
+ QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
+
+ ModuleBase_ModelWidget* anActiveWidget = myWorkshop->module()->activeWidget();
+ if (anActiveWidget)
+ anActiveWidget->selectionFilters(aModuleSelectionFilters, aSelectionFilters);
+ myWorkshop->module()->moduleSelectionFilters(aModuleSelectionFilters, aSelectionFilters);
+ }
+ break;
+ case FacesPanel: {
+ XGUI_Tools::workshop(myWorkshop)->facesPanel()->selectionFilters(aSelectionFilters);
+ //QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
+ //myWorkshop->module()->moduleSelectionFilters(aModuleSelectionFilters, aSelectionFilters);
+ }
+ break;
+ default: break;
+ }
+ activateSelectionFilters(aSelectionFilters);
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::activateSelectionFilters
+ (const SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ XGUI_Displayer* aDisplayer = getDisplayer();
+ aDisplayer->deactivateSelectionFilters(false);
+
+ SelectMgr_ListIteratorOfListOfFilter aIt(theSelectionFilters);
+ for (; aIt.More(); aIt.Next()) {
+ Handle(SelectMgr_Filter) aFilter = aIt.Value();
+ if (aFilter.IsNull())
+ continue;
+ aDisplayer->addSelectionFilter(aFilter);
+ }
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::getSelectionModes(ModuleBase_ModelWidget* theWidget,
+ QIntList& theModes)
+{
+ if (!theWidget)
+ return;
+
+ int aModuleSelectionModes = -1;
+ theWidget->selectionModes(aModuleSelectionModes, theModes);
+ myWorkshop->module()->moduleSelectionModes(aModuleSelectionModes, theModes);
+}
+
+//**************************************************************
+QIntList XGUI_SelectionActivate::activeSelectionModes() const
+{
+ QIntList aModes;
+ foreach (int aMode, myActiveSelectionModes) {
+ // aMode < 9 is a Shape Enum values
+ aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode);
+ }
+ return aModes;
+}
+
+//**************************************************************
+bool XGUI_SelectionActivate::isActive(ObjectPtr theObject) const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (aContext.IsNull() || !getDisplayer()->isVisible(theObject))
+ return false;
+
+ AISObjectPtr anObj = getDisplayedAISObject(theObject);
+ Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
+
+ TColStd_ListOfInteger aModes;
+ aContext->ActivatedModes(anAIS, aModes);
+
+ return aModes.Extent() > 0;
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::activateObjects(const QIntList& theModes,
+ const QObjectPtrList& theObjList, const bool theUpdateViewer)
+{
+ setSelectionModes(theModes);
+
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ // Open local context if there is no one
+ if (aContext.IsNull())
+ return;
+
+ //aContext->UseDisplayedObjects();
+ //myUseExternalObjects = true;
+
+ Handle(AIS_InteractiveObject) anAISIO;
+ AIS_ListOfInteractive aPrsList;
+ AIS_ListOfInteractive aPrsListToBeDeactivated;
+ //if (aObjList.isEmpty())
+ // return;
+ //else {
+ foreach(ObjectPtr anObject, theObjList) {
+ AISObjectPtr anAISObject = getDisplayedAISObject(anObject);
+ if (!anAISObject.get())
+ continue;
+
+ Handle(AIS_InteractiveObject) aPrs = anAISObject->impl<Handle(AIS_InteractiveObject)>();
+ if (myWorkshop->module()->canActivateSelection(anObject))
+ aPrsList.Append(aPrs);
+ else
+ aPrsListToBeDeactivated.Append(aPrs);
+ }
+ //}
+
+ // Add trihedron because it has to partisipate in selection
+ Handle(AIS_InteractiveObject) aTrihedron;
+ if (isTrihedronActive()) {
+ aTrihedron = getTrihedron();
+ if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron))
+ aPrsList.Append(aTrihedron);
+ }
+ if (aPrsList.Extent() == 0 && aPrsListToBeDeactivated.Extent() == 0)
+ return;
+
+ AIS_ListIteratorOfListOfInteractive aLIt;
+ bool isActivationChanged = false;
+ for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()) {
+ anAISIO = aLIt.Value();
+ if (activate(anAISIO, false))
+ isActivationChanged = true;
+ }
+
+ for(aLIt.Initialize(aPrsListToBeDeactivated); aLIt.More(); aLIt.Next()) {
+ anAISIO = aLIt.Value();
+ deactivateAIS(anAISIO);
+ isActivationChanged = true;
+ }
+}
+
+#ifdef DEBUG_ACTIVATE_OBJECTS
+//**************************************************************
+QString getModeInfo(const int theMode)
+{
+ QString anInfo = "Undefined";
+ switch(theMode) {
+ case 0: anInfo = "SHAPE(0)"; break;
+ case 1: anInfo = "VERTEX(1)"; break;
+ case 2: anInfo = "EDGE(2)"; break;
+ case 3: anInfo = "WIRE(3)"; break;
+ case 4: anInfo = "FACE(4)"; break;
+ case 5: anInfo = "SHELL(5)"; break;
+ case 6: anInfo = "SOLID(6)"; break;
+ case 7: anInfo = "COMPSOLID(7)"; break;
+ case 8: anInfo = "COMPOUND(8)"; break;
+ case 100: anInfo = "Sel_Mode_First(100)"; break; //SketcherPrs_Tools
+ case 101: anInfo = "Sel_Constraint(101)"; break;
+ case 102: anInfo = "Sel_Dimension_All(102)"; break;
+ case 103: anInfo = "Sel_Dimension_Line(103)"; break;
+ case 104: anInfo = "Sel_Dimension_Text(104)"; break;
+ default: break;
+ }
+ return anInfo;
+}
+
+//**************************************************************
+QString getModesInfo(const QIntList& theModes)
+{
+ QStringList aModesInfo;
+ for (int i = 0, aSize = theModes.size(); i < aSize; i++)
+ aModesInfo.append(getModeInfo(theModes[i]));
+ return QString("[%1] = %2").arg(aModesInfo.size()).arg(aModesInfo.join(", "));
+}
+#endif
+
+//**************************************************************
+void XGUI_SelectionActivate::setSelectionModes(const QIntList& theModes)
+{
+ // Convert shape types to selection types
+ QIntList aModes;
+ foreach(int aType, theModes) {
+ aModes.append(getSelectionMode(aType));
+ }
+
+#ifdef DEBUG_ACTIVATE_OBJECTS
+ QStringList anInfo;
+ QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end();
+ for (; anIt != aLast; ++anIt) {
+ anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
+ }
+ QString anInfoStr = anInfo.join(", ");
+
+ qDebug(QString("activateObjects: new modes%1, active modes%2, objects[%3] = %4").
+ arg(getModesInfo(aModes)).
+ arg(getModesInfo(myActiveSelectionModes)).
+ arg(theObjList.size()).
+ arg(anInfoStr).
+ toStdString().c_str());
+#endif
+ // In order to avoid doblications of selection modes
+ QIntList aNewModes;
+ foreach (int aMode, aModes) {
+ if (!aNewModes.contains(aMode))
+ aNewModes.append(aMode);
+ }
+ myActiveSelectionModes = aNewModes;
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::activateOnDisplay(const Handle(AIS_InteractiveObject)& theIO,
+ const bool theUpdateViewer)
+{
+ if (myActiveSelectionModes.size() == 0)
+ activateAIS(theIO, 0, theUpdateViewer);
+ else {
+ foreach(int aMode, myActiveSelectionModes) {
+ activateAIS(theIO, aMode, theUpdateViewer);
+ }
+ }
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::activateAIS(const Handle(AIS_InteractiveObject)& theIO,
+ const int theMode, const bool theUpdateViewer) const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!theIO.IsNull() && theIO == getTrihedron()) {
+ if (theMode != AIS_Shape::SelectionType(TopAbs_EDGE) &&
+ theMode != AIS_Shape::SelectionType(TopAbs_VERTEX))
+ return;
+ }
+ if (!aContext.IsNull()) {
+ if (myWorkshop->module()) {
+ int aMode = (theMode > 8)? theMode : AIS_Shape::SelectionType(theMode);
+ aContext->Activate(theIO, theMode, false);
+ } else
+ aContext->Activate(theIO, theMode, false);
+
+ // the fix from VPA for more suitable selection of sketcher lines
+ if (theIO->Width() > 1) {
+ double aPrecision = theIO->Width() + 2;
+ if (theMode == getSelectionMode(TopAbs_VERTEX))
+ aPrecision = ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
+ "point-selection-sensitivity", 12);
+ else if ((theMode == getSelectionMode(TopAbs_EDGE)) ||
+ (theMode == getSelectionMode(TopAbs_WIRE)))
+ aPrecision = theIO->Width() + ModuleBase_Preferences::resourceMgr()->doubleValue("Viewer",
+ "edge-selection-sensitivity", 2);
+ aContext->SetSelectionSensitivity(theIO, theMode, aPrecision);
+ }
+
+#ifdef DEBUG_ACTIVATE_AIS
+ ObjectPtr anObject = getObject(theIO);
+ anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
+ qDebug(QString("activateAIS: theMode = %1, object = %2").arg(theMode)
+ .arg(anInfo).toStdString().c_str());
+#endif
+ if (theUpdateViewer)
+ getDisplayer()->updateViewer();
+ }
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO,
+ const int theMode) const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ if (theMode == -1)
+ aContext->Deactivate(theIO);
+ else
+ aContext->Deactivate(theIO, theMode);
+
+#ifdef DEBUG_DEACTIVATE_AIS
+ ObjectPtr anObject = getObject(theIO);
+ anInfo.append(ModuleBase_Tools::objectInfo((*anIt)));
+ qDebug(QString("deactivateAIS: theMode = %1, object = %2").arg(theMode)
+ .arg(anInfo).toStdString().c_str());
+#endif
+ }
+}
+
+//**************************************************************
+bool XGUI_SelectionActivate::activate(const Handle(AIS_InteractiveObject)& theIO,
+ const bool theUpdateViewer) const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (aContext.IsNull() || theIO.IsNull())
+ return false;
+
+ bool isActivationChanged = false;
+ // deactivate object in all modes, which are not in the list of activation
+ // It seems that after the IO deactivation the selected state of the IO's owners
+ // is modified in OCC(version: 6.8.0) and the selection of the object later is lost.
+ // By this reason, the number of the IO deactivate is decreased and the object is deactivated
+ // only if there is a difference in the current modes and the parameters modes.
+ // If the selection problem happens again, it is possible to write a test scenario and create
+ // a bug. The bug steps are the following:
+ // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both,
+ // with clicked SHIFT select the second object.
+ // The result is the selection of the first IO is lost.
+ TColStd_ListOfInteger aTColModes;
+ aContext->ActivatedModes(theIO, aTColModes);
+ TColStd_ListIteratorOfListOfInteger itr( aTColModes );
+ QIntList aModesActivatedForIO;
+ bool isDeactivated = false;
+ bool aHasValidMode = false;
+ for (; itr.More(); itr.Next() ) {
+ Standard_Integer aMode = itr.Value();
+ aHasValidMode = aHasValidMode || aMode != -1;
+ int aShapeMode = (aMode > 8)? aMode : AIS_Shape::SelectionType(aMode);
+ if (!myActiveSelectionModes.contains(aMode)) {
+ deactivateAIS(theIO, aMode);
+ isDeactivated = true;
+ }
+ else {
+ aModesActivatedForIO.append(aMode);
+ }
+ }
+ if (isDeactivated) {
+ // the selection from the previous activation modes should be cleared manually (#26172)
+ //theIO->ClearSelected();
+#ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
+ XGUI_Tools::workshop(myWorkshop)->selector()->deselectPresentation(theIO);
+#endif
+ // For performance issues
+ //if (theUpdateViewer)
+ // getDisplayer()->updateViewer();
+ isActivationChanged = true;
+ }
+
+ // loading the interactive object allowing the decomposition
+ if (aTColModes.IsEmpty() || !aHasValidMode) {
+ aContext->Load(theIO, -1, true);
+ Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
+ if (!aTrihedron.IsNull()) {
+ // Workaround for Trihedron. It should be loaded using the next Load method to
+ // add this object to myGlobal map of selection manager
+ // it is important to activate trihedron in two selection modes: edges and vertices
+ aContext->SelectionManager()->Load(theIO);
+ }
+ }
+
+ // trihedron AIS check should be after the AIS loading.
+ // If it is not loaded, it is steel selectable in the viewer.
+ Handle(AIS_Trihedron) aTrihedron;
+ if (!isTrihedronActive())
+ aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
+ if (aTrihedron.IsNull()) {
+ // In order to clear active modes list
+ if (myActiveSelectionModes.size() == 0) {
+ activateAIS(theIO, 0, theUpdateViewer);
+ } else {
+ foreach(int aMode, myActiveSelectionModes) {
+ if (!aModesActivatedForIO.contains(aMode)) {
+ activateAIS(theIO, aMode, theUpdateViewer);
+ isActivationChanged = true;
+ }
+ }
+ }
+ }
+ return isActivationChanged;
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::deactivate(const ObjectPtr& theObject, const bool theUpdateViewer)
+{
+#ifdef DEBUG_DEACTIVATE
+ QString anInfoStr = ModuleBase_Tools::objectInfo(theObject);
+ qDebug(QString("deactivate: myActiveSelectionModes[%1]: %2, objects = ").
+ arg(myActiveSelectionModes.size()).arg(qIntListInfo(myActiveSelectionModes)).
+ arg(anInfoStr).
+ toStdString().c_str());
+#endif
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull() && getDisplayer()->isVisible(theObject)) {
+ AISObjectPtr anObj = getDisplayedAISObject(theObject);
+ Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
+
+ deactivateAIS(anAIS);
+ // the selection from the previous activation modes should be cleared manually (#26172)
+#ifndef CLEAR_OUTDATED_SELECTION_BEFORE_REDISPLAY
+ XGUI_Tools::workshop(myWorkshop)->selector()->deselectPresentation(anAIS);
+#endif
+ if (theUpdateViewer)
+ getDisplayer()->updateViewer();
+ }
+}
+
+/// #1136 hidden axis are selected in sketch
+#ifdef BEFORE_TRIHEDRON_PATCH
+//**************************************************************
+void deactivateObject(Handle(AIS_InteractiveContext) theContext,
+ Handle(AIS_InteractiveObject) theObject)
+{
+ if (!theObject.IsNull())
+ theContext->Deactivate(theObject);
+}
+#endif
+
+//**************************************************************
+void XGUI_SelectionActivate::activateTrihedron(bool theIsActive)
+{
+ myIsTrihedronActive = theIsActive;
+ if (!myIsTrihedronActive)
+ deactivateTrihedron(true);
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::deactivateTrihedron(const bool theUpdateViewer) const
+{
+ Handle(AIS_InteractiveObject) aTrihedron = getTrihedron();
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aTrihedron.IsNull() && aContext->IsDisplayed(aTrihedron)) {
+ Handle(AIS_Trihedron) aTrie = Handle(AIS_Trihedron)::DownCast(aTrihedron);
+ if (!aTrie.IsNull())
+ aContext->Deactivate(aTrie);
+
+ /// #1136 hidden axis are selected in sketch
+#ifdef BEFORE_TRIHEDRON_PATCH
+ deactivateObject(aContext, aTrie->XAxis());
+ deactivateObject(aContext, aTrie->YAxis());
+ deactivateObject(aContext, aTrie->Axis());
+ deactivateObject(aContext, aTrie->Position());
+
+ deactivateObject(aContext, aTrie->XYPlane());
+ deactivateObject(aContext, aTrie->XZPlane());
+ deactivateObject(aContext, aTrie->YZPlane());
+#endif
+ if (theUpdateViewer)
+ getDisplayer()->updateViewer();
+ }
+}
+
+//**************************************************************
+void XGUI_SelectionActivate::deactivateTrihedronInSelectionModes()
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(getTrihedron());
+ /// deactivate trihedron in selection modes
+ TColStd_ListOfInteger aTColModes;
+ aContext->ActivatedModes(aTrihedron, aTColModes);
+ TColStd_ListIteratorOfListOfInteger itr( aTColModes );
+ for (; itr.More(); itr.Next() ) {
+ Standard_Integer aMode = itr.Value();
+ aContext->Deactivate(aTrihedron, aMode);
+ }
+}
+
+//**************************************************************
+Handle(AIS_InteractiveContext) XGUI_SelectionActivate::AISContext() const
+{
+ return myWorkshop->viewer()->AISContext();
+}
+
+//**************************************************************
+XGUI_Displayer* XGUI_SelectionActivate::getDisplayer() const
+{
+ return XGUI_Tools::workshop(myWorkshop)->displayer();
+}
+
+//**************************************************************
+Handle(AIS_InteractiveObject) XGUI_SelectionActivate::getTrihedron() const
+{
+ return myWorkshop->viewer()->trihedron();
+}
+
+//**************************************************************
+AISObjectPtr XGUI_SelectionActivate::getDisplayedAISObject(ObjectPtr theObject) const
+{
+ return getDisplayer()->getAISObject(theObject);
+}
+
+//**************************************************************
+int XGUI_SelectionActivate::getSelectionMode(int theShapeType)
+{
+ return (theShapeType > TopAbs_SHAPE) ? theShapeType :
+ AIS_Shape::SelectionMode((TopAbs_ShapeEnum)theShapeType);
+}
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_ISelectionActivate_H
+#define XGUI_ISelectionActivate_H
+
+#include "XGUI.h"
+
+#include "ModuleBase_Definitions.h"
+#include "ModuleBase_ISelectionActivate.h"
+
+#include "SelectMgr_ListOfFilter.hxx"
+
+#include <memory>
+
+class AIS_InteractiveContext;
+class AIS_InteractiveObject;
+class ModelAPI_Object;
+
+class XGUI_Displayer;
+
+/// \ingroup GUI
+/// A class which implements activation/deactivate selection modes and using selection filters.
+class XGUI_SelectionActivate : public ModuleBase_ISelectionActivate
+{
+public:
+ /// Types of the activation place
+ enum SelectionPlace { Workshop, PropertyPanel, FacesPanel };
+
+public:
+ /// Constructor
+ XGUI_EXPORT XGUI_SelectionActivate(ModuleBase_IWorkshop* theWorkshop);
+
+ /// Destructor
+ ~XGUI_SelectionActivate() {}
+
+ /// Returns place of activation modes that now is active
+ /// \return place
+ SelectionPlace activeSelectionPlace() const;
+
+ /// Updates active selection modes in the viewer depending on the application state
+ XGUI_EXPORT virtual void updateSelectionModes();
+
+ /// Updates active selection filters in the viewer depending on the application state
+ XGUI_EXPORT virtual void updateSelectionFilters();
+
+ /// Activates parameter filters in the workshop, deactivate active out of the container
+ /// Please find a possibility to use updateSelectionFilters instead of direct call this method.
+ /// \param theSelectionFilters a filtes
+ XGUI_EXPORT virtual void activateSelectionFilters
+ (const SelectMgr_ListOfFilter& theSelectionFilters);
+
+ /// Returns list of currently active selection modes
+ /// Selection modes will be returned according to TopAbs_ShapeEnum
+ XGUI_EXPORT QIntList activeSelectionModes() const;
+
+ /// Returns true if the given object can be selected
+ /// \param theObject object to check
+ XGUI_EXPORT bool isActive(ObjectPtr theObject) const;
+
+ /// Activates in local context displayed outside of the context.
+ /// \param theModes - modes on which it has to be activated (can be empty)
+ /// \param theObjList - list of objects which has to be activated.
+ /// \param theUpdateViewer an update viewer flag
+ XGUI_EXPORT void activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList,
+ const bool theUpdateViewer = true);
+
+ /// Fill container of current selection modes
+ /// \param theModes selection modes
+ XGUI_EXPORT void setSelectionModes(const QIntList& theModes);
+
+ /// Activate object in the selection modes
+ /// \param theIO an object
+ /// \param theUpdateViewer an update viewer flag
+ XGUI_EXPORT void activateOnDisplay(const Handle(AIS_InteractiveObject)& theIO,
+ const bool theUpdateViewer);
+
+ /// Activate interactive object
+ /// \param theIO an interactive object
+ /// \param theMode activation mode
+ /// \param theUpdateViewer update viewer flag
+ XGUI_EXPORT void activateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode,
+ const bool theUpdateViewer) const;
+
+ /// Activate interactive object. It is necessary to call ClearOutdatedSelection
+ /// after deactivation
+ /// \param theIO an interactive object
+ /// \param theMode a mode to deactivate. When theMode=-1 then all modes will be deactivated
+ XGUI_EXPORT void deactivateAIS(const Handle(AIS_InteractiveObject)& theIO,
+ const int theMode = -1) const;
+
+ /// Activates the interactive object in the local context.
+ /// \param theIO an interactive object
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
+ /// \return a flag is object activated or not
+ XGUI_EXPORT bool activate(const Handle(AIS_InteractiveObject)& theIO,
+ const bool theUpdateViewer) const;
+
+ /// Deactivates the given object (not allow selection)
+ /// \param theObject object to deactivate
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
+ XGUI_EXPORT void deactivate(const std::shared_ptr<ModelAPI_Object>& theObject,
+ const bool theUpdateViewer);
+
+ /// Returns true if the trihedron should be activated in current selection modes
+ bool isTrihedronActive() const { return myIsTrihedronActive; }
+
+ /// Set trihedron active (used in selection) or non active
+ XGUI_EXPORT void activateTrihedron(bool theIsActive);
+
+ /// Find a trihedron in a list of displayed presentations and deactivate it.
+ /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
+ XGUI_EXPORT void deactivateTrihedron(const bool theUpdateViewer) const;
+
+ /// Get selection modes of trihedron and deactivate it in it.
+ XGUI_EXPORT void deactivateTrihedronInSelectionModes();
+
+protected:
+ /// Returns selection modes of the widget
+ /// \param theWidget model widget
+ /// \param theModes selection modes
+ void getSelectionModes(ModuleBase_ModelWidget* theWidget, QIntList& theModes);
+
+ /// Returns Trihedron object if it is displayed
+ Handle(AIS_InteractiveObject) getTrihedron() const;
+
+ /// Returns context of the 3D viewer
+ /// \return context instance
+ Handle(AIS_InteractiveContext) AISContext() const;
+
+ /// Returns displayer
+ /// \return displayer
+ XGUI_Displayer* getDisplayer() const;
+
+ /// Returns AIS object displayed in 3D viewer for the given model object
+ /// \param theObject source object
+ /// \returns interactive object
+ AISObjectPtr getDisplayedAISObject(std::shared_ptr<ModelAPI_Object> theObject) const;
+
+ /// Converts shape type (TopAbs_ShapeEnum) to selection mode
+ /// \param theShapeType a shape type from TopAbs_ShapeEnum
+ static int getSelectionMode(int theShapeType);
+
+protected:
+ QIntList myActiveSelectionModes; ///< Current activated selection modes
+ bool myIsTrihedronActive; ///< Flag: use trihedgon for selection or not
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2014-2017 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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef XGUI_SelectionFilterType_H
+#define XGUI_SelectionFilterType_H
+
+#include "XGUI.h"
+
+/// Enumeration to specify module selection filters
+enum XGUI_EXPORT XGUI_SelectionFilterType {
+ SF_GlobalFilter, /// filter for different documents, group results
+ SF_FilterInfinite, /// filter for infinite construction results
+ SF_ResultGroupNameFilter, /// filter for selection some kind of results
+ SF_SketchCirclePointFilter, /// filter for selection circle points on current sketch
+ SF_SketchPlaneFilter /// filter for selection in the current sketch plane only
+};
+
+#endif
emit selectionChanged();
}
+//**************************************************************
+void XGUI_SelectionMgr::deselectPresentation(const Handle(AIS_InteractiveObject) theObject)
+{
+ NCollection_List<Handle(SelectBasics_EntityOwner)> aResultOwners;
+
+ Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+ for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
+ Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
+ if (anOwner.IsNull()) // TODO: check why it is possible
+ continue;
+ if (anOwner->Selectable() == theObject && anOwner->IsSelected())
+ aResultOwners.Append(anOwner);
+ }
+ NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (aResultOwners);
+ Handle(SelectMgr_EntityOwner) anOwner;
+ for (; anOwnersIt.More(); anOwnersIt.Next()) {
+ anOwner = Handle(SelectMgr_EntityOwner)::DownCast(anOwnersIt.Value());
+ if (!anOwner.IsNull())
+ aContext->AddOrRemoveSelected(anOwner, false);
+ }
+}
+
//**************************************************************
void XGUI_SelectionMgr::updateSelectionBy(const ModuleBase_ISelection::SelectionPlace& thePlace)
{
}
}
}
+
+std::list<FeaturePtr> XGUI_SelectionMgr::getSelectedFeatures()
+{
+ std::list<FeaturePtr> aFeatures;
+ QObjectPtrList aObjects = selection()->selectedObjects();
+ if (aObjects.isEmpty())
+ return aFeatures;
+
+ bool isPart = false;
+ foreach(ObjectPtr aObj, aObjects) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+ if (aFeature.get()) {
+ ResultPtr aRes = aFeature->firstResult();
+ isPart = (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group()));
+ if (!isPart)
+ aFeatures.push_back(aFeature);
+ }
+ }
+ return aFeatures;
+}
\ No newline at end of file
#include "XGUI.h"
#include <ModuleBase_Definitions.h>
#include <ModuleBase_ISelection.h>
+#include <ModelAPI_Feature.h>
#include <QObject>
#include <QModelIndexList>
+#include <AIS_InteractiveObject.hxx>
#include <AIS_ListOfInteractive.hxx>
#include <NCollection_List.hxx>
#include <TopoDS_Shape.hxx>
//! \param theValues a container of values to be selected.
void setSelected(const QList<std::shared_ptr<ModuleBase_ViewerPrs> >& theValues);
+ //! Find all selected owners of the object and remove the owners from selection
+ //! \param theObject an interactive object
+ void deselectPresentation(const Handle(AIS_InteractiveObject) theObject);
+
/// Updates selection, which are depend on the selection in the given place
/// \param thePlace a widget where selection has happened.
void updateSelectionBy(const ModuleBase_ISelection::SelectionPlace& thePlace);
+ /// Returns list of selected features (ignores other selected objects and parts)
+ std::list<FeaturePtr> getSelectedFeatures();
+
signals:
//! Emited when selection in a one of viewers was changed
void selectionChanged();
#include "XGUI_Workshop.h"
#include "XGUI_ActionsMgr.h"
+#include "XGUI_ActiveControlMgr.h"
+#include "XGUI_ActiveControlSelector.h"
#include "XGUI_MenuMgr.h"
#include "XGUI_ColorDialog.h"
#include "XGUI_DeflectionDialog.h"
#include "XGUI_Displayer.h"
#include "XGUI_ErrorDialog.h"
#include "XGUI_ErrorMgr.h"
+#include "XGUI_FacesPanel.h"
+#include "XGUI_FacesPanelSelector.h"
#include "XGUI_ModuleConnector.h"
#include "XGUI_ObjectsBrowser.h"
#include "XGUI_OperationMgr.h"
#include "XGUI_PropertyPanel.h"
+#include "XGUI_PropertyPanelSelector.h"
#include "XGUI_PropertyDialog.h"
#include "XGUI_SalomeConnector.h"
#include "XGUI_Selection.h"
+#include "XGUI_SelectionActivate.h"
#include "XGUI_SelectionMgr.h"
#include "XGUI_Tools.h"
#include "XGUI_ViewerProxy.h"
#include <ModelAPI_Feature.h>
#include <ModelAPI_Object.h>
#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_ResultGroup.h>
#include <ModelAPI_ResultParameter.h>
#include <ModelAPI_ResultField.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_Tools.h>
//#include <PartSetPlugin_Part.h>
#include <ModuleBase_WidgetValidated.h>
#include <ModuleBase_ModelWidget.h>
#include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_ActionIntParameter.h>
#include <Config_Common.h>
#include <Config_FeatureMessage.h>
#include <dlfcn.h>
#endif
+//#define DEBUG_WITH_MESSAGE_REPORT
+
QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end");
//#define DEBUG_DELETE
//#define DEBUG_FEATURE_NAME
//#define DEBUG_CLEAN_HISTORY
+//******************************************************
XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
: QObject(),
myCurrentDir(QString()),
myModule(NULL),
mySalomeConnector(theConnector),
myPropertyPanel(0),
+ myFacesPanel(0),
myObjectBrowser(0),
myDisplayer(0)
//myViewerSelMode(TopAbs_FACE)
ModuleBase_IWorkshop* aWorkshop = moduleConnector();
// Has to be defined first in order to get errors and messages from other components
myEventsListener = new XGUI_WorkshopListener(aWorkshop);
+ mySelectionActivate = new XGUI_SelectionActivate(aWorkshop);
SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
#ifndef HAVE_SALOME
connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateCommandStatus()));
myActionsMgr = new XGUI_ActionsMgr(this);
+ myActiveControlMgr = new XGUI_ActiveControlMgr(myModuleConnector);
myMenuMgr = new XGUI_MenuMgr(this);
myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop());
myContextMenuMgr = new XGUI_ContextMenuMgr(this);
#ifdef _DEBUG
Config_PropManager::registerProp("Plugins", "create_part_by_start", "Create Part by Start",
Config_Prop::Boolean, "false");
+
+ Config_PropManager::registerProp("Plugins", "show_hide_faces", "Show Hide Faces (on the right)",
+ Config_Prop::Boolean, "false");
#endif
registerValidators();
#endif
}
+//******************************************************
void XGUI_Workshop::activateModule()
{
- myModule->activateSelectionFilters();
+ selectionActivate()->updateSelectionFilters();
connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
myOperationMgr->activate();
}
+//******************************************************
void XGUI_Workshop::deactivateModule()
{
- myModule->deactivateSelectionFilters();
-
// remove internal displayer filter
- displayer()->deactivateSelectionFilters();
+ displayer()->deactivateSelectionFilters(false);
disconnect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
XGUI_Displayer* aDisplayer = displayer();
QObjectPtrList aDisplayed = aDisplayer->displayedObjects();
aDisplayer->deactivateObjects(aDisplayed, true);
- Handle(AIS_InteractiveContext) aContext = viewer()->AISContext();
- Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(aDisplayer->getTrihedron());
- /// deactivate trihedron in selection modes
- TColStd_ListOfInteger aTColModes;
- aContext->ActivatedModes(aTrihedron, aTColModes);
- TColStd_ListIteratorOfListOfInteger itr( aTColModes );
- for (; itr.More(); itr.Next() ) {
- Standard_Integer aMode = itr.Value();
- aContext->Deactivate(aTrihedron, aMode);
- }
+ selectionActivate()->deactivateTrihedronInSelectionModes();
+
#ifdef BEFORE_TRIHEDRON_PATCH
+ //Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(aDisplayer->getTrihedron());
/// Trihedron problem: objects stayed in the viewer, should be removed manually
/// otherwise in SALOME happens crash by HideAll in the viewer
aContext->Remove(aTrihedron->Position(), true);
addHistoryMenu(aAction, SIGNAL(updateRedoHistory(const QList<ActionInfo>&)), SLOT(onRedo(int)));
salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
- //aAction = salomeConnector()->addDesktopCommand("REBUILD_CMD", tr("Rebuild"),
- // tr("Rebuild data objects"),
- // QIcon(":pictures/rebuild.png"), QKeySequence(),
- // false, "MEN_DESK_EDIT");
- //salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
-
- //connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild()));
- //salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."),
tr("Export the current document into a native file"),
SIGNAL(updateRedoHistory(const QList<ActionInfo>&)),
SLOT(onRedo(int)));
- //aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
- // QIcon(":pictures/rebuild.png"), QKeySequence());
- //aCommand->connectTo(this, SLOT(onRebuild()));
-
- //aCommand->disable();
-
aCommand = aGroup->addFeature("OPEN_CMD", tr("Open..."), tr("Open a new document"),
QIcon(":pictures/open.png"), QKeySequence::Open);
aCommand->connectTo(this, SLOT(onOpen()));
}
#ifndef HAVE_SALOME
+//******************************************************
AppElements_Workbench* XGUI_Workshop::addWorkbench(const QString& theName)
{
AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer)
{
if (!myModule->canActivateSelection(theObject)) {
- if (myDisplayer->isActive(theObject)) {
+ if (selectionActivate()->isActive(theObject)) {
QObjectPtrList anObjects;
anObjects.append(theObject);
myDisplayer->deactivateObjects(anObjects, theUpdateViewer);
return aHasNested;
}
+//******************************************************
void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation)
{
ModuleBase_OperationFeature* aFOperation =
if (!aFOperation)
return;
- showPropertyPanel();
+ showPanel(myPropertyPanel);
myPropertyPanel->cleanContent();
QList<ModuleBase_ModelWidget*> aWidgets;
myErrorMgr->setPropertyPanel(myPropertyPanel);
}
+//******************************************************
void XGUI_Workshop::connectToPropertyPanel(const bool isToConnect)
{
XGUI_PropertyPanel* aPropertyPanel = propertyPanel();
myModule->operationResumed(theOperation);
}
-
//******************************************************
void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
{
ModuleBase_ISelection* aSel = mySelector->selection();
QObjectPtrList aObj = aSel->selectedPresentations();
//!< No need for property panel
- hidePropertyPanel();
+ hidePanel(myPropertyPanel);
myPropertyPanel->cleanContent();
connectToPropertyPanel(false);
QObjectPtrList anObjects;
FeaturePtr aFeature = aFOperation->feature();
if (aFeature.get()) { // feature may be not created (plugin load fail)
- if (myDisplayer->isVisible(aFeature) && !myDisplayer->isActive(aFeature))
+ if (myDisplayer->isVisible(aFeature) && !selectionActivate()->isActive(aFeature))
anObjects.append(aFeature);
std::list<ResultPtr> aResults;
ModelAPI_Tools::allResults(aFeature, aResults);
std::list<ResultPtr>::const_iterator aIt;
for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
ResultPtr anObject = *aIt;
- if (myDisplayer->isVisible(anObject) && !myDisplayer->isActive(anObject)) {
+ if (myDisplayer->isVisible(anObject) && !selectionActivate()->isActive(anObject)) {
anObjects.append(anObject);
}
}
activateObjectsSelection(anObjects);
}
-
+//******************************************************
void XGUI_Workshop::onOperationCommitted(ModuleBase_Operation* theOperation)
{
myModule->operationCommitted(theOperation);
}
+//******************************************************
void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation)
{
myModule->operationAborted(theOperation);
}
+//******************************************************
void XGUI_Workshop::setGrantedFeatures(ModuleBase_Operation* theOperation)
{
ModuleBase_OperationFeature* aFOperation =
//******************************************************
void XGUI_Workshop::onUndo(int theTimes)
{
- ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
- if (anActiveWidget && anActiveWidget->processAction(ActionUndo))
- return;
-
- objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
- SessionPtr aMgr = ModelAPI_Session::get();
- std::list<std::string> aUndoList = aMgr->undoList();
- if (aMgr->isOperation()) {
- /// this is important for nested operations
- /// when sketch operation is active, this condition is false and
- /// the sketch operation is not aborted
- operationMgr()->onAbortOperation();
- }
- std::list<std::string>::const_iterator aIt = aUndoList.cbegin();
- for (int i = 0; (i < theTimes) && (aIt != aUndoList.cend()); ++i, ++aIt) {
- aMgr->undo();
- if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND)
- myObjectBrowser->rebuildDataTree();
- }
-
- operationMgr()->updateApplyOfOperations();
- updateCommandStatus();
+ processUndoRedo(ActionUndo, theTimes);
}
//******************************************************
void XGUI_Workshop::onRedo(int theTimes)
{
- ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
- if (anActiveWidget && anActiveWidget->processAction(ActionRedo))
- return;
+ processUndoRedo(ActionRedo, theTimes);
+}
+//******************************************************
+void XGUI_Workshop::processUndoRedo(const ModuleBase_ActionType theActionType, int theTimes)
+{
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ if (anActiveWidget) {
+ ActionIntParamPtr aParam(new ModuleBase_ActionIntParameter(theTimes));
+ if (anActiveWidget->processAction(theActionType, aParam))
+ return;
+ }
// the viewer update should be blocked in order to avoid the features blinking. For the created
// feature a results are created, the flush of the created signal caused the viewer redisplay for
// each created result. After a redisplay signal is flushed. So, the viewer update is blocked
// until redo of all possible objects happens
bool isUpdateEnabled = myDisplayer->enableUpdateViewer(false);
- objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
SessionPtr aMgr = ModelAPI_Session::get();
- std::list<std::string> aRedoList = aMgr->redoList();
if (aMgr->isOperation()) {
+ XGUI_OperationMgr* aOpMgr = operationMgr();
/// this is important for nested operations
/// when sketch operation is active, this condition is false and
/// the sketch operation is not aborted
- operationMgr()->onAbortOperation();
+ if (aOpMgr->canStopOperation(aOpMgr->currentOperation()))
+ aOpMgr->abortOperation(aOpMgr->currentOperation());
+ else
+ {
+ myDisplayer->enableUpdateViewer(isUpdateEnabled);
+ return;
+ }
}
- std::list<std::string>::const_iterator aIt = aRedoList.cbegin();
- for (int i = 0; (i < theTimes) && (aIt != aRedoList.cend()); ++i, ++aIt) {
- aMgr->redo();
+ objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
+ std::list<std::string> anActionList = theActionType == ActionUndo ? aMgr->undoList()
+ : aMgr->redoList();
+ std::list<std::string>::const_iterator aIt = anActionList.cbegin();
+ for (int i = 0; (i < theTimes) && (aIt != anActionList.cend()); ++i, ++aIt) {
+ if (theActionType == ActionUndo)
+ aMgr->undo();
+ else
+ aMgr->redo();
+
if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND)
myObjectBrowser->rebuildDataTree();
}
operationMgr()->updateApplyOfOperations();
+ facesPanel()->reset(true);
updateCommandStatus();
// unblock the viewer update functionality and make update on purpose
myDisplayer->updateViewer();
}
-//******************************************************
-//void XGUI_Workshop::onRebuild()
-//{
-// SessionPtr aMgr = ModelAPI_Session::get();
-// bool aWasOperation = aMgr->isOperation(); // keep this value
-// if (!aWasOperation) {
-// aMgr->startOperation("Rebuild");
-// }
-// static const Events_ID aRebuildEvent = Events_Loop::loop()->eventByName("Rebuild");
-// Events_Loop::loop()->send(std::shared_ptr<Events_Message>(
-// new Events_Message(aRebuildEvent, this)));
-// if (!aWasOperation) {
-// aMgr->finishOperation();
-// }
-// updateCommandStatus();
-//}
-
//******************************************************
void XGUI_Workshop::onWidgetStateChanged(int thePreviousState)
{
}
}
+//******************************************************
void XGUI_Workshop::onWidgetObjectUpdated()
{
operationMgr()->onValidateOperation();
}
+//******************************************************
ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
{
QString libName = QString::fromStdString(library(theModule.toStdString()));
emit commandStatusUpdated();
}
+//******************************************************
void XGUI_Workshop::updateHistory()
{
- std::list<std::string> aUndoList = ModelAPI_Session::get()->undoList();
- QList<ActionInfo> aUndoRes = processHistoryList(aUndoList);
- emit updateUndoHistory(aUndoRes);
+ bool isActionEnabled = false;
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ QList<ActionInfo> aUndoRes;
+ QList<ActionInfo> aRedoRes;
+ if (anActiveWidget && anActiveWidget->canProcessAction(ActionUndo, isActionEnabled)) {
+ aUndoRes = anActiveWidget->actionsList(ActionUndo);
+ aRedoRes = anActiveWidget->actionsList(ActionRedo);
+ } else {
+ std::list<std::string> aUndoList = ModelAPI_Session::get()->undoList();
+ aUndoRes = processHistoryList(aUndoList);
- std::list<std::string> aRedoList = ModelAPI_Session::get()->redoList();
- QList<ActionInfo> aRedoRes = processHistoryList(aRedoList);
+ std::list<std::string> aRedoList = ModelAPI_Session::get()->redoList();
+ aRedoRes = processHistoryList(aRedoList);
+ }
+ emit updateUndoHistory(aUndoRes);
emit updateRedoHistory(aRedoRes);
}
QDockWidget* aObjDock = createObjectBrowser(aDesktop);
aDesktop->addDockWidget(Qt::LeftDockWidgetArea, aObjDock);
myPropertyPanel = new XGUI_PropertyPanel(aDesktop, myOperationMgr);
+ myActiveControlMgr->addSelector(new XGUI_PropertyPanelSelector(myPropertyPanel));
+
myPropertyPanel->setupActions(myActionsMgr);
myPropertyPanel->setAllowedAreas(Qt::LeftDockWidgetArea |
Qt::RightDockWidgetArea |
Qt::BottomDockWidgetArea);
aDesktop->addDockWidget(Qt::LeftDockWidgetArea, myPropertyPanel);
- hidePropertyPanel(); ///<! Invisible by default
+ hidePanel(myPropertyPanel); ///<! Invisible by default
+
+ myFacesPanel = new XGUI_FacesPanel(aDesktop, myModuleConnector);
+ myActiveControlMgr->addSelector(new XGUI_FacesPanelSelector(myFacesPanel));
+ myFacesPanel->setAllowedAreas(Qt::LeftDockWidgetArea |
+ Qt::RightDockWidgetArea |
+ Qt::BottomDockWidgetArea);
+ connect(myFacesPanel, SIGNAL(closed()), myFacesPanel, SLOT(onClosed()));
+
+ aDesktop->addDockWidget(
+#ifdef HAVE_SALOME
+ Qt::RightDockWidgetArea,
+#else
+ Qt::LeftDockWidgetArea,
+#endif
+ myFacesPanel);
+ hidePanel(myFacesPanel); ///<! Invisible by default
+
+#ifdef _DEBUG
+ bool aShowOnTheRight = Config_PropManager::boolean("Plugins", "show_hide_faces");
+ if (aShowOnTheRight) {
+ aDesktop->addDockWidget(Qt::RightDockWidgetArea, myFacesPanel);
+ showPanel(myFacesPanel);
+ }
+#endif
hideObjectBrowser();
+
+#ifndef HAVE_SALOME
+#ifdef _DEBUG
+ if (!aShowOnTheRight)
+ {
+#endif // _DEBUG
+ aDesktop->tabifyDockWidget(myFacesPanel, aObjDock);
+#ifdef _DEBUG
+ }
+#endif // _DEBUG
+
+#endif // HAVE_SALOME
+
aDesktop->tabifyDockWidget(aObjDock, myPropertyPanel);
myPropertyPanel->installEventFilter(myOperationMgr);
}
//******************************************************
-void XGUI_Workshop::showPropertyPanel()
+void XGUI_Workshop::showPanel(QDockWidget* theDockWidget)
{
- QAction* aViewAct = myPropertyPanel->toggleViewAction();
- ///<! Restore ability to close panel from the window's menu
- aViewAct->setEnabled(true);
- myPropertyPanel->show();
- myPropertyPanel->raise();
+ if (theDockWidget == myPropertyPanel) {
+ QAction* aViewAct = myPropertyPanel->toggleViewAction();
+ ///<! Restore ability to close panel from the window's menu
+ aViewAct->setEnabled(true);
+ }
+ theDockWidget->show();
+ theDockWidget->raise();
// The next code is necessary to made the property panel the active window
// in order to operation manager could process key events of the panel.
// otherwise they are ignored. It happens only if the same(activateWindow) is
// not happened by property panel activation(e.g. resume operation of Sketch)
- ModuleBase_Tools::setFocus(myPropertyPanel, "XGUI_Workshop::showPropertyPanel()");
+ ModuleBase_Tools::setFocus(theDockWidget, "XGUI_Workshop::showPanel()");
}
//******************************************************
-void XGUI_Workshop::hidePropertyPanel()
+void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget)
{
- QAction* aViewAct = myPropertyPanel->toggleViewAction();
- ///<! Do not allow to show empty property panel
- aViewAct->setEnabled(false);
- myPropertyPanel->hide();
+ if (theDockWidget && theDockWidget == myPropertyPanel) {
+ QAction* aViewAct = theDockWidget->toggleViewAction();
+ ///<! Do not allow to show empty property panel
+ aViewAct->setEnabled(false);
+ }
+ theDockWidget->hide();
// the property panel is active window of the desktop, when it is
// hidden, it is undefined which window becomes active. By this reason
// are processed by this console. For example Undo actions.
// It is possible that this code is to be moved to SHAPER package
QMainWindow* aDesktop = desktop();
- ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::showPropertyPanel()");
+ ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::hidePanel()");
}
//******************************************************
viewer()->eraseAll();
#endif
updateCommandStatus();
+ // Necessary for update icons in ObjectBrowser on Linux
+ myObjectBrowser->updateAllIndexes();
} else if (theId == "SELECT_VERTEX_CMD") {
setViewerSelectionMode(TopAbs_VERTEX);
} else if (theId == "SELECT_EDGE_CMD") {
setViewerSelectionMode(TopAbs_EDGE);
} else if (theId == "SELECT_FACE_CMD") {
setViewerSelectionMode(TopAbs_FACE);
+ } else if (theId == "INSERT_FOLDER_CMD") {
+ insertFeatureFolder();
+ } else if (theId == "ADD_TO_FOLDER_BEFORE_CMD") {
+ insertToFolder(true);
+ } else if (theId == "ADD_TO_FOLDER_AFTER_CMD") {
+ insertToFolder(false);
+ } else if (theId == "ADD_OUT_FOLDER_BEFORE_CMD") {
+ moveOutFolder(true);
+ } else if (theId == "ADD_OUT_FOLDER_AFTER_CMD") {
+ moveOutFolder(false);
} else if (theId == "SELECT_RESULT_CMD") {
//setViewerSelectionMode(-1);
//IMP: an attempt to use result selection with other selection modes
if (!aContext.IsNull())
aParameters.Append(aContext);
+#ifdef DEBUG_WITH_MESSAGE_REPORT
+ Handle(Message_Report) aContextReport = aContext->GetReport();
+ aContext->SetReportActive (Standard_True);
+ aContextReport->SetLimit (1000);
+ if (!aContextReport.IsNull())
+ aParameters.Append(aContextReport);
+#endif
MyVCallBack = new VInspector_CallBack();
myDisplayer->setCallBack(MyVCallBack);
#ifndef HAVE_SALOME
MyTCommunicator->RegisterPlugin("TKDFBrowser");
MyTCommunicator->RegisterPlugin("TKShapeView");
MyTCommunicator->RegisterPlugin("TKVInspector");
+#ifdef DEBUG_WITH_MESSAGE_REPORT
+ MyTCommunicator->RegisterPlugin("TKMessageView");
+#endif
MyTCommunicator->RegisterPlugin("SMBrowser"); // custom plugin to view ModelAPI
//MyTCommunicator->RegisterPlugin("TKSMBrowser"); // custom plugin to view ModelAPI
MyTCommunicator->Init(aParameters);
MyTCommunicator->Activate("TKSMBrowser"); // to have button in TInspector
+#ifndef DEBUG_WITH_MESSAGE_REPORT
MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
+#endif
MyTCommunicator->Activate("TKDFBrowser");
+
+#ifdef DEBUG_WITH_MESSAGE_REPORT
+ MyTCommunicator->Activate("TKMessageView"); // temporary
+ MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
+#endif
}
MyTCommunicator->SetVisible(true);
}
else
myViewerSelMode.append(theMode);
}
- activateObjectsSelection(myDisplayer->displayedObjects());
+ selectionActivate()->updateSelectionModes();
}
//**************************************************************
module()->activeSelectionModes(aModes);
if (aModes.isEmpty() && (myViewerSelMode.length() > 0))
aModes.append(myViewerSelMode);
- myDisplayer->activateObjects(aModes, theList);
+ selectionActivate()->activateObjects(aModes, theList);
+}
+
+//**************************************************************
+bool XGUI_Workshop::prepareForDisplay(const std::set<ObjectPtr>& theObjects) const
+{
+ if (facesPanel()->isEmpty())
+ return true;
+
+ // generate container of objects taking into account sub elments of compsolid
+ std::set<ObjectPtr> anAllProcessedObjects;
+ for (std::set<ObjectPtr>::const_iterator anObjectsIt = theObjects.begin();
+ anObjectsIt != theObjects.end(); anObjectsIt++) {
+ ObjectPtr anObject = *anObjectsIt;
+ ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anObject);
+ if (aCompRes.get()) {
+ if (aCompRes->numberOfSubs(true) == 0)
+ anAllProcessedObjects.insert(anObject);
+ else {
+ for (int i = 0; i < aCompRes->numberOfSubs(true); i++) {
+ ResultPtr aSubRes = aCompRes->subResult(i, true);
+ anAllProcessedObjects.insert(aCompRes->subResult(i, true));
+ }
+ }
+ }
+ else
+ anAllProcessedObjects.insert(anObject);
+ }
+
+ // find hidden objects in faces panel
+ std::set<ObjectPtr> aHiddenObjects;
+ QStringList aHiddenObjectNames;
+ for (std::set<ObjectPtr>::const_iterator anObjectsIt = anAllProcessedObjects.begin();
+ anObjectsIt != anAllProcessedObjects.end(); anObjectsIt++) {
+ if (!facesPanel()->isObjectHiddenByPanel(*anObjectsIt))
+ continue;
+ aHiddenObjects.insert(*anObjectsIt);
+ aHiddenObjectNames.append((*anObjectsIt)->data()->name().c_str());
+ }
+ if (aHiddenObjects.empty()) // in parameter objects there are no hidden objects in hide face
+ return true;
+
+ int anAnswer = QMessageBox::question(
+ desktop(), tr("Show object"),
+ tr("'%1'\n are hidden by %2:\nRemove objects from the panel to be displayed?")
+ .arg(aHiddenObjectNames.join(' ,')).arg(facesPanel()->windowTitle()),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+
+ bool aToBeDisplayed = anAnswer == QMessageBox::Yes;
+ if (aToBeDisplayed)
+ facesPanel()->restoreObjects(aHiddenObjects);
+
+ return aToBeDisplayed;
}
//**************************************************************
bool hasParameter = false;
bool hasCompositeOwner = false;
bool hasResultInHistory = false;
+ bool hasFolder = false;
ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasCompositeOwner,
- hasResultInHistory);
- if (!(hasFeature || hasParameter))
+ hasResultInHistory, hasFolder);
+ if (!(hasFeature || hasParameter || hasFolder))
return;
// delete objects
ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
+ std::set<FolderPtr> aFolders;
+ ModuleBase_Tools::convertToFolders(anObjects, aFolders);
+
bool aDone = false;
QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1";
aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
aDone = ModelAPI_Tools::removeFeatures(aFeatures, false);
}
+ if (aFolders.size() > 0) {
+ std::set<FolderPtr>::const_iterator anIt = aFolders.begin(),
+ aLast = aFolders.end();
+ for (; anIt != aLast; anIt++) {
+ FolderPtr aFolder = *anIt;
+ if (aFolder.get()) {
+ DocumentPtr aDoc = aFolder->document();
+ aDoc->removeFolder(aFolder);
+ }
+ }
+ }
+
if (aDone)
operationMgr()->commitOperation();
else
return ModelAPI_Tools::removeFeaturesAndReferences(aFeatures);
}
+//******************************************************
bool hasResults(QObjectPtrList theObjects, const std::set<std::string>& theTypes)
{
bool isFoundResultType = false;
return std::list<FeaturePtr>(aObjectIt, aCurrentIt);
}
+//******************************************************
bool XGUI_Workshop::canMoveFeature()
{
QString anActionId = "MOVE_CMD";
return false;
}
+//******************************************************
void setColor(ResultPtr theResult, const std::vector<int>& theColor)
{
if (!theResult.get())
for (int i = 0; i < aDoc->size(aGroupName); i++) { \
aDoc->object(aGroupName, i)->setDisplayed(aDisplay); \
}
+
+//******************************************************
void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
{
+ if (isVisible) {
+ std::set<ObjectPtr> anObjects;
+ foreach (ObjectPtr aObj, theList) {
+ anObjects.insert(aObj);
+ }
+ if (!prepareForDisplay(anObjects))
+ return;
+ }
+
foreach (ObjectPtr aObj, theList) {
aObj->setDisplayed(isVisible);
}
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-#ifndef WIN32
- // Necessary for update icons in ObjectBrowser on Linux
- QModelIndexList aIndexes = mySelector->selection()->selectedIndexes();
- foreach (QModelIndex aIdx, aIndexes) {
- if (aIdx.column() == 0) {
- myObjectBrowser->treeView()->update(aIdx);
- }
- }
-#endif
+ myObjectBrowser->updateAllIndexes();
}
//**************************************************************
viewer()->eraseAll();
#endif
+ std::set<ObjectPtr> anObjects;
+ foreach (ObjectPtr aObj, theList) {
+ anObjects.insert(aObj);
+ }
+
+ if (!prepareForDisplay(anObjects))
+ return;
+
// Show only objects from the list
foreach (ObjectPtr aObj, theList) {
aObj->setDisplayed(true);
}
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-#ifndef WIN32
+
// Necessary for update icons in ObjectBrowser on Linux
- QModelIndexList aIndexes = mySelector->selection()->selectedIndexes();
- foreach (QModelIndex aIdx, aIndexes) {
- if (aIdx.column() == 0) {
- myObjectBrowser->treeView()->update(aIdx);
- }
- }
-#endif
+ myObjectBrowser->updateAllIndexes();
}
-
//**************************************************************
void XGUI_Workshop::registerValidators() const
{
//objectBrowser()->dataModel()->blockEventsProcessing(isBlocked);
}
+//******************************************************
void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot)
{
XGUI_HistoryMenu* aMenu = NULL;
connect(aMenu, SIGNAL(actionSelected(int)), this, theSlot);
}
+//******************************************************
QList<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>& theList) const
{
QList<ActionInfo> aResult;
return aResult;
}
+//******************************************************
void XGUI_Workshop::setStatusBarMessage(const QString& theMessage)
{
#ifdef HAVE_SALOME
#endif
}
+#ifdef HAVE_SALOME
+//******************************************************
void XGUI_Workshop::synchronizeViewer()
{
SessionPtr aMgr = ModelAPI_Session::get();
}
}
+//******************************************************
void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc,
const std::string& theGroup,
bool theUpdateViewer)
if (theUpdateViewer)
myDisplayer->updateViewer();
}
+#endif
+//******************************************************
void XGUI_Workshop::highlightResults(const QObjectPtrList& theObjects)
{
FeaturePtr aFeature;
tr("Results not found"), QMessageBox::Ok);
}
+//******************************************************
void XGUI_Workshop::highlightFeature(const QObjectPtrList& theObjects)
{
ResultPtr aResult;
objectBrowser()->blockSignals(aBlocked);
}
}
+
+void XGUI_Workshop::insertFeatureFolder()
+{
+ QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
+ if (aObjects.isEmpty())
+ return;
+ ObjectPtr aObj = aObjects.first();
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+ if (aFeature.get() == NULL)
+ return;
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+
+ QString aDescription = contextMenuMgr()->action("INSERT_FOLDER_CMD")->text();
+
+ aMgr->startOperation(aDescription.toStdString());
+ aDoc->addFolder(aFeature);
+ aMgr->finishOperation();
+
+ updateCommandStatus();
+}
+
+
+void XGUI_Workshop::insertToFolder(bool isBefore)
+{
+ std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
+ if (aFeatures.empty())
+ return;
+
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+
+ FolderPtr aFolder = isBefore? aDoc->findFolderAbove(aFeatures):
+ aDoc->findFolderBelow(aFeatures);
+ if (!aFolder.get())
+ return;
+
+ QString aDescription = contextMenuMgr()->action(
+ isBefore ? "ADD_TO_FOLDER_BEFORE_CMD" : "ADD_TO_FOLDER_AFTER_CMD")->text();
+
+ aMgr->startOperation(aDescription.toStdString());
+ aDoc->moveToFolder(aFeatures, aFolder);
+ aMgr->finishOperation();
+
+ updateCommandStatus();
+}
+
+void XGUI_Workshop::moveOutFolder(bool isBefore)
+{
+ std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
+ if (aFeatures.empty())
+ return;
+
+ SessionPtr aMgr = ModelAPI_Session::get();
+ DocumentPtr aDoc = aMgr->activeDocument();
+
+
+ QString aDescription = contextMenuMgr()->action(
+ isBefore ? "ADD_OUT_FOLDER_BEFORE_CMD" : "ADD_OUT_FOLDER_AFTER_CMD")->text();
+
+ aMgr->startOperation(aDescription.toStdString());
+ aDoc->removeFromFolder(aFeatures, isBefore);
+ aMgr->finishOperation();
+
+ updateCommandStatus();
+}
#define XGUI_WORKSHOP_H
#include "XGUI.h"
-//#include "XGUI_Constants.h"
-#include <ModuleBase_Definitions.h>
+
#include <ModelAPI_Document.h>
#include <ModelAPI_Feature.h>
#include <ModuleBase_ActionInfo.h>
+#include <ModuleBase_ActionType.h>
+#include <ModuleBase_Definitions.h>
+#include <SelectMgr_ListOfFilter.hxx>
+
+#include <QIcon>
#include <QObject>
-#include <QMap>
#include <QKeySequence>
-#include <QIcon>
+#include <QMap>
#ifndef HAVE_SALOME
-class AppElements_MainWindow;
class AppElements_Command;
+class AppElements_MainWindow;
class AppElements_Workbench;
#endif
+class Config_DataModelReader;
+
class XGUI_ActionsMgr;
+class XGUI_ActiveControlMgr;
class XGUI_ContextMenuMgr;
class XGUI_Displayer;
class XGUI_ErrorDialog;
class XGUI_ErrorMgr;
+class XGUI_FacesPanel;
class XGUI_MenuMgr;
class XGUI_ModuleConnector;
class XGUI_ObjectsBrowser;
class XGUI_PropertyPanel;
class XGUI_SalomeConnector;
class XGUI_SalomeViewer;
+class XGUI_SelectionActivate;
class XGUI_SelectionMgr;
class XGUI_ViewerProxy;
class XGUI_WorkshopListener;
class ModuleBase_IViewer;
class ModuleBase_Operation;
-class QWidget;
+class QAction;
class QDockWidget;
class QMainWindow;
+class QWidget;
-class QAction;
-class Config_DataModelReader;
-
-/**\class XGUI_Workshop
- * \ingroup GUI
- * \brief Class which defines a configuration of the application (Workshop) and launches it.
- */
+/// \class XGUI_Workshop
+/// \ingroup GUI
+/// \brief Class which defines a configuration of the application (Workshop) and launches it.
class XGUI_EXPORT XGUI_Workshop : public QObject
{
Q_OBJECT
XGUI_Workshop(XGUI_SalomeConnector* theConnector = 0);
virtual ~XGUI_Workshop();
- //! Starting of the application
+ /// Starting of the application
void startApplication();
/// Activates the module controls. Should be called after module creation
void deactivateModule();
#ifndef HAVE_SALOME
- //! Returns main window (Desktop) of the application
- AppElements_MainWindow* mainWindow() const
- {
- return myMainWindow;
- }
+ /// Returns main window (Desktop) of the application
+ AppElements_MainWindow* mainWindow() const { return myMainWindow; }
- //! Creates and adds a new workbench (menu group) with the given name and returns it
+ /// Creates and adds a new workbench (menu group) with the given name and returns it
AppElements_Workbench* addWorkbench(const QString& theName);
#endif
- //! Returns selection manager object
- XGUI_SelectionMgr* selector() const
- {
- return mySelector;
- }
-
- //! Returns displayer
- XGUI_Displayer* displayer() const
- {
- return myDisplayer;
- }
-
- //! ! Returns operation manager.
- XGUI_OperationMgr* operationMgr() const
- {
- return myOperationMgr;
- }
-
- //! ! Returns error manager.
- XGUI_ErrorMgr* errorMgr() const
- {
- return myErrorMgr;
- }
-
- //! ! Returns an actions manager
- XGUI_ActionsMgr* actionsMgr() const
- {
- return myActionsMgr;
- }
-
- //! ! Returns an actions manager
- XGUI_MenuMgr* menuMgr() const
- {
- return myMenuMgr;
- }
-
- //! Returns property panel widget
- XGUI_PropertyPanel* propertyPanel() const
- {
- return myPropertyPanel;
- }
-
- //! Returns context menu manager object
- XGUI_ContextMenuMgr* contextMenuMgr() const
- {
- return myContextMenuMgr;
- }
-
- //! Returns an object which provides interface to Salome Module (LightApp_Module)
- XGUI_SalomeConnector* salomeConnector() const
- {
- return mySalomeConnector;
- }
-
- //! Provides an object which provides interface to Salome Viewer
+ /// Returns selection manager object
+ XGUI_SelectionMgr* selector() const { return mySelector; }
+
+ /// Returns selection activating object
+ XGUI_SelectionActivate* selectionActivate() const { return mySelectionActivate; }
+
+ /// Returns displayer
+ XGUI_Displayer* displayer() const { return myDisplayer; }
+
+ /// Returns operation manager.
+ XGUI_OperationMgr* operationMgr() const { return myOperationMgr; }
+
+ /// Returns error manager.
+ XGUI_ErrorMgr* errorMgr() const { return myErrorMgr; }
+
+ /// Returns an actions manager
+ XGUI_ActionsMgr* actionsMgr() const { return myActionsMgr; }
+
+ /// Returns an active control manager
+ XGUI_ActiveControlMgr* activeControlMgr() const { return myActiveControlMgr; }
+
+ /// Returns an actions manager
+ XGUI_MenuMgr* menuMgr() const { return myMenuMgr; }
+
+ /// Returns property panel widget
+ XGUI_PropertyPanel* propertyPanel() const { return myPropertyPanel; }
+
+ /// Returns panel for hide object faces
+ XGUI_FacesPanel* facesPanel() const { return myFacesPanel; }
+
+ /// Returns context menu manager object
+ XGUI_ContextMenuMgr* contextMenuMgr() const { return myContextMenuMgr; }
+
+ /// Returns an object which provides interface to Salome Module (LightApp_Module)
+ XGUI_SalomeConnector* salomeConnector() const { return mySalomeConnector; }
+
+ /// Provides an object which provides interface to Salome Viewer
ModuleBase_IViewer* salomeViewer() const;
- //! Returns true if the application works as SALOME module
- bool isSalomeMode() const
- {
- return mySalomeConnector != 0;
- }
+ /// Returns true if the application works as SALOME module
+ bool isSalomeMode() const { return mySalomeConnector != 0; }
- //! Returns Object browser
- XGUI_ObjectsBrowser* objectBrowser() const
- {
- return myObjectBrowser;
- }
+ /// Returns Object browser
+ XGUI_ObjectsBrowser* objectBrowser() const { return myObjectBrowser; }
/// This method is called by Salome module when selection is changed
void salomeViewerSelectionChanged();
/// Returns viewer which unifies access as to Salome viewer as to standalone viewer
- XGUI_ViewerProxy* viewer() const
- {
- return myViewerProxy;
- }
+ XGUI_ViewerProxy* viewer() const { return myViewerProxy; }
/// Returns the module connector
/// \returns the instance of connector
- XGUI_ModuleConnector* moduleConnector() const
- {
- return myModuleConnector;
- }
+ XGUI_ModuleConnector* moduleConnector() const { return myModuleConnector; }
/// Returns a desktop
/// \return a desktop instance
QMainWindow* desktop() const;
- //! Delete features
+ /// If faces panel made the object hidden, show message box whether the object should be
+ /// restored (removed from the panel) and displayed, if answer is No, returns false
+ /// \param theObject a model object
+ /// \return boolean state if the object should not be displayed
+ virtual bool prepareForDisplay(const std::set<ObjectPtr>& theObjects) const;
+
+ /// Delete features
void deleteObjects();
- //! Searches for selected features unused in other (not selected) features. If one or several
- //! selected features are found, a warning message proposes to delete them. It contains
- //! the list of features to be deleted.
+ /// Searches for selected features unused in other (not selected) features. If one or several
+ /// selected features are found, a warning message proposes to delete them. It contains
+ /// the list of features to be deleted.
void cleanHistory();
- //! Returns true if the selected feature can be moved to the position after the current feature
- //! \return boolean value
+ /// Returns true if the selected feature can be moved to the position after the current feature
+ /// \return boolean value
bool canMoveFeature();
- //! Move selected features to be after the current feature
+ /// Move selected features to be after the current feature
void moveObjects();
- //! Returns true if the object can be shaded. If the object is a compsolid result, the method
- //! checks subobjects of the result
- //! \return boolean value
+ /// Returns true if the object can be shaded. If the object is a compsolid result, the method
+ /// checks subobjects of the result
+ /// \return boolean value
bool canBeShaded(const ObjectPtr& theObject) const;
- //! Returns true if there is at least one selected body/construction/group result
- //! \param theActionName text of the checked action
- //! \return boolean value
+ /// Returns true if there is at least one selected body/construction/group result
+ /// \param theActionName text of the checked action
+ /// \return boolean value
bool canChangeProperty(const QString& theActionName) const;
- //! Change color of the results if it is possible
- //! The operation is available for construction, body and group results
- //! theObjects a list of selected objects
+ /// Change color of the results if it is possible
+ /// The operation is available for construction, body and group results
+ /// theObjects a list of selected objects
void changeColor(const QObjectPtrList& theObjects);
- //! Change deflection of the results if it is possible
- //! The operation is available for construction, body and group results
- //! theObjects a list of selected objects
+ /// Change deflection of the results if it is possible
+ /// The operation is available for construction, body and group results
+ /// theObjects a list of selected objects
void changeDeflection(const QObjectPtrList& theObjects);
- //! Change transparency of the results if it is possible
- //! The operation is available for construction, body and group results
- //! theObjects a list of selected objects
+ /// Change transparency of the results if it is possible
+ /// The operation is available for construction, body and group results
+ /// theObjects a list of selected objects
void changeTransparency(const QObjectPtrList& theObjects);
- //! Show the given features in 3d Viewer
+ /// Show the given features in 3d Viewer
void showObjects(const QObjectPtrList& theList, bool isVisible);
- //! Show the given features in 3d Viewer
+ /// Show the given features in 3d Viewer
void showOnlyObjects(const QObjectPtrList& theList);
/// Set display mode for the given objects
void activateObjectsSelection(const QObjectPtrList& theList);
/// Returns current module
- ModuleBase_IModule* module() const
- {
- return myModule;
- }
+ ModuleBase_IModule* module() const { return myModule; }
/// Returns current directory which contains data files
QString currentDataDir() const { return myCurrentDir; }
/// Returns current directory which contains data files
void setCurrentDataDir(const QString& theDir) { myCurrentDir = theDir; }
- /**
- * Save the current document into a directory
- * \param theName - path to the directory
- * \param theFileNames - returned file names created in this directory
- */
+ /// Save the current document into a directory
+ /// \param theName - path to the directory
+ /// \param theFileNames - returned file names created in this directory
void saveDocument(const QString& theName, std::list<std::string>& theFileNames);
- /**
- * If there is an active (uncommitted) operation shows a prompt to abort it
- * and performs abortion if user agreed. Returns true if
- * - operation aborted successfully
- * - there is no active operation
- */
+ /// If there is an active (uncommitted) operation shows a prompt to abort it
+ /// and performs abortion if user agreed. Returns true if
+ /// - operation aborted successfully
+ /// - there is no active operation
bool abortAllOperations();
/// Updates workshop state according to the started operation, e.g. visualizes the property panel
/// \param theOpertion a started operation
void operationStarted(ModuleBase_Operation* theOperation);
-
- //! Delete features. Delete the referenced features. There can be a question with a list of
- //! referenced objects.
- //! \param theFeatures a list of objects to be deleted
+ /// Delete features. Delete the referenced features. There can be a question with a list of
+ /// referenced objects.
+ /// \param theFeatures a list of objects to be deleted
bool deleteFeatures(const QObjectPtrList& theFeatures);
/// Deactivates the object, if it is active and the module returns that the activation
/// \param theFeature a feature
bool isFeatureOfNested(const FeaturePtr& theFeature);
- //! Shows the message in the status bar
- //! \param theMessage a message
+ /// Shows the message in the status bar
+ /// \param theMessage a message
void setStatusBarMessage(const QString& theMessage);
+#ifdef HAVE_SALOME
/// Has to be called in order to display objects with visibility status = true
void synchronizeViewer();
const std::string& theGroup,
bool theUpdateViewer);
+#endif
/// Update the property panel content by the XML description of the operation and set the panel
/// into the operation
/// \param theOperation an operation
/// It is used for specific processing of Undo/Redo for this command.
static QString MOVE_TO_END_COMMAND;
- //! Closes all in the current session and load the directory
- //! \param theDirectory a path to directory
+ /// Closes all in the current session and load the directory
+ /// \param theDirectory a path to directory
void openDirectory(const QString& theDirectory);
signals:
/// Emitted when selection happens in Salome viewer
void salomeViewerSelection();
- //! the signal about the workshop actions states are updated.
+ /// the signal about the workshop actions states are updated.
void commandStatusUpdated();
- //! the application is started
+ /// the application is started
void applicationStarted();
- //! Signal to update Undo history list
+ /// Signal to update Undo history list
void updateUndoHistory(const QList<ActionInfo>&);
- //! Signal to update Redo history list
+ /// Signal to update Redo history list
void updateRedoHistory(const QList<ActionInfo>&);
public slots:
/// Redo previous command
void onRedo(int times = 1);
- // Rebuild data tree
- //void onRebuild();
-
/// Validates the operation to change the "Apply" button state.
/// \param thePreviousState the previous state of the widget
void onWidgetStateChanged(int thePreviousState);
/// Listens the corresponded signal of model widget and updates Apply button state by feature
void onWidgetObjectUpdated();
- /// Show property panel
- void showPropertyPanel();
+ /// Show dock widget panel
+ void showPanel(QDockWidget* theDockWidget);
- /// Hide property panel
- void hidePropertyPanel();
+ /// Hide dock widget panel
+ void hidePanel(QDockWidget* theDockWidget);
/// Show object Browser
void showObjectBrowser();
void setGrantedFeatures(ModuleBase_Operation* theOperation);
private:
- /// Display all results
- //void displayAllResults();
-
/// Display results from document
/// \param theDoc a document
void displayDocumentResults(DocumentPtr theDoc);
/// Display results from a group
void displayGroupResults(DocumentPtr theDoc, std::string theGroup);
- private slots:
- /// SLOT, that is called after the operation is started. Update workshop state according to
- /// the started operation, e.g. visualizes the property panel and connect to it.
- /// \param theOpertion a started operation
- // void onOperationStarted(ModuleBase_Operation* theOperation);
+ /// Insert folder object before currently selected feature
+ void insertFeatureFolder();
+
+ /// Insert an object to a folder above or below
+ void insertToFolder(bool isBefore);
+
+ /// Insert an object to a folder above or below
+ void moveOutFolder(bool isBefore);
+ private slots:
/// SLOT, that is called after the operation is resumed. Update workshop state according to
/// the started operation, e.g. visualizes the property panel and connect to it.
/// \param theOpertion a resumed operation
void onPreviewActionClicked();
private:
- /// Init menu
+ /// Init menu
void initMenu();
/// Register validators
// Creates Dock widgets: Object browser and Property panel
void createDockWidgets();
- //! Extends undo/redo toolbutton's with history menu
- //! \param theObject - in the OpenParts it is a QToolButton by itself,
- //! in salome mode - QAction that creates a button.
- //! \param theSignal - void "updateUndoHistory" or "updateRedoHistory" SIGNAL;
- //! \param theSlot - onUndo(int) or onRedo(int) SLOT
+ /// Extends undo/redo toolbutton's with history menu
+ /// \param theObject - in the OpenParts it is a QToolButton by itself,
+ /// in salome mode - QAction that creates a button.
+ /// \param theSignal - void "updateUndoHistory" or "updateRedoHistory" SIGNAL;
+ /// \param theSlot - onUndo(int) or onRedo(int) SLOT
void addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot);
- //! Creates list of actions (commands) by given history list from session
+ /// Creates list of actions (commands) by given history list from session
QList<ActionInfo> processHistoryList(const std::list<std::string>&) const;
+ /// Pefrom Undo/Redo and necessary workshop updates(viewer, browser, actions state)
+ /// \param theActionType a type of the action (Undo or Redo)
+ /// \param theTimes number of applies the given action
+ void processUndoRedo(const ModuleBase_ActionType theActionType, int theTimes);
+
private:
#ifndef HAVE_SALOME
- AppElements_MainWindow* myMainWindow;
+ AppElements_MainWindow* myMainWindow; ///< desktop window
#endif
- ModuleBase_IModule* myModule;
- XGUI_ErrorMgr* myErrorMgr;
- XGUI_ObjectsBrowser* myObjectBrowser;
- XGUI_PropertyPanel* myPropertyPanel;
- XGUI_SelectionMgr* mySelector;
- XGUI_Displayer* myDisplayer;
+ ModuleBase_IModule* myModule; ///< current module
+ XGUI_ErrorMgr* myErrorMgr; ///< updator of error message
+ XGUI_ObjectsBrowser* myObjectBrowser; ///< data tree widget
+ XGUI_PropertyPanel* myPropertyPanel; ///< container of feature attributes widgets
+ XGUI_FacesPanel* myFacesPanel; ///< panel for hide object faces
+ XGUI_SelectionMgr* mySelector; ///< handler of selection processing
+ XGUI_SelectionActivate* mySelectionActivate; /// manager of selection activating
+ XGUI_Displayer* myDisplayer; ///< handler of objects display
XGUI_OperationMgr* myOperationMgr; ///< manager to manipulate through the operations
- XGUI_ActionsMgr* myActionsMgr;
+ XGUI_ActionsMgr* myActionsMgr; ///< manager of workshop actions
+ XGUI_ActiveControlMgr* myActiveControlMgr; ///< manager to have none or one active control
XGUI_MenuMgr* myMenuMgr; ///< manager to build menu/tool bar using order defined in XML
- XGUI_SalomeConnector* mySalomeConnector;
- XGUI_ErrorDialog* myErrorDlg;
- XGUI_ViewerProxy* myViewerProxy;
- XGUI_ContextMenuMgr* myContextMenuMgr;
- XGUI_ModuleConnector* myModuleConnector;
- XGUI_WorkshopListener* myEventsListener;
-
- QString myCurrentDir;
-
- QIntList myViewerSelMode;
-
- Config_DataModelReader* myDataModelXMLReader;
+ XGUI_SalomeConnector* mySalomeConnector; ///< connector to SALOME module interface
+ XGUI_ErrorDialog* myErrorDlg; ///< dialog to show information of occured error events
+ XGUI_ViewerProxy* myViewerProxy; ///< connector to SALOME viewer interface
+ XGUI_ContextMenuMgr* myContextMenuMgr; ///< manager of context menu build
+ XGUI_ModuleConnector* myModuleConnector; ///< implementation of ModuleBase_IWorkshop
+ XGUI_WorkshopListener* myEventsListener; ///< processing of events
+ QString myCurrentDir; ///< cached the last open directory
+ QIntList myViewerSelMode; ///< selection modes set in the viewer
+ Config_DataModelReader* myDataModelXMLReader; ///< XML reader of data model
};
#endif
//
#include "XGUI_WorkshopListener.h"
-#include "XGUI_Workshop.h"
-#include "XGUI_Displayer.h"
-#include "XGUI_ErrorMgr.h"
-#include "XGUI_OperationMgr.h"
-#include "XGUI_SalomeConnector.h"
-#include "XGUI_ActionsMgr.h"
-#include "XGUI_PropertyPanel.h"
-#include "XGUI_ModuleConnector.h"
-#include "XGUI_QtEvents.h"
-#include "XGUI_SelectionMgr.h"
#ifndef HAVE_SALOME
#include <AppElements_MainWindow.h>
#endif
-#include <ModuleBase_IModule.h>
-#include <ModuleBase_Events.h>
+#include <Config_FeatureMessage.h>
+#include <Config_PointerMessage.h>
+#include <Config_Keywords.h>
+
+#include <Events_InfoMessage.h>
+#include <Events_Loop.h>
+#include <Events_LongOp.h>
#include <ModelAPI_Object.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_Tools.h>
-#include <Events_Loop.h>
-#include <Events_LongOp.h>
-
+#include <ModuleBase_Events.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IViewer.h>
#include <ModuleBase_IWorkshop.h>
-
#include <ModuleBase_Operation.h>
#include <ModuleBase_OperationDescription.h>
#include <ModuleBase_OperationFeature.h>
#include <ModuleBase_Tools.h>
-#include <ModuleBase_IViewer.h>
#include <ModuleBase_WidgetSelector.h>
-#include <Config_FeatureMessage.h>
-#include <Config_PointerMessage.h>
-#include <Config_Keywords.h>
-#include <Events_InfoMessage.h>
+#include "XGUI_ActionsMgr.h"
+#include "XGUI_Displayer.h"
+#include "XGUI_ErrorMgr.h"
+#include "XGUI_FacesPanel.h"
+#include "XGUI_OperationMgr.h"
+#include "XGUI_ModuleConnector.h"
+#include "XGUI_PropertyPanel.h"
+#include "XGUI_QtEvents.h"
+#include "XGUI_SalomeConnector.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Workshop.h"
+
+#include <QAction>
#include <QApplication>
#include <QMainWindow>
#include <QThread>
-#include <QAction>
#ifdef _DEBUG
#include <QDebug>
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED));
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION));
+
+ aLoop->registerListener(this, Events_Loop::eventByName("FinishOperation"));
+ aLoop->registerListener(this, Events_Loop::eventByName("AbortOperation"));
}
//******************************************************
if (aWidgetSelector)
workshop()->selector()->setSelected(aWidgetSelector->getAttributeSelection());
}
- }
+ } else if (theMessage->eventID() == Events_Loop::eventByName("FinishOperation")/* ||
+ theMessage->eventID() == Events_Loop::eventByName("AbortOperation")*/)
+ workshop()->facesPanel()->reset(false); // do not flush redisplay, it is flushed after event
//Update property panel on corresponding message. If there is no current operation (no
//property panel), or received message has different feature to the current - do nothing.
<file>pictures/face32.png</file>
<file>pictures/edge32.png</file>
<file>pictures/vertex32.png</file>
+ <file>pictures/features_folder.png</file>
+ <file>pictures/create_folder.png</file>
+ <file>pictures/insert_folder_after.png</file>
+ <file>pictures/insert_folder_before.png</file>
+ <file>pictures/move_out_after.png</file>
+ <file>pictures/move_out_before.png</file>
+ <file>pictures/selection.png</file>
</qresource>
</RCC>
Translation_7 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
Translation_8 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_8_1")], model.selection("EDGE", "Box_8_1/Right&Box_8_1/Top"), 15)
Translation_9 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "PartSet/Axis_4"), 15)
-Translation_10 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_10_1")], model.selection("EDGE", "PartSet/OZ"), 15)
-Translation_11 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_11_1")], model.selection("EDGE", "PartSet/OZ"), 0)
-Translation_12 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_12_1")], model.selection("EDGE", "PartSet/OZ"), -15)
-Translation_13 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_13_1")], model.selection("EDGE", "InvalidName"), 15)
-Translation_14 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_14_1")], model.selection("EDGE", "PartSet/OZ"), "d")
-Translation_15 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_15_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 50)
-Translation_16 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_16_1")], model.selection("EDGE", "Edge_1_1"), 50)
-#Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_8_1")], model.selection("EDGE", "MultiTranslation_8_1/Translated_Edge_8_8"), 50)
-Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_17_1")], model.selection("EDGE", "Box_17_1/Translated_Face_3_4&Box_17_1/Translated_Face_3_1"), 50)
-Translation_18 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_18_1")], model.selection("EDGE", "PartSet/Axis_4"), 50)
+Translation_10 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OZ"), 15)
+Translation_11 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_2_1")], model.selection("EDGE", "PartSet/OZ"), 0)
+Translation_12 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_3_1")], model.selection("EDGE", "PartSet/OZ"), -15)
+Translation_13 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_4_1")], model.selection("EDGE", "InvalidName"), 15)
+Translation_14 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_5_1")], model.selection("EDGE", "PartSet/OZ"), "d")
+Translation_15 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 50)
+Translation_16 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_7_1")], model.selection("EDGE", "Edge_1_1"), 50)
+#Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_8_1")], model.selection("EDGE", "LinearCopy_8_1/Translated_Edge_8_8"), 50)
+Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_8_1")], model.selection("EDGE", "LinearCopy_8_1/Translated_Face_3_4&LinearCopy_8_1/Translated_Face_3_1"), 50)
+Translation_18 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_9_1")], model.selection("EDGE", "PartSet/Axis_4"), 50)
Translation_19 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "OX"), 15)
Translation_20 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_3/")], model.selection("EDGE", "OX"), 0)
Translation_21 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_4/")], model.selection("EDGE", "OX"), -15)
# Translation 27
Translation_27_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_2_1")], [model.selection("SOLID", "Box_1_1")])
-Translation_27 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_2_1")], model.selection("EDGE", "PartSet/OX"), 15)
+Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_2_1")], [model.selection("SOLID", "Translation_1_1")])
+Translation_27 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_1_1")], model.selection("EDGE", "PartSet/OX"), 15)
# Translation 28
Translation_28_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_2 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_4_1")], [model.selection("SOLID", "Box_3_1")])
-Translation_28 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_4_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Intersection_2 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_4_1")], [model.selection("SOLID", "Translation_3_1")])
+Translation_28 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_2_1")], model.selection("EDGE", "PartSet/OX"), 0)
# Translation 29
Translation_29_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_5_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_3 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_6_1")], [model.selection("SOLID", "Box_5_1")])
-Translation_29 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_6_1")], model.selection("EDGE", "PartSet/OX"), -15)
+Intersection_3 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_6_1")], [model.selection("SOLID", "Translation_5_1")])
+Translation_29 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_3_1")], model.selection("EDGE", "PartSet/OX"), -15)
# Translation 30
Translation_30_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_7_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_4 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_8_1")], [model.selection("SOLID", "Box_7_1")])
-Translation_30 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_8_1")], model.selection("EDGE", "InvalidName"), -15)
+Intersection_4 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_8_1")], [model.selection("SOLID", "Translation_7_1")])
+Translation_30 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_4_1")], model.selection("EDGE", "InvalidName"), -15)
# Translation 31
Translation_31_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_9_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_5 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_10_1")], [model.selection("SOLID", "Box_9_1")])
-Translation_31 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_10_1")], model.selection("EDGE", "PartSet/OY"), "d")
+Intersection_5 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_10_1")], [model.selection("SOLID", "Translation_9_1")])
+Translation_31 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_5_1")], model.selection("EDGE", "PartSet/OY"), "d")
# Translation 32
Translation_32_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_11_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_6 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_12_1")], [model.selection("SOLID", "Box_11_1")])
-Translation_32 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_12_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
+Intersection_6 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_12_1")], [model.selection("SOLID", "Translation_11_1")])
+Translation_32 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
# Translation 33
Translation_33_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_13_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_7 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_14_1")], [model.selection("SOLID", "Box_13_1")])
-Translation_33 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_14_1")], model.selection("EDGE", "Edge_1_1"), 15)
+Intersection_7 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_14_1")], [model.selection("SOLID", "Translation_13_1")])
+Translation_33 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
# Translation 34
Translation_34_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_15_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_8 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_16_1")], [model.selection("SOLID", "Box_15_1")])
-Translation_34 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_16_1")], model.selection("EDGE", "Intersection_8_1_6"), 15)
+Intersection_8 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_16_1")], [model.selection("SOLID", "Translation_15_1")])
+Translation_34 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_8_1")], model.selection("EDGE", "Intersection_8_1_6"), 15)
# Translation 35
Translation_35_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_17_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Intersection_9 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_18_1")], [model.selection("SOLID", "Box_17_1")])
-Translation_35 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Box_18_1")], model.selection("EDGE", "Axis_1"), 15)
+Intersection_9 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Box_18_1")], [model.selection("SOLID", "Translation_17_1")])
+Translation_35 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "Intersection_9_1")], model.selection("EDGE", "Axis_1"), 15)
#Translation 36
Translation_36_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_19_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_20_1"), model.selection("SOLID", "Box_19_1")])
-Translation_36 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_20_1")], model.selection("EDGE", "PartSet/OX"), 15)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_20_1"), model.selection("SOLID", "Translation_19_1")])
+Translation_36 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OX"), 15)
## Translation 37
Translation_37_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_21_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_2 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_22_1"), model.selection("SOLID", "Box_21_1")])
-Translation_37 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_22_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_22_1"), model.selection("SOLID", "Translation_21_1")])
+Translation_37 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_2_1")], model.selection("EDGE", "PartSet/OX"), 0)
## Translation 38
Translation_38_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_23_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_3 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_24_1"), model.selection("SOLID", "Box_23_1")])
-Translation_38 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_24_1")], model.selection("EDGE", "PartSet/OX"), 0)
+Partition_3 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_24_1"), model.selection("SOLID", "Translation_23_1")])
+Translation_38 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_3_1")], model.selection("EDGE", "PartSet/OX"), 0)
## Translation 39
Translation_39_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_25_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_4 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_26_1"), model.selection("SOLID", "Box_25_1")])
-Translation_39 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_26_1")], model.selection("EDGE", "InvalidName"), 0)
+Partition_4 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_26_1"), model.selection("SOLID", "Translation_25_1")])
+Translation_39 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_4_1")], model.selection("EDGE", "InvalidName"), 0)
## Translation 40
Translation_40_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_27_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_5 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_28_1"), model.selection("SOLID", "Box_27_1")])
-Translation_40 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_28_1")], model.selection("EDGE", "PartSet/OX"), "d")
+Partition_5 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_28_1"), model.selection("SOLID", "Translation_27_1")])
+Translation_40 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_5_1")], model.selection("EDGE", "PartSet/OX"), "d")
# Translation 41
Translation_41_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_29_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_6 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_30_1"), model.selection("SOLID", "Box_29_1")])
-Translation_41 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_30_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
+Partition_6 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_30_1"), model.selection("SOLID", "Translation_29_1")])
+Translation_41 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
# Translation 42
Translation_42_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_31_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_7 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_32_1"), model.selection("SOLID", "Box_31_1")])
-Translation_42 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_32_1")], model.selection("EDGE", "Edge_1_1"), 15)
+Partition_7 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_32_1"), model.selection("SOLID", "Translation_31_1")])
+Translation_42 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
# Translation 43
Translation_43_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_33_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_8 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_34_1"), model.selection("SOLID", "Box_33_1")])
-Translation_43 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_34_1")], model.selection("EDGE", "Partition_8_1_1/Modified_Face_2_5&Partition_8_1_1/Modified_Face_2_2"), 15)
+Partition_8 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_34_1"), model.selection("SOLID", "Translation_33_1")])
+Translation_43 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_8_1")], model.selection("EDGE", "Partition_8_1_1/Modified_Face_2_5&Partition_8_1_1/Modified_Face_2_2"), 15)
# Translation 44
Translation_44_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_35_1")], model.selection("EDGE", "PartSet/OX"), 5)
-Partition_9 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_36_1"), model.selection("SOLID", "Box_35_1")])
-Translation_44 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Box_36_1")], model.selection("EDGE", "Axis_1"), 15)
+Partition_9 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_36_1"), model.selection("SOLID", "Translation_35_1")])
+Translation_44 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_9_1")], model.selection("EDGE", "Axis_1"), 15)
model.do()
model.end()
SketchConstraintRadius_3 = Sketch_2.setRadius(SketchCircle_1.results()[1], "50/2")
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f")], model.selection(), 0, 13, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"))
SketchPoint_3 = Sketch_3.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_2&ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_4"))
SketchLine_11 = Sketch_3.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&ExtrusionCut_1_1/Modfied_4"))
SketchConstraintCoincidence_23.setName("SketchConstraintCoincidence_24")
model.do()
ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_3_2f-SketchLine_12f-SketchArc_5_2r")], model.selection(), 5, 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_1_1/To_Face_1"))
SketchPoint_4 = Sketch_4.addPoint(model.selection("VERTEX", "ExtrusionFuse_1_1/Modfied_4&ExtrusionFuse_1_1/Modfied_5&ExtrusionFuse_1_1/To_Face_1"))
SketchCircle_2 = Sketch_4.addCircle(-15, 35.00000000000001, 5)
SketchConstraintRadius_4 = Sketch_4.setRadius(SketchCircle_2.results()[1], "10/2")
model.do()
ExtrusionFuse_2 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_2_2f")], model.selection(), 8, 0, [model.selection("SOLID", "ExtrusionFuse_1_1")])
-ExtrusionFuse_2.result().setName("ExtrusionFuse_2_1")
Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
SketchArc_6 = Sketch_5.addArc(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&ExtrusionFuse_1_1/Modfied_3"))
SketchArc_7 = Sketch_5.addArc(-45, 35, -45, 5, -25.41666666666737, 12.27351642784166, False)
SketchConstraintCoincidence_33.setName("SketchConstraintCoincidence_34")
model.do()
ExtrusionFuse_3 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_7_2f-SketchArc_8_2r-SketchLine_13r-SketchArc_9_2r")], model.selection(), 0, 8, [model.selection("SOLID", "ExtrusionFuse_2_1")])
-ExtrusionFuse_3.result().setName("ExtrusionFuse_3_1")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_3_1/Modfied_3"))
SketchLine_14 = Sketch_6.addLine(model.selection("EDGE", "ExtrusionFuse_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7"))
SketchArc_10 = Sketch_6.addArc(55, 35, 55, 15, 35, 35, True)
SketchConstraintCoincidence_41.setName("SketchConstraintCoincidence_42")
model.do()
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_6/Wire-SketchArc_10_2f-SketchLine_16r-SketchLine_18f-SketchLine_19r")], model.selection(), 0, 9, [model.selection("SOLID", "ExtrusionFuse_3_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_4"))
SketchCircle_4 = Sketch_7.addCircle(45, 35, 5)
SketchLine_20 = Sketch_7.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_2&ExtrusionCut_2_1/Modfied_4"))
SketchConstraintHorizontal_4 = Sketch_7.setHorizontal(SketchLine_21.result())
model.do()
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_7/Face-SketchCircle_4_2f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/From_Face_1"), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
SketchLine_22 = Sketch_8.addLine(55, 25, 5.000000000000002, 25)
SketchLine_23 = Sketch_8.addLine(5.000000000000002, 25, 5.000000000000002, 13)
SketchConstraintCoincidence_49.setName("SketchConstraintCoincidence_50")
model.do()
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_8"), 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_1_1/Modfied_2"))
SketchLine_28 = Sketch_9.addLine(25, -45, 18.44853578320836, -63)
SketchLine_29 = Sketch_9.addLine(model.selection("EDGE", "ExtrusionFuse_1_1/Modfied_2&ExtrusionCut_4_1/Modfied_6"))
SketchConstraintCoincidence_55.setName("SketchConstraintCoincidence_56")
model.do()
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchLine_28f-SketchLine_31f-SketchLine_32f")], model.selection(), model.selection(), 0, model.selection("FACE", "ExtrusionCut_4_1/Modfied_3"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
Sketch_10 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_5_1/Modfied_1"))
SketchCircle_5 = Sketch_10.addCircle(-6.000000000000002, 4.999999999999997, 5)
SketchLine_33 = Sketch_10.addLine(model.selection("EDGE", "ExtrusionCut_2_1/Modfied_3&ExtrusionCut_5_1/Modfied_1"))
SketchConstraintRadius_7 = Sketch_10.setRadius(SketchCircle_5.results()[1], "10/2")
model.do()
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_10/Face-SketchCircle_5_2f")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
-ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
model.do()
# Test reexecution after parameter change
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f")], model.selection(), 75, 45)
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
Boolean_1 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Boolean_1.result().setName("Boolean_1_1")
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
SketchLine_20 = Sketch_4.addLine(-4, 38.00000000000001, -4, 21.26617031813674)
SketchLine_20.setName("SketchLine_36")
Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 50, 30)
Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
Boolean_2 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], [model.selection("SOLID", "Extrusion_4_1")])
-Boolean_2.result().setName("Boolean_2_1")
Extrusion_5 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
Extrusion_6 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2f")], model.selection(), 75, 40)
Boolean_3 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Extrusion_6_1")], [model.selection("SOLID", "Extrusion_5_1")])
-Boolean_3.result().setName("Boolean_3_1")
Sketch_5 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
SketchLine_38 = Sketch_5.addLine(44, 3.464101615137769, 17.52573586555855, 49.31887218898888)
SketchLine_38.setName("SketchLine_41")
model.do()
Extrusion_7 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchLine_55r-SketchLine_44r-SketchLine_52r-SketchLine_53r-SketchLine_54r-SketchLine_47r-SketchLine_48r-SketchLine_49r-SketchArc_12_2r-SketchArc_13_2r")], model.selection(), 0, 40)
Boolean_4 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Boolean_2_1")])
-Boolean_4.result().setName("Boolean_4_1")
Boolean_5 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_4_1")], [model.selection("SOLID", "Extrusion_7_1")])
-Boolean_5.result().setName("Boolean_5_1")
Boolean_6 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_5_1")], [model.selection("SOLID", "Boolean_3_1")])
-Boolean_6.result().setName("Boolean_6_1")
Extrusion_8 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_10r-SketchLine_11r-SketchLine_8r-SketchLine_3r-SketchLine_9r-SketchLine_6r-SketchArc_1_2r-SketchArc_2_2f")], model.selection(), 55, 55)
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_1"))
SketchLine_54 = Sketch_7.addLine(55, -9.237604307034024, 55, -60)
SketchConstraintDistance_34 = Sketch_7.setDistance(SketchCircle_7.center(), SketchLine_66.result(), 11)
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchArc_14_2r-SketchArc_15_2r"), model.selection("FACE", "Sketch_7/Face-SketchCircle_4_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_5_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_7_2f"), model.selection("FACE", "Sketch_7/Face-SketchCircle_6_2f")], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_8_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_8_1/Generated_Face_3"))
SketchLine_67 = Sketch_8.addLine(55, -34.06366588218793, 55, 66.69872981077805)
SketchLine_67.setName("SketchLine_79")
SketchLine_67.result().setName("SketchLine_79")
-SketchPoint_10 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_3"))
+SketchPoint_10 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_4&ExtrusionCut_1_1/Modfied_1&Extrusion_8_1/Generated_Face_3"))
SketchLine_68 = Sketch_8.addLine(55, -34.06366588218793, 55, 76.69872981077803)
SketchLine_68.setName("SketchLine_70")
SketchLine_68.result().setName("SketchLine_70")
SketchLine_70.setAuxiliary(True)
SketchConstraintCoincidence_118 = Sketch_8.setCoincident(SketchLine_68.endPoint(), SketchLine_70.startPoint())
SketchConstraintCoincidence_118.setName("SketchConstraintCoincidence_122")
-SketchPoint_12 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_3&Extrusion_8_1/Generated_Face_4"))
+SketchPoint_12 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_2&Extrusion_8_1/Generated_Face_3&Extrusion_8_1/Generated_Face_4"))
SketchConstraintCoincidence_119 = Sketch_8.setCoincident(SketchLine_70.endPoint(), SketchPoint_12.result())
SketchConstraintCoincidence_119.setName("SketchConstraintCoincidence_123")
SketchLine_71 = Sketch_8.addLine(-55, 66.69872976783566, -55, -34.06366588218793)
SketchLine_72.setAuxiliary(True)
SketchConstraintCoincidence_120 = Sketch_8.setCoincident(SketchLine_70.endPoint(), SketchLine_72.startPoint())
SketchConstraintCoincidence_120.setName("SketchConstraintCoincidence_124")
-SketchPoint_13 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_6&ExtrusionCut_1_1/Modfied_3&Extrusion_8_1/Generated_Face_3"))
+SketchPoint_13 = Sketch_8.addPoint(model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_4&ExtrusionCut_1_1/Modfied_2&Extrusion_8_1/Generated_Face_3"))
SketchConstraintCoincidence_121 = Sketch_8.setCoincident(SketchLine_72.endPoint(), SketchPoint_13.result())
SketchConstraintCoincidence_121.setName("SketchConstraintCoincidence_125")
SketchLine_73 = Sketch_8.addLine(-55, -34.06366588218793, -83.25521566485324, -34.06366588218793)
SketchConstraintDistance_44.setName("SketchConstraintDistance_45")
model.do()
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_79r-SketchLine_80r-SketchLine_81r-SketchLine_73r-SketchLine_74r-SketchLine_75r-SketchLine_76r-SketchLine_77r-SketchArc_16_2r-SketchArc_17_2r"), model.selection("WIRE", "Sketch_8/Wire-SketchCircle_8_2f"), model.selection("WIRE", "Sketch_8/Wire-SketchCircle_9_2f"), model.selection("WIRE", "Sketch_8/Wire-SketchArc_19_2f-SketchArc_18_2f-SketchLine_82f-SketchLine_83r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Boolean_7 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Boolean_6_1")], [model.selection("SOLID", "ExtrusionCut_2_1")])
-Boolean_7.result().setName("Boolean_7_1")
model.do()
# Test reexecution after parameter change
model.addParameter(partSet, "Thickness", "25")
Part_1 = model.addPart(partSet)
Part_1.setName("Body")
-Part_1.result().setName("Part_1")
Part_1_doc = Part_1.document()
model.addParameter(Part_1_doc, "Radius", "50", "Radius of the body")
model.addParameter(Part_1_doc, "Width", "25", "Width of body arms")
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchLine_10r-SketchLine_11r-SketchArc_3_2f-SketchArc_4_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_14r-SketchArc_7_2f-SketchLine_15r-SketchArc_8_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_12r-SketchArc_5_2f-SketchLine_13r-SketchArc_6_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_19f-SketchLine_20f-SketchLine_21f-SketchArc_10_2f"), model.selection("FACE", "Sketch_2/Face-SketchLine_16f-SketchLine_17f-SketchLine_18f-SketchArc_9_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchArc_11_2f")], model.selection(), model.selection(), 10, model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 10)
Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_4"), model.selection("SOLID", "Extrusion_1_5")])
-Boolean_1.result().setName("Boolean_1_1")
Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3"), model.selection("SOLID", "Extrusion_1_6")])
-Boolean_2.result().setName("Boolean_2_1")
-Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Boolean_2_1/Modified_7"), model.selection("FACE", "Boolean_2_1/Modified_9"))
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Boolean_2_1/Modified_Face_7"), model.selection("FACE", "Boolean_2_1/Modified_Face_9"))
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchCircle_3 = Sketch_3.addCircle(25, -10, 4)
SketchCircle_4 = Sketch_3.addCircle(40, -10, 4)
SketchConstraintDistance_10.setName("SketchConstraintDistance_9")
SketchConstraintDistance_11 = Sketch_3.setDistance(SketchCircle_4.center(), SketchLine_28.result(), 40)
SketchConstraintDistance_11.setName("SketchConstraintDistance_10")
-SketchProjection_1 = Sketch_3.addProjection(model.selection("EDGE", "Boolean_2_1/Modified_23&Boolean_2_1/Modified_7"))
+SketchProjection_1 = Sketch_3.addProjection(model.selection("EDGE", "Boolean_2_1/Modified_Face_17&Boolean_2_1/Modified_Face_7"))
SketchLine_29 = SketchProjection_1.createdFeature()
SketchLine_29.setName("SketchLine_26")
SketchLine_29.result().setName("SketchLine_26")
SketchConstraintDistance_13 = Sketch_3.setDistance(SketchCircle_3.center(), SketchLine_29.result(), 10)
SketchConstraintDistance_13.setName("SketchConstraintDistance_12")
model.do()
-Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_3/Wire-SketchCircle_4_2f")], model.selection(), model.selection("FACE", "Boolean_1_1/Modified_6"), 5, model.selection("FACE", "Boolean_1_1/Modified_8"), 5)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_3/Wire-SketchCircle_4_2f")], model.selection(), model.selection("FACE", "Boolean_1_1/Modified_Face_6"), 5, model.selection("FACE", "Boolean_1_1/Modified_Face_8"), 5)
Boolean_3 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_2_1")], [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")])
-Boolean_3.result().setName("Boolean_3_1")
Recover_1 = model.addRecover(Part_1_doc, Boolean_3, [Extrusion_2.results()[1], Extrusion_2.result()])
Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_1_1"), model.selection("SOLID", "Recover_1_2")], model.selection("EDGE", "PartSet/OZ"), 120)
-Rotation_1.result().setName("Rotation_1_1")
-Rotation_1.results()[1].setName("Rotation_1_2")
Boolean_4 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_3_1")], [model.selection("SOLID", "Rotation_1_1"), model.selection("SOLID", "Rotation_1_2")])
-Boolean_4.result().setName("Boolean_4_1")
Recover_2 = model.addRecover(Part_1_doc, Boolean_4, [Rotation_1.results()[1], Rotation_1.result()])
Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_2_1"), model.selection("SOLID", "Recover_2_2")], model.selection("EDGE", "PartSet/OZ"), 120)
-Rotation_2.result().setName("Rotation_2_1")
-Rotation_2.results()[1].setName("Rotation_2_2")
Boolean_5 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_4_1")], [model.selection("SOLID", "Rotation_2_2"), model.selection("SOLID", "Rotation_2_1")])
-Boolean_5.result().setName("Boolean_5_1")
model.do()
Part_2 = model.addPart(partSet)
Part_2.setName("Arm 1")
-Part_2.result().setName("Part_2")
Part_2_doc = Part_2.document()
model.addParameter(Part_2_doc, "a", "7.5")
model.addParameter(Part_2_doc, "b", "12.5")
Face_1 = model.addFace(Part_2_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_1_2f-SketchArc_4_2f-SketchArc_5_2f-SketchArc_6_2f-SketchArc_7_2f-SketchArc_8_2f-SketchArc_9_2f-SketchArc_10_2f")])
Axis_4 = model.addAxis(Part_2_doc, model.selection("FACE", "PartSet/XOZ"), model.selection("VERTEX", "Sketch_2/Vertex-SketchArc_3-SketchLine_20s"))
Rotation_3 = model.addRotation(Part_2_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "Axis_1"), -43.8752)
-Rotation_3.result().setName("Rotation_1_1")
Pipe_1 = model.addPipe(Part_2_doc, [model.selection("FACE", "Rotation_1_1")], model.selection("EDGE", "Sketch_2/Edge-SketchArc_3_2"))
-Pipe_1.result().setName("Pipe_1_1")
Extrusion_3 = model.addExtrusion(Part_2_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_2_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchLine_14r-SketchLine_15r-SketchLine_16r-SketchLine_17r")], model.selection(), "Gap/2", "Gap/2")
Boolean_6 = model.addFuse(Part_2_doc, [model.selection("SOLID", "Pipe_1_1")], [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2")])
-Boolean_6.result().setName("Boolean_1_1")
Extrusion_4 = model.addExtrusion(Part_2_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_3_2f")], model.selection(), "Gap", "Gap")
Boolean_7 = model.addCut(Part_2_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Boolean_7.result().setName("Boolean_2_1")
Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Boolean_2_1")], model.selection("VERTEX", "Sketch_2/Vertex-SketchArc_3_2s"), model.selection("VERTEX", "Sketch_2/Vertex-SketchLine_21e"))
-Translation_1.result().setName("Translation_1_1")
model.do()
Part_3 = model.duplicatePart(Part_2)
Part_3.setName("Arm 2")
-Part_3.result().setName("Part_3")
model.do()
Part_4 = model.duplicatePart(Part_3)
Part_4.setName("Arm 3")
-Part_4.result().setName("Part_4")
model.do()
Translation_4 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_2/"), model.selection("COMPOUND", "Part_3/"), model.selection("COMPOUND", "Part_4/")], model.selection("EDGE", "OX"), -40)
Rotation_6 = model.addRotation(partSet, [model.selection("COMPOUND", "Translation_1_2/")], model.selection("EDGE", "OZ"), 120)
Rotation_7 = model.addRotation(partSet, [model.selection("COMPOUND", "Translation_1_3/")], model.selection("EDGE", "OZ"), 240)
Part_5 = model.addPart(partSet)
Part_5.setName("Rod part")
-Part_5.result().setName("Part_5")
Part_5_doc = Part_5.document()
Parameter_H = model.addParameter(partSet, "H", "110")
Sketch_10 = model.addSketch(Part_5_doc, model.defaultPlane("YOZ"))
model.do()
Revolution_3 = model.addRevolution(Part_5_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_14f-SketchLine_15f-SketchLine_16f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
Boolean_12 = model.addCut(Part_5_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Revolution_2_1")])
-Boolean_12.result().setName("Boolean_1_1")
Boolean_13 = model.addFuse(Part_5_doc, [model.selection("SOLID", "Boolean_1_1"), model.selection("SOLID", "Revolution_1_1")], [])
-Boolean_13.result().setName("Boolean_2_1")
# Test reexecution after parameter change
Parameter_H.setValue(120)
SketchConstraintCoincidence_8.setName("SketchConstraintCoincidence_16")
Extrusion_5.setNestedSketch(Sketch_5)
Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_4_1"), model.selection("SOLID", "Extrusion_5_1"), model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_3_1")], [])
-Boolean_1.result().setName("Boolean_1_1")
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection("FACE", "Extrusion_5_1/To_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "Boolean_1_1")])
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/From_Face_1"))
SketchCircle_6 = Sketch_6.addCircle(0, 0, 4.2)
SketchConstraintCoincidence_9 = Sketch_6.setCoincident(SketchPoint_2.coordinates(), SketchCircle_6.center())
SketchConstraintCoincidence_9.setName("SketchConstraintCoincidence_17")
ExtrusionCut_1.setNestedSketch(Sketch_6)
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
SketchCircle_7 = Sketch_7.addCircle(0, -85, 66)
SketchLine_6 = Sketch_7.addLine(model.selection("EDGE", "PartSet/OY"))
[SketchCircle_8, SketchCircle_9] = SketchMultiRotation_1.rotated()
model.do()
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_22"))
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_8"))
SketchLine_7 = Sketch_8.addLine(-2.320957096353877e-016, 11.00000001704673, -7, 11.00000001704673)
SketchConstraintHorizontal_1 = Sketch_8.setHorizontal(SketchLine_7.result())
SketchLine_8 = Sketch_8.addLine(-7, 11.00000001704673, -6.329882773485103e-016, 30.00000001704673)
SketchLine_13.setName("SketchLine_16")
SketchLine_13.result().setName("SketchLine_16")
model.do()
-ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_7r-SketchLine_8r-SketchLine_10f-SketchLine_11f"), model.selection("FACE", "Sketch_8/Face-SketchLine_16f-SketchLine_17f-SketchLine_18r-SketchLine_19r"), model.selection("FACE", "Sketch_8/Face-SketchLine_12f-SketchLine_13f-SketchLine_14r-SketchLine_15r")], model.selection(), model.selection("FACE", "ExtrusionCut_2_1/Modfied_23"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_7r-SketchLine_8r-SketchLine_10f-SketchLine_11f"), model.selection("FACE", "Sketch_8/Face-SketchLine_16f-SketchLine_17f-SketchLine_18r-SketchLine_19r"), model.selection("FACE", "Sketch_8/Face-SketchLine_12f-SketchLine_13f-SketchLine_14r-SketchLine_15r")], model.selection(), model.selection("FACE", "ExtrusionCut_2_1/Modfied_9"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
# Test reexecution after parameter change
Parameter_R.setValue(50)
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), "TL/2-3", "TL/2-3")
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 100, 100, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), "TL/2", "TL/2", [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 60, 60, [model.selection("SOLID", "ExtrusionFuse_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_5 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
SketchCircle_5 = Sketch_5.addCircle(30, -41, 7.5)
SketchLine_37 = Sketch_5.addLine(model.selection("EDGE", "PartSet/OX"))
SketchConstraintRadius_13.setName("SketchConstraintRadius_8")
model.do()
RevolutionFuse_1 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection("EDGE", "Sketch_7/Edge-SketchLine_41"), 360, 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-RevolutionFuse_1.result().setName("RevolutionFuse_1_1")
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchLine_49 = Sketch_8.addLine(32, 6, 32.50001476412091, 6.000000000000001)
SketchLine_49.setName("SketchLine_55")
SketchConstraintRadius_14.setName("SketchConstraintRadius_9")
model.do()
RevolutionFuse_2 = model.addRevolutionFuse(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_55r-SketchLine_49f-SketchLine_50f-SketchLine_56r-SketchLine_52f-SketchLine_53f-SketchArc_7_2r")], model.selection("EDGE", "Sketch_8/Edge-SketchLine_50"), 360, 0, [model.selection("SOLID", "RevolutionFuse_1_1")])
-RevolutionFuse_2.result().setName("RevolutionFuse_2_1")
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 30, True)
Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
SketchLine_57 = Sketch_9.addLine(-32.50001494742042, 5.999999999999998, -32, 6)
SketchConstraintRadius_16.setName("SketchConstraintRadius_11")
model.do()
RevolutionFuse_3 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "Sketch_9/Edge-SketchLine_58"), 360, 0, [model.selection("SOLID", "RevolutionFuse_2_1")])
-RevolutionFuse_3.result().setName("RevolutionFuse_3_1")
RevolutionFuse_4 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_10")], model.selection("EDGE", "Sketch_10/Edge-SketchLine_66"), 360, 0, [model.selection("SOLID", "RevolutionFuse_3_1")])
-RevolutionFuse_4.result().setName("RevolutionFuse_4_1")
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_11_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_9_2f"), model.selection("WIRE", "Sketch_6/Wire-SketchCircle_10_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_12_2f")], model.selection("EDGE", "PartSet/OZ"), "BPS+5", 5, [model.selection("SOLID", "RevolutionFuse_4_1")])
# Test reexecution after parameter change
model.do()
Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_8f-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_14f")], model.selection("EDGE", "PartSet/OX"), 360, 0)
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_1_2r-SketchLine_382f-SketchLine_383f-SketchLine_20f-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f-SketchLine_30f-SketchLine_31f-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f-SketchLine_36f-SketchLine_37f-SketchLine_38f-SketchLine_39f-SketchLine_40f-SketchLine_41f-SketchLine_42f-SketchLine_43f-SketchLine_44f-SketchLine_45f-SketchLine_46f-SketchLine_47f-SketchLine_48f-SketchLine_49f-SketchLine_50f-SketchLine_51f-SketchLine_52f-SketchLine_53f-SketchLine_54f-SketchLine_55f-SketchLine_56f-SketchLine_57f-SketchLine_58f-SketchLine_59f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchLine_65f-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_69f-SketchLine_70f-SketchLine_71f-SketchLine_72f-SketchLine_73f-SketchLine_74f-SketchLine_75f-SketchLine_76f-SketchLine_77f-SketchLine_78f-SketchLine_79f-SketchLine_80f-SketchLine_81f-SketchLine_82f-SketchLine_83f-SketchLine_84f-SketchLine_85f-SketchLine_86f-SketchLine_87f-SketchLine_88f-SketchLine_89f-SketchLine_90f-SketchLine_91f-SketchLine_92f-SketchLine_93f-SketchLine_94f-SketchLine_95f-SketchLine_96f-SketchLine_97f-SketchLine_98f-SketchLine_99f-SketchLine_100f-SketchLine_101f-SketchLine_102f-SketchLine_103f-SketchLine_104f-SketchLine_105f-SketchLine_106f-SketchLine_107f-SketchLine_108f-SketchLine_109f-SketchLine_110f-SketchLine_111f-SketchLine_112f-SketchLine_113f-SketchLine_114f-SketchLine_115f-SketchLine_116f-SketchLine_117f-SketchLine_118f-SketchLine_119f-SketchLine_120f-SketchLine_121f-SketchLine_122f-SketchLine_123f-SketchLine_124f-SketchLine_125f-SketchLine_126f-SketchLine_127f-SketchLine_128f-SketchLine_129f-SketchLine_130f-SketchLine_131f-SketchLine_132f-SketchLine_133f-SketchLine_134f-SketchLine_135f-SketchLine_136f-SketchLine_137f-SketchLine_138f-SketchLine_139f-SketchLine_140f-SketchLine_141f-SketchLine_142f-SketchLine_143f-SketchLine_144f-SketchLine_145f-SketchLine_146f-SketchLine_147f-SketchLine_148f-SketchLine_149f-SketchLine_150f-SketchLine_151f-SketchLine_152f-SketchLine_153f-SketchLine_154f-SketchLine_155f-SketchLine_156f-SketchLine_157f-SketchLine_158f-SketchLine_159f-SketchLine_160f-SketchLine_161f-SketchLine_162f-SketchLine_163f-SketchLine_164f-SketchLine_165f-SketchLine_166f-SketchLine_167f-SketchLine_168f-SketchLine_169f-SketchLine_170f-SketchLine_171f-SketchLine_172f-SketchLine_173f-SketchLine_174f-SketchLine_175f-SketchLine_176f-SketchLine_177f-SketchLine_178f-SketchLine_179f-SketchLine_180f-SketchLine_181f-SketchLine_182f-SketchLine_183f-SketchLine_184f-SketchLine_185f-SketchLine_186f-SketchLine_187f-SketchLine_188f-SketchLine_189f-SketchLine_190f-SketchLine_191f-SketchLine_192f-SketchLine_193f-SketchLine_194f-SketchLine_195f-SketchLine_196f-SketchLine_197f-SketchLine_198f-SketchLine_199f-SketchArc_2_2r-SketchArc_3_2r-SketchArc_4_2r-SketchArc_5_2r-SketchArc_6_2r-SketchArc_7_2r-SketchArc_8_2r-SketchArc_9_2r-SketchArc_10_2r-SketchArc_11_2r-SketchArc_12_2r-SketchArc_13_2r-SketchArc_14_2r-SketchArc_15_2r-SketchArc_16_2r-SketchArc_17_2r-SketchArc_18_2r-SketchArc_19_2r-SketchArc_20_2r-SketchArc_21_2r-SketchArc_22_2r-SketchArc_23_2r-SketchArc_24_2r-SketchArc_25_2r-SketchArc_26_2r-SketchArc_27_2r-SketchArc_28_2r-SketchArc_29_2r-SketchArc_30_2r-SketchArc_31_2r-SketchArc_32_2r-SketchArc_33_2r-SketchArc_34_2r-SketchArc_35_2r-SketchArc_36_2r-SketchArc_37_2r-SketchArc_38_2r-SketchArc_39_2r-SketchArc_40_2r-SketchArc_41_2r-SketchArc_42_2r-SketchArc_43_2r-SketchArc_44_2r-SketchArc_45_2r-SketchArc_46_2r-SketchArc_47_2r-SketchArc_48_2r-SketchArc_49_2r-SketchArc_50_2r-SketchArc_51_2r-SketchArc_52_2r-SketchArc_53_2r-SketchArc_54_2r-SketchArc_55_2r-SketchArc_56_2r-SketchArc_57_2r-SketchArc_58_2r-SketchArc_59_2r-SketchArc_60_2r-SketchArc_61_2r-SketchArc_62_2r-SketchArc_63_2r-SketchArc_64_2r-SketchArc_65_2r-SketchArc_66_2r-SketchArc_67_2r-SketchArc_68_2r-SketchArc_69_2r-SketchArc_70_2r-SketchArc_71_2r-SketchArc_72_2r-SketchArc_73_2r-SketchArc_74_2r-SketchArc_75_2r-SketchArc_76_2r-SketchArc_77_2r-SketchArc_78_2r-SketchArc_79_2r-SketchArc_80_2r-SketchArc_81_2r-SketchArc_82_2r-SketchArc_83_2r-SketchArc_84_2r-SketchArc_85_2r-SketchArc_86_2r-SketchArc_87_2r-SketchArc_88_2r-SketchArc_89_2r-SketchArc_90_2r-SketchArc_91_2r-SketchArc_92_2r-SketchArc_93_2r-SketchArc_94_2r-SketchArc_95_2r-SketchArc_96_2r-SketchArc_97_2r-SketchArc_98_2r-SketchArc_99_2r-SketchArc_100_2r-SketchArc_101_2r-SketchArc_102_2r-SketchArc_103_2r-SketchArc_104_2r-SketchArc_105_2r-SketchArc_106_2r-SketchArc_107_2r-SketchArc_108_2r-SketchArc_109_2r-SketchArc_110_2r-SketchArc_111_2r-SketchArc_112_2r-SketchArc_113_2r-SketchArc_114_2r-SketchArc_115_2r-SketchArc_116_2r-SketchArc_117_2r-SketchArc_118_2r-SketchArc_119_2r-SketchArc_120_2r-SketchArc_121_2r-SketchArc_122_2r-SketchArc_123_2r-SketchArc_124_2r-SketchArc_125_2r-SketchArc_126_2r-SketchArc_127_2r-SketchArc_128_2r-SketchArc_129_2r-SketchArc_130_2r-SketchArc_131_2r-SketchArc_132_2r-SketchArc_133_2r-SketchArc_134_2r-SketchArc_135_2r-SketchArc_136_2r-SketchArc_137_2r-SketchArc_138_2r-SketchArc_139_2r-SketchArc_140_2r-SketchArc_141_2r-SketchArc_142_2r-SketchArc_143_2r-SketchArc_144_2r-SketchArc_145_2r-SketchArc_146_2r-SketchArc_147_2r-SketchArc_148_2r-SketchArc_149_2r-SketchArc_150_2r-SketchArc_151_2r-SketchArc_152_2r-SketchArc_153_2r-SketchArc_154_2r-SketchArc_155_2r-SketchArc_156_2r-SketchArc_157_2r-SketchArc_158_2r-SketchArc_159_2r-SketchArc_160_2r-SketchArc_161_2r-SketchArc_162_2r-SketchArc_163_2r-SketchArc_164_2r-SketchArc_165_2r-SketchArc_166_2r-SketchArc_167_2r-SketchArc_168_2r-SketchArc_169_2r-SketchArc_170_2r-SketchArc_171_2r-SketchArc_172_2r-SketchArc_173_2r-SketchArc_174_2r-SketchArc_175_2r-SketchArc_176_2r-SketchArc_177_2r-SketchArc_178_2r-SketchArc_179_2r-SketchArc_180_2r-SketchLine_21f-SketchLine_200f-SketchLine_201f-SketchLine_202f-SketchLine_203f-SketchLine_204f-SketchLine_205f-SketchLine_206f-SketchLine_207f-SketchLine_208f-SketchLine_209f-SketchLine_210f-SketchLine_211f-SketchLine_212f-SketchLine_213f-SketchLine_214f-SketchLine_215f-SketchLine_216f-SketchLine_217f-SketchLine_218f-SketchLine_219f-SketchLine_220f-SketchLine_221f-SketchLine_222f-SketchLine_223f-SketchLine_224f-SketchLine_225f-SketchLine_226f-SketchLine_227f-SketchLine_228f-SketchLine_229f-SketchLine_230f-SketchLine_231f-SketchLine_232f-SketchLine_233f-SketchLine_234f-SketchLine_235f-SketchLine_236f-SketchLine_237f-SketchLine_238f-SketchLine_239f-SketchLine_240f-SketchLine_241f-SketchLine_242f-SketchLine_243f-SketchLine_244f-SketchLine_245f-SketchLine_246f-SketchLine_247f-SketchLine_248f-SketchLine_249f-SketchLine_250f-SketchLine_251f-SketchLine_252f-SketchLine_253f-SketchLine_254f-SketchLine_255f-SketchLine_256f-SketchLine_257f-SketchLine_258f-SketchLine_259f-SketchLine_260f-SketchLine_261f-SketchLine_262f-SketchLine_263f-SketchLine_264f-SketchLine_265f-SketchLine_266f-SketchLine_267f-SketchLine_268f-SketchLine_269f-SketchLine_270f-SketchLine_271f-SketchLine_272f-SketchLine_273f-SketchLine_274f-SketchLine_275f-SketchLine_276f-SketchLine_277f-SketchLine_278f-SketchLine_279f-SketchLine_280f-SketchLine_281f-SketchLine_282f-SketchLine_283f-SketchLine_284f-SketchLine_285f-SketchLine_286f-SketchLine_287f-SketchLine_288f-SketchLine_289f-SketchLine_290f-SketchLine_291f-SketchLine_292f-SketchLine_293f-SketchLine_294f-SketchLine_295f-SketchLine_296f-SketchLine_297f-SketchLine_298f-SketchLine_299f-SketchLine_300f-SketchLine_301f-SketchLine_302f-SketchLine_303f-SketchLine_304f-SketchLine_305f-SketchLine_306f-SketchLine_307f-SketchLine_308f-SketchLine_309f-SketchLine_310f-SketchLine_311f-SketchLine_312f-SketchLine_313f-SketchLine_314f-SketchLine_315f-SketchLine_316f-SketchLine_317f-SketchLine_318f-SketchLine_319f-SketchLine_320f-SketchLine_321f-SketchLine_322f-SketchLine_323f-SketchLine_324f-SketchLine_325f-SketchLine_326f-SketchLine_327f-SketchLine_328f-SketchLine_329f-SketchLine_330f-SketchLine_331f-SketchLine_332f-SketchLine_333f-SketchLine_334f-SketchLine_335f-SketchLine_336f-SketchLine_337f-SketchLine_338f-SketchLine_339f-SketchLine_340f-SketchLine_341f-SketchLine_342f-SketchLine_343f-SketchLine_344f-SketchLine_345f-SketchLine_346f-SketchLine_347f-SketchLine_348f-SketchLine_349f-SketchLine_350f-SketchLine_351f-SketchLine_352f-SketchLine_353f-SketchLine_354f-SketchLine_355f-SketchLine_356f-SketchLine_357f-SketchLine_358f-SketchLine_359f-SketchLine_360f-SketchLine_361f-SketchLine_362f-SketchLine_363f-SketchLine_364f-SketchLine_365f-SketchLine_366f-SketchLine_367f-SketchLine_368f-SketchLine_369f-SketchLine_370f-SketchLine_371f-SketchLine_372f-SketchLine_373f-SketchLine_374f-SketchLine_375f-SketchLine_376f-SketchLine_377f-SketchCircle_3_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_4_2f")], model.selection(), 30, 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
# Test reexecution after parameter change
Parameter_H.setValue(14)
model.do()
Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_7r-SketchLine_1r-SketchLine_2r-SketchLine_8r-SketchArc_1_2f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 0, 180)
ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_7r-SketchLine_1r-SketchLine_2r-SketchLine_8r-SketchArc_1_2f")], model.selection(), 0, 25, [model.selection("SOLID", "Revolution_1_1")])
-ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchLine_9 = Sketch_2.addLine(0, 20, -17.00000285538278, 20)
SketchLine_9.setName("SketchLine_13")
SketchConstraintDistance_4 = Sketch_2.setDistance(SketchLine_11.endPoint(), SketchLine_10.result(), 20)
model.do()
ExtrusionFuse_2 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_13f-SketchLine_9f-SketchLine_10f-SketchLine_14f-SketchArc_2_2f")], model.selection(), 0, 25, [model.selection("SOLID", "ExtrusionFuse_1_1")])
-ExtrusionFuse_2.result().setName("ExtrusionFuse_2_1")
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_2_1/Modfied_8"))
SketchLine_15 = Sketch_3.addLine(0, -20, -17.00000002635728, -20)
SketchLine_15.setName("SketchLine_19")
SketchConstraintDistance_7 = Sketch_3.setDistance(SketchLine_21.startPoint(), SketchLine_18.result(), 3)
model.do()
RevolutionFuse_1 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection("EDGE", "Sketch_3/Edge-SketchLine_21"), 71, 0, [model.selection("SOLID", "ExtrusionFuse_2_1")])
-RevolutionFuse_1.result().setName("RevolutionFuse_1_1")
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "RevolutionFuse_1_1/Modfied_7"))
SketchLine_22 = Sketch_4.addLine(-3, -20, 17.00000452949485, -20)
SketchLine_22.setName("SketchLine_26")
SketchConstraintDistance_11 = Sketch_4.setDistance(SketchLine_23.startPoint(), SketchLine_29.result(), 3)
model.do()
RevolutionFuse_2 = model.addRevolutionFuse(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchLine_26f-SketchLine_22f-SketchLine_23f-SketchLine_27f-SketchArc_4_2f")], model.selection("EDGE", "Sketch_4/Edge-SketchLine_29"), 0, 71, [model.selection("SOLID", "RevolutionFuse_1_1")])
-RevolutionFuse_2.result().setName("RevolutionFuse_2_1")
Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
SketchLine_30 = Sketch_5.addLine(0, 0, 0, 82)
SketchLine_31 = Sketch_5.addLine(model.selection("EDGE", "PartSet/OZ"))
SketchConstraintDistance_15.setName("SketchConstraintDistance_16")
model.do()
RevolutionFuse_3 = model.addRevolutionFuse(Part_1_doc, [model.selection("WIRE", "Sketch_5/Wire-SketchLine_30r-SketchLine_39r-SketchLine_32r-SketchLine_40r-SketchLine_38r-SketchArc_6_2f-SketchArc_7_2r")], model.selection("EDGE", "PartSet/OZ"), 45, 315, [model.selection("SOLID", "RevolutionFuse_2_1")])
-RevolutionFuse_3.result().setName("RevolutionFuse_3_1")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
SketchLine_38 = Sketch_6.addLine(19.99999999999999, 60, -20, 60)
SketchLine_38.setName("SketchLine_48")
SketchConstraintCoincidence_84.setName("SketchConstraintCoincidence_156")
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), 100, 0, [model.selection("SOLID", "RevolutionFuse_3_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
SketchLine_50 = Sketch_7.addLine(65, 23.09999999999939, 65, 23.00000523211526)
SketchLine_50.setName("SketchLine_61")
SketchLine_54.setAuxiliary(True)
SketchConstraintCoincidence_86 = Sketch_7.setCoincident(SketchLine_52.endPoint(), SketchLine_54.startPoint())
SketchConstraintCoincidence_86.setName("SketchConstraintCoincidence_96")
-SketchLine_55 = Sketch_7.addLine(model.selection("EDGE", "RevolutionFuse_3_1/Modfied_13&RevolutionFuse_3_1/Modfied_10"))
+SketchLine_55 = Sketch_7.addLine(model.selection("EDGE", "RevolutionFuse_3_1/Modfied_11&RevolutionFuse_3_1/Modfied_8"))
SketchLine_55.setName("SketchLine_56")
SketchLine_55.result().setName("SketchLine_56")
SketchConstraintCoincidence_87 = Sketch_7.setCoincident(SketchLine_54.endPoint(), SketchLine_55.result())
SketchConstraintDistance_21.setName("SketchConstraintDistance_23")
model.do()
RevolutionFuse_4 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection("EDGE", "PartSet/OZ"), 14.4, 14.4, [model.selection("SOLID", "ExtrusionCut_1_1")])
-RevolutionFuse_4.result().setName("RevolutionFuse_4_1")
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
SketchCircle_1 = Sketch_8.addCircle(0, 45, 12.5)
SketchLine_60 = Sketch_8.addLine(model.selection("EDGE", "Sketch_5/Edge-SketchLine_30"))
SketchConstraintRadius_8.setName("SketchConstraintRadius_13")
model.do()
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchCircle_1_2f")], model.selection(), 100, 100, [model.selection("SOLID", "RevolutionFuse_4_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_9 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
SketchLine_62 = Sketch_9.addLine(0, 84, 0, -2)
SketchLine_62.setName("SketchLine_65")
SketchLine_77 = Sketch_10.addLine(64, 20, 89, 20)
SketchLine_77.setName("SketchLine_76")
SketchLine_77.result().setName("SketchLine_76")
-SketchPoint_4 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_2_1/Modfied_11&RevolutionFuse_2_1/Modfied_15&RevolutionFuse_3_1/Modfied_15&RevolutionFuse_3_1/Modfied_4"))
+SketchPoint_4 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_2_1/Modfied_9&RevolutionFuse_2_1/Modfied_12&RevolutionFuse_3_1/Modfied_12&RevolutionFuse_3_1/Modfied_1divided_f_1"))
SketchConstraintCoincidence_122 = Sketch_10.setCoincident(SketchLine_77.startPoint(), SketchPoint_4.result())
SketchConstraintCoincidence_122.setName("SketchConstraintCoincidence_120")
SketchPoint_5 = Sketch_10.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_8e-SketchLine_4e"))
SketchLine_78 = Sketch_10.addLine(64, -20, 89, -20)
SketchLine_78.setName("SketchLine_77")
SketchLine_78.result().setName("SketchLine_77")
-SketchPoint_6 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_1_1/Modfied_4&RevolutionFuse_1_1/Modfied_10&RevolutionFuse_3_1/Modfied_17&RevolutionFuse_3_1/Modfied_8"))
+SketchPoint_6 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_1_1/Modfied_4&RevolutionFuse_1_1/Modfied_10&RevolutionFuse_3_1/Modfied_13&RevolutionFuse_3_1/Modfied_1divided_f_2"))
SketchConstraintCoincidence_124 = Sketch_10.setCoincident(SketchLine_78.startPoint(), SketchPoint_6.result())
SketchConstraintCoincidence_124.setName("SketchConstraintCoincidence_122")
-SketchPoint_7 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_3&RevolutionFuse_1_1/Modfied_4&ExtrusionFuse_2_1/Modfied_4&RevolutionFuse_3_1/Modfied_17"))
+SketchPoint_7 = Sketch_10.addPoint(model.selection("VERTEX", "ExtrusionFuse_2_1/Modfied_3&RevolutionFuse_1_1/Modfied_4&ExtrusionFuse_2_1/Modfied_4&RevolutionFuse_3_1/Modfied_13"))
SketchConstraintCoincidence_125 = Sketch_10.setCoincident(SketchLine_78.endPoint(), SketchPoint_7.result())
SketchConstraintCoincidence_125.setName("SketchConstraintCoincidence_123")
SketchArc_10 = Sketch_10.addArc(89.00000104846708, 1.669244441022778e-015, 89, -20, 89, 20, False)
SketchConstraintCoincidence_129.setName("SketchConstraintCoincidence_127")
SketchConstraintTangent_19 = Sketch_10.setTangent(SketchArc_11.results()[1], SketchLine_78.result())
SketchConstraintTangent_19.setName("SketchConstraintTangent_24")
-SketchPoint_8 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_3_1/Modfied_9&RevolutionFuse_3_1/Modfied_8&ExtrusionCut_2_1/Modfied_5&RevolutionFuse_3_1/Modfied_7&RevolutionFuse_3_1/Modfied_24"))
+SketchPoint_8 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_1_1/Modfied_10&RevolutionFuse_3_1/Modfied_7&RevolutionFuse_3_1/Modfied_1divided_f_2"))
SketchConstraintCoincidence_130 = Sketch_10.setCoincident(SketchArc_11.endPoint(), SketchPoint_8.result())
SketchConstraintCoincidence_130.setName("SketchConstraintCoincidence_128")
SketchArc_12 = Sketch_10.addArc(64.00001789135865, 23.01137360115889, 64, 20, 61.15622559702543, 22.02080994708722, True)
SketchConstraintCoincidence_131.setName("SketchConstraintCoincidence_129")
SketchConstraintTangent_20 = Sketch_10.setTangent(SketchArc_12.results()[1], SketchLine_77.result())
SketchConstraintTangent_20.setName("SketchConstraintTangent_25")
-SketchPoint_9 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_3_1/Modfied_5&RevolutionFuse_3_1/Modfied_4&ExtrusionCut_2_1/Modfied_5&RevolutionFuse_3_1/Modfied_3&RevolutionFuse_3_1/Modfied_24"))
+SketchPoint_9 = Sketch_10.addPoint(model.selection("VERTEX", "RevolutionFuse_2_1/Modfied_12&RevolutionFuse_3_1/Modfied_4&RevolutionFuse_3_1/Modfied_1divided_f_1"))
SketchConstraintCoincidence_132 = Sketch_10.setCoincident(SketchArc_12.endPoint(), SketchPoint_9.result())
SketchConstraintCoincidence_132.setName("SketchConstraintCoincidence_130")
SketchLine_79 = Sketch_10.addLine(61.15622559702543, 22.02080994708722, 59.81204392543111, 22.0208099470871)
SketchArc_13.results()[1].setName("SketchArc_16_2")
model.do()
ExtrusionFuse_3 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_10/Face-SketchArc_16_2f-SketchLine_81r-SketchLine_82f-SketchArc_17_2r-SketchLine_83f-SketchLine_84f-SketchLine_85r-SketchArc_18_2r"), model.selection("FACE", "Sketch_10/Face-SketchArc_19_2f-SketchLine_86r-SketchLine_87f-SketchArc_20_2r-SketchLine_88f-SketchLine_89f-SketchLine_90r-SketchArc_21_2r")], model.selection(), 20, 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionFuse_3.result().setName("ExtrusionFuse_3_1")
Sketch_11 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
SketchCircle_2 = Sketch_11.addCircle(89, 0, 6)
SketchPoint_11 = Sketch_11.addPoint(model.selection("VERTEX", "Sketch_2/Vertex-SketchPoint_1-SketchLine_10s-SketchLine_9e"))
[SketchCircle_4, SketchCircle_5, SketchCircle_6, SketchCircle_7] = SketchMultiRotation_2.rotated()
model.do()
RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "PartSet/OZ"), 0, 360, [model.selection("SOLID", "ExtrusionFuse_3_1")])
-RevolutionCut_1.result().setName("RevolutionCut_1_1")
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_4_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_5_2f")], model.selection(), 30, -15, [model.selection("SOLID", "RevolutionCut_1_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_2_2f"), model.selection("FACE", "Sketch_11/Face-SketchCircle_6_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_7_2f")], model.selection(), 30, 2, [model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
# Test reexecution after parameter change
Parameter_R.setValue(5)
model.do()
-model.testResultsVolumes(ExtrusionCut_4, [502615.944655187719035893678665161])
+model.testResultsVolumes(ExtrusionCut_4, [502616.749082866765093058347702026])
Parameter_R.setValue(3)
model.end()
model.testNbSubResults(ExtrusionCut_4, [0])
model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.SOLID, [1])
model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.FACE, [81])
-model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.EDGE, [406])
-model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.VERTEX, [812])
-model.testResultsVolumes(ExtrusionCut_4, [502902.431481667619664222002029419])
+model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.EDGE, [410])
+model.testNbSubShapes(ExtrusionCut_4, GeomAPI_Shape.VERTEX, [820])
+model.testResultsVolumes(ExtrusionCut_4, [502903.236060981987975537776947021])
assert(model.checkPythonDump())
SketchConstraintCoincidence_26.setName("SketchConstraintCoincidence_30")
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_3_2r-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchLine_21r-SketchLine_22r")], model.selection(), 7, 15, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_9"))
SketchLine_21 = Sketch_3.addLine(28, -6, -4.270492394552598, -6.000000000000001)
SketchLine_21.setName("SketchLine_23")
SketchConstraintEqual_2 = Sketch_3.setEqual(SketchLine_30.result(), SketchLine_25.result())
model.do()
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
SketchLine_37 = Sketch_4.addLine(0.4324637622511017, 3.581086955422081, 1.55585595716119, 2.812450190483599)
SketchLine_37.setName("SketchLine_39")
SketchLine_41.result().setName("SketchLine_43")
model.do()
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
-Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_6&ExtrusionCut_3_1/Modfied_3"))
Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchArc_4 = Sketch_5.addArc(25.00007393928819, -7.521062532210847, 22.00014787857639, -7.5, 28, -7.5, True)
SketchPoint_5 = Sketch_5.addPoint(22.00014787857639, -7.5)
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_3"), 6, True)
Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 3, True)
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), 3, 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), model.selection("FACE", "Plane_3"), 0, model.selection("FACE", "Plane_2"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_6"))
SketchArc_5 = Sketch_6.addArc(45.99999999999999, 0, 45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019, False)
SketchLine_53 = Sketch_6.addLine(0, 0, 54, 0)
SketchLine_56.result().setName("SketchLine_58")
model.do()
ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
-ExtrusionFuse_1.result().setName("ExtrusionFuse_1_1")
-Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_9"))
SketchLine_64 = Sketch_7.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
SketchLine_64.setName("SketchLine_76")
SketchLine_64.result().setName("SketchLine_76")
SketchConstraintRadius_8 = Sketch_7.setRadius(SketchArc_17.results()[1], 0.25)
model.do()
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionFuse_1_1")])
-ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
-Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_17"))
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_10"))
SketchPoint_12 = Sketch_8.addPoint(53.99994409538203, -1.615587133892632e-027)
SketchPoint_13 = Sketch_8.addPoint(53.99994409538203, -1.615587133892632e-027)
SketchConstraintRigid_7 = Sketch_8.setFixed(SketchPoint_13.result())
SketchConstraintCoincidence_141.setName("SketchConstraintCoincidence_145")
model.do()
ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_6_1")])
-ExtrusionCut_7.result().setName("ExtrusionCut_7_1")
-Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_56"))
+Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_32"))
SketchLine_94 = Sketch_9.addLine(21.00014787857639, 4.163450069699051, 21.00014787857639, 0)
SketchLine_94.setName("SketchLine_107")
SketchLine_94.result().setName("SketchLine_107")
Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 4, False)
Plane_8 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_2"), 4, True)
ExtrusionCut_8 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection(), model.selection("FACE", "Plane_5"), 0, model.selection("FACE", "Plane_4"), 0, [model.selection("SOLID", "ExtrusionCut_7_1")])
-ExtrusionCut_8.result().setName("ExtrusionCut_8_1")
Sketch_10 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_8_1/Modfied_5"))
SketchCircle_1 = Sketch_10.addCircle(12, 6, 1)
SketchConstraintRadius_11 = Sketch_10.setRadius(SketchCircle_1.results()[1], 1)
SketchConstraintDistance_17 = Sketch_10.setDistance(SketchLine_105.result(), SketchCircle_1.center(), 12)
model.do()
ExtrusionCut_9 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
-ExtrusionCut_9.result().setName("ExtrusionCut_9_1")
model.do()
Part_2 = model.addPart(partSet)
Part_2_doc = Part_2.document()
SketchConstraintCoincidence_199.setName("SketchConstraintCoincidence_30")
model.do()
ExtrusionCut_10 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_3_2r-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchLine_21r-SketchLine_22r")], model.selection(), 7, 15, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_10.result().setName("ExtrusionCut_1_1")
Sketch_13 = model.addSketch(Part_2_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_9"))
SketchLine_127 = Sketch_13.addLine(28, -6, -4.270492394552598, -6.000000000000001)
SketchLine_127.setName("SketchLine_23")
SketchConstraintEqual_5 = Sketch_13.setEqual(SketchLine_136.result(), SketchLine_131.result())
model.do()
ExtrusionCut_11 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_4"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_11.result().setName("ExtrusionCut_2_1")
Sketch_14 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
SketchLine_143 = Sketch_14.addLine(0.4324637622511017, 3.581086955422081, 1.55585595716119, 2.812450190483599)
SketchLine_143.setName("SketchLine_39")
SketchLine_147.result().setName("SketchLine_43")
model.do()
ExtrusionCut_12 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_12.result().setName("ExtrusionCut_3_1")
-Plane_9 = model.addPlane(Part_2_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
+Plane_9 = model.addPlane(Part_2_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_1"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_6&ExtrusionCut_3_1/Modfied_3"))
Sketch_15 = model.addSketch(Part_2_doc, model.selection("FACE", "Plane_1"))
SketchArc_27 = Sketch_15.addArc(25.00007393928819, -7.521062532210847, 22.00014787857639, -7.5, 28, -7.5, True)
SketchPoint_29 = Sketch_15.addPoint(22.00014787857639, -7.5)
Plane_10 = model.addPlane(Part_2_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_3"), 6, True)
Plane_11 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 3, True)
ExtrusionCut_13 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), 3, 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_13.result().setName("ExtrusionCut_4_1")
ExtrusionCut_14 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), model.selection("FACE", "Plane_3"), 0, model.selection("FACE", "Plane_2"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
-ExtrusionCut_14.result().setName("ExtrusionCut_5_1")
Sketch_16 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_6"))
SketchArc_28 = Sketch_16.addArc(45.99999999999999, 0, 45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019, False)
SketchLine_159 = Sketch_16.addLine(0, 0, 54, 0)
SketchLine_162.result().setName("SketchLine_58")
model.do()
ExtrusionFuse_2 = model.addExtrusionFuse(Part_2_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
-ExtrusionFuse_2.result().setName("ExtrusionFuse_1_1")
-Sketch_17 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
+Sketch_17 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_9"))
SketchLine_170 = Sketch_17.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
SketchLine_170.setName("SketchLine_76")
SketchLine_170.result().setName("SketchLine_76")
SketchConstraintRadius_19 = Sketch_17.setRadius(SketchArc_40.results()[1], 0.25)
model.do()
ExtrusionCut_15 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionFuse_1_1")])
-ExtrusionCut_15.result().setName("ExtrusionCut_6_1")
-Sketch_18 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_17"))
+Sketch_18 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_10"))
SketchPoint_36 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
SketchPoint_37 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
SketchConstraintRigid_20 = Sketch_18.setFixed(SketchPoint_37.result())
SketchConstraintCoincidence_314.setName("SketchConstraintCoincidence_145")
model.do()
ExtrusionCut_16 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_6_1")])
-ExtrusionCut_16.result().setName("ExtrusionCut_7_1")
-Sketch_19 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_56"))
+Sketch_19 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_32"))
SketchLine_200 = Sketch_19.addLine(21.00014787857639, 4.163450069699051, 21.00014787857639, 0)
SketchLine_200.setName("SketchLine_107")
SketchLine_200.result().setName("SketchLine_107")
Plane_12 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, False)
Plane_13 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, True)
ExtrusionCut_17 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection(), model.selection("FACE", "Plane_5"), 0, model.selection("FACE", "Plane_4"), 0, [model.selection("SOLID", "ExtrusionCut_7_1")])
-ExtrusionCut_17.result().setName("ExtrusionCut_8_1")
Sketch_20 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_8_1/Modfied_5"))
SketchCircle_2 = Sketch_20.addCircle(12, 6, 1)
SketchConstraintRadius_22 = Sketch_20.setRadius(SketchCircle_2.results()[1], 1)
SketchConstraintDistance_34 = Sketch_20.setDistance(SketchLine_211.result(), SketchCircle_2.center(), 12)
model.do()
ExtrusionCut_18 = model.addExtrusionCut(Part_2_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
-ExtrusionCut_18.result().setName("ExtrusionCut_9_1")
model.do()
-Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "Part_1/ExtrusionCut_9_1/Modfied_1&ExtrusionCut_7_1/Modfied_57"), 180)
+Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "Part_1/ExtrusionCut_9_1/Modfied_1&ExtrusionCut_7_1/Modfied_33"), 180)
Placement_1 = model.addPlacement(partSet, [model.selection("COMPOUND", "Rotation_1/")], model.selection("FACE", "Rotation_1/ExtrusionCut_5_1/Modfied_1"), model.selection("FACE", "Part_1/ExtrusionCut_5_1/Modfied_1"), False, True)
-Rotation_2 = model.addRotation(partSet, [model.selection("COMPOUND", "Placement_1/")], model.selection("EDGE", "Part_1/ExtrusionCut_5_1/Modfied_8&ExtrusionCut_8_1/Modfied_3"), 7)
+Rotation_2 = model.addRotation(partSet, [model.selection("COMPOUND", "Placement_1/")], model.selection("EDGE", "Part_1/ExtrusionCut_5_1/Modfied_5&ExtrusionCut_8_1/Modfied_3"), 7)
Rotation_2.result().setColor(255, 85, 0)
model.end()
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_10f-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_4f-SketchLine_8f-SketchLine_9f-SketchArc_1_2r-SketchArc_2_2f")], model.selection(), "307/2.", "307/2.")
Extrusion_1.setName("Profil")
-Extrusion_1.result().setName("Extrusion_1_1")
Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"))
SketchLine_14 = Sketch_2.addLine(149.5, -2.3, 153.5, -2.3)
SketchPoint_1 = Sketch_2.addPoint(model.selection("VERTEX", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"))
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_6"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
ExtrusionCut_1.setName("Decoupe_Angle")
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"))
SketchLine_22 = Sketch_3.addLine(153.5, -10.3, 153.5, -8.3)
SketchLine_22.setName("SketchLine_29")
Sketch_3.result().setName("Sketch_4")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
ExtrusionCut_2.setName("Chamfrein_1")
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_5"))
SketchLine_30 = Sketch_4.addLine(-149.5, 10.3, -149.5, 8.3)
SketchLine_30.setName("SketchLine_35")
Sketch_4.setName("Sketch_5")
Sketch_4.result().setName("Sketch_5")
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_5")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_7"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"))
SketchLine_40 = Sketch_5.addLine(152.2999838762584, -21.04999053274691, 153.5, -21.04999053274714)
SketchLine_40.setName("SketchLine_58")
Sketch_5.setName("Sketch_6")
Sketch_5.result().setName("Sketch_6")
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_6/Wire-SketchArc_9_2f-SketchArc_10_2f-SketchLine_73r-SketchLine_74r-SketchLine_75r-SketchLine_76r"), model.selection("WIRE", "Sketch_6/Wire-SketchLine_58f-SketchLine_61f-SketchLine_60f-SketchLine_51f-SketchArc_4_2f-SketchArc_5_2f"), model.selection("WIRE", "Sketch_6/Wire-SketchLine_57f-SketchLine_47f-SketchLine_62f-SketchLine_63f-SketchArc_3_2f-SketchArc_6_2f")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_1"))
SketchArc_11 = Sketch_6.addArc(44.89, -23.54999053274703, 43.89, -23.54999053274703, 44.89, -22.54999053274703, False)
SketchArc_12 = Sketch_6.addArc(44.89, -13.54999053274703, 44.89, -14.54999053274703, 43.89, -13.54999053274703, False)
Sketch_6.setName("Sketch_7")
Sketch_6.result().setName("Sketch_7")
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchArc_20_2f-SketchArc_21_2f-SketchArc_22_2f-SketchArc_23_2f-SketchLine_91r-SketchLine_92f-SketchLine_93r-SketchLine_94f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_52_2f-SketchArc_53_2f-SketchArc_56_2f-SketchArc_57_2f-SketchLine_114r-SketchLine_115f-SketchLine_116r-SketchLine_121f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_44_2f-SketchArc_45_2f-SketchArc_48_2f-SketchArc_49_2f-SketchLine_107f-SketchLine_113f-SketchLine_117r-SketchLine_123r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_16_2f-SketchArc_17_2f-SketchArc_18_2f-SketchArc_19_2f-SketchLine_87f-SketchLine_88f-SketchLine_89r-SketchLine_90r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_11_2f-SketchArc_12_2f-SketchArc_14_2f-SketchLine_81f-SketchLine_82r-SketchLine_83f-SketchLine_84r-SketchArc_15_2f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_36_2f-SketchArc_38_2f-SketchArc_40_2f-SketchArc_41_2f-SketchLine_108r-SketchLine_119r-SketchLine_127f-SketchLine_129f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_37_2f-SketchArc_39_2f-SketchArc_42_2f-SketchArc_43_2f-SketchLine_118r-SketchLine_120f-SketchLine_122r-SketchLine_130f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_24_2f-SketchArc_25_2f-SketchArc_26_2f-SketchArc_27_2f-SketchLine_98f-SketchLine_100r-SketchLine_101f-SketchLine_103r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_30_2f-SketchArc_31_2f-SketchArc_34_2f-SketchArc_35_2f-SketchLine_95f-SketchLine_96r-SketchLine_97f-SketchLine_105r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_46_2f-SketchArc_47_2f-SketchArc_50_2f-SketchArc_51_2f-SketchLine_124f-SketchLine_125r-SketchLine_126f-SketchLine_128r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_54_2f-SketchArc_55_2f-SketchArc_58_2f-SketchArc_59_2f-SketchLine_109f-SketchLine_110r-SketchLine_111r-SketchLine_112f"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_28_2f-SketchArc_29_2f-SketchArc_32_2f-SketchArc_33_2f-SketchLine_99r-SketchLine_102f-SketchLine_104f-SketchLine_106r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_4_1")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_5_1/Modfied_1"))
SketchLine_126 = Sketch_7.addLine(-153.5, -37.049990532747, -152.3000099350335, -37.0499905327475)
SketchLine_126.setName("SketchLine_135")
Sketch_7.setName("Sketch_8")
Sketch_7.result().setName("Sketch_8")
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_5_1")])
-ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_2"))
SketchLine_134 = Sketch_8.addLine(0.85, 50.75, -0.85, 50.75)
SketchLine_134.setName("SketchLine_139")
Sketch_8.setName("Sketch_9")
Sketch_8.result().setName("Sketch_9")
ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchLine_147f-SketchLine_148f-SketchArc_64_2f-SketchArc_65_2f"), model.selection("FACE", "Sketch_9/Face-SketchLine_139f-SketchLine_141f-SketchArc_63_2f-SketchArc_62_2f"), model.selection("FACE", "Sketch_9/Face-SketchArc_66_2f-SketchArc_67_2f-SketchLine_149r-SketchLine_150r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_6_1")])
-ExtrusionCut_7.result().setName("ExtrusionCut_7_1")
model.do()
# Test reexecution after parameter change
partSet = model.moduleDocument()
Part_1 = model.addPart(partSet)
Part_1_doc = Part_1.document()
-model.addParameter(Part_1_doc, "dint", "58")
-model.addParameter(Part_1_doc, "thick", "16")
-model.addParameter(Part_1_doc, "length", "172")
+Parameter_dint = model.addParameter(Part_1_doc, "dint", "58")
+Parameter_thick = model.addParameter(Part_1_doc, "thick", "16")
+Parameter_length = model.addParameter(Part_1_doc, "length", "172")
Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
SketchLine_1 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OZ"))
SketchArc_1 = Sketch_1.addArc(-1.656176621148808e-020, 61, -36.69142117459658, 34.94736842105263, -1.927105092898643e-024, 106, True)
model.do()
Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_9_2f-SketchLine_11f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Revolution_1_1")])
-Boolean_1.result().setName("Boolean_1_1")
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
SketchLine_12 = Sketch_3.addLine(2.220446049250313e-016, 106, -4, 106)
SketchLine_13 = Sketch_3.addLine(-4, 106, -4, 67.34428877022477)
model.do()
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_12f-SketchLine_13f-SketchLine_17r-SketchLine_18r-SketchArc_10_2f")], model.selection(), "172/2", "172/2")
Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Boolean_2.result().setName("Boolean_2_1")
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_10"))
SketchLine_18 = Sketch_4.addLine(-65, 16, -65, -16)
SketchLine_18.setName("SketchLine_19")
SketchLine_18.result().setName("SketchLine_19")
SketchConstraintTangent_6 = Sketch_4.setTangent(SketchLine_21.result(), SketchArc_11.results()[1])
SketchConstraintTangent_7 = Sketch_4.setTangent(SketchArc_12.results()[1], SketchLine_20.result())
model.do()
-Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchArc_11_2f-SketchArc_12_2f-SketchLine_21f-SketchLine_22r")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), 0)
-MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], model.selection("EDGE", "Extrusion_1_1/To_Face_1&Extrusion_1_1/Generated_Face_2"), -130, 2)
-MultiTranslation_1.result().setName("MultiTranslation_1_1")
-Boolean_3 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_2_1")], [model.selection("COMPOUND", "MultiTranslation_1_1")])
-Boolean_3.result().setName("Boolean_3_1")
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchArc_11_2f-SketchArc_12_2f-SketchLine_21f-SketchLine_22r")], model.selection(), model.selection(), 0, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), 0)
+MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], model.selection("EDGE", "Extrusion_1_1/To_Face_1&Extrusion_1_1/Generated_Face_12"), -130, 2)
+Boolean_3 = model.addCut(Part_1_doc, [model.selection("SOLID", "Boolean_2_1")], [model.selection("COMPOUND", "LinearCopy_1_1")])
model.do()
+
+# Test reexecution after parameter change
+Parameter_dint.setValue(62)
+Parameter_thick.setValue(20)
+Parameter_length.setValue(200)
+model.do()
+model.testResultsVolumes(Boolean_3, [407959.406418853614013642072677612])
+Parameter_dint.setValue(58)
+Parameter_thick.setValue(16)
+Parameter_length.setValue(172)
+
model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Boolean_3, 1)
+model.testNbSubResults(Boolean_3, [0])
+model.testNbSubShapes(Boolean_3, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Boolean_3, GeomAPI_Shape.FACE, [32])
+model.testNbSubShapes(Boolean_3, GeomAPI_Shape.EDGE, [192])
+model.testNbSubShapes(Boolean_3, GeomAPI_Shape.VERTEX, [384])
+model.testResultsVolumes(Boolean_3, [305733.913411944580730050802230835])
+
+assert(model.checkPythonDump)
SketchConstraintDistance_6 = Sketch_4.setDistance(SketchPoint_6.coordinates(), SketchLine_86.result(), 24.5)
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_5"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection("EDGE", "PartSet/OX"), 0, 360, [model.selection("SOLID", "ExtrusionCut_1_1")])
-RevolutionCut_1.result().setName("RevolutionCut_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 0, 5, [model.selection("SOLID", "RevolutionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
model.do()
# Test reexecution after parameter change
Face_2 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_2_2")])
Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1")], model.selection(), 2, 0)
-Extrusion_2.result().setName("Extrusion_2_1")
-Extrusion_2.results()[1].setName("Extrusion_2_2")
-Extrusion_2.results()[2].setName("Extrusion_2_3")
Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2"), model.selection("SOLID", "Extrusion_2_3")], [])
-Boolean_1.result().setName("Boolean_1_1")
model.do()
# Test reexecution after parameter change
SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_12.result(), SketchCircle_4.center(), 8)
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_2/Wire-SketchCircle_1_2f"), model.selection("WIRE", "Sketch_2/Wire-SketchCircle_2_2r"), model.selection("WIRE", "Sketch_2/Wire-SketchCircle_3_2f")], model.selection(), 0, 15, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_4_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/From_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
SketchCircle_5 = Sketch_3.addCircle(20.99999999999342, 22.99999999999327, 19)
SketchConstraintRadius_4 = Sketch_3.setRadius(SketchCircle_5.results()[1], 19)
SketchConstraintDistance_12 = Sketch_5.setDistance(SketchCircle_8.center(), SketchLine_37.result(), 8)
model.do()
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_5/Wire-SketchLine_29f-SketchLine_30r-SketchLine_31r-SketchLine_32r-SketchArc_9_2f-SketchArc_10_2f-SketchArc_11_2f-SketchArc_12_2f")], model.selection(), 0, 15, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "ExtrusionCut_3_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
-ExtrusionCut_4.results()[1].setName("ExtrusionCut_4_2")
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchCircle_8_2f"), model.selection("FACE", "Sketch_5/Face-SketchCircle_9_2f")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionCut_4_1"), model.selection("SOLID", "ExtrusionCut_4_2")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
-ExtrusionCut_5.results()[1].setName("ExtrusionCut_5_2")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
SketchLine_38 = Sketch_6.addLine(-59, 44, -59, 2)
SketchLine_38.setName("SketchLine_39")
SketchLine_46 = SketchProjection_3.createdFeature()
SketchLine_46.setName("SketchLine_47")
SketchLine_46.result().setName("SketchLine_47")
-SketchProjection_4 = Sketch_6.addProjection(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_3&Extrusion_1_1/Generated_Face_5"))
+SketchProjection_4 = Sketch_6.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_1_1/Modfied_1"))
SketchLine_47 = SketchProjection_4.createdFeature()
SketchLine_47.setName("SketchLine_48")
SketchLine_47.result().setName("SketchLine_48")
SketchConstraintDistance_14 = Sketch_6.setDistance(SketchLine_38.startPoint(), SketchLine_47.result(), 17)
model.do()
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_5"), -2, model.selection(), -2, [model.selection("SOLID", "ExtrusionCut_5_2")])
-ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"))
SketchLine_49 = Sketch_7.addLine(0, -22.99999999998656, -76, -22.99999999998655)
SketchLine_49.setName("SketchLine_50")
SketchLine_49.result().setName("SketchLine_50")
SketchLine_49.setAuxiliary(True)
-SketchLine_50 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_4"))
+SketchLine_50 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_2"))
SketchLine_50.setName("SketchLine_51")
SketchLine_50.result().setName("SketchLine_51")
SketchConstraintCoincidence_74 = Sketch_7.setCoincident(SketchLine_49.startPoint(), SketchLine_50.result())
SketchLine_51.setName("SketchLine_52")
SketchLine_51.result().setName("SketchLine_52")
SketchLine_51.setAuxiliary(True)
-SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_4"))
+SketchLine_52 = Sketch_7.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_3"))
SketchLine_52.setName("SketchLine_53")
SketchLine_52.result().setName("SketchLine_53")
SketchConstraintCoincidence_76 = Sketch_7.setCoincident(SketchLine_51.startPoint(), SketchLine_52.result())
SketchLine_54 = SketchProjection_6.createdFeature()
SketchLine_54.setName("SketchLine_55")
SketchLine_54.result().setName("SketchLine_55")
-SketchProjection_7 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_4"))
+SketchProjection_7 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_3_1/Modfied_2"))
SketchLine_55 = SketchProjection_7.createdFeature()
SketchLine_55.setName("SketchLine_56")
SketchLine_55.result().setName("SketchLine_56")
SketchConstraintCoincidence_83 = Sketch_8.setCoincident(SketchLine_57.result(), SketchPoint_5.coordinates())
SketchConstraintCoincidence_83.setName("SketchConstraintCoincidence_84")
SketchConstraintPerpendicular_1 = Sketch_8.setPerpendicular(SketchLine_57.result(), SketchLine_56.result())
-SketchProjection_8 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_4"))
+SketchProjection_8 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&ExtrusionCut_4_2/Modfied_3"))
SketchLine_58 = SketchProjection_8.createdFeature()
SketchLine_58.setName("SketchLine_59")
SketchLine_58.result().setName("SketchLine_59")
-SketchProjection_9 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_7"))
+SketchProjection_9 = Sketch_8.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_1"))
SketchLine_59 = SketchProjection_9.createdFeature()
SketchLine_59.setName("SketchLine_60")
SketchLine_59.result().setName("SketchLine_60")
SketchConstraintDistance_16 = Sketch_8.setDistance(SketchCircle_11.center(), SketchCircle_12.center(), 16)
model.do()
Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchCircle_11_2f"), model.selection("FACE", "Sketch_8/Face-SketchCircle_12_2f")], model.selection(), 17, 0)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_4"), 38, True)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_2"), 38, True)
Sketch_9 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchLine_60 = Sketch_9.addLine(-14, -36.99999999998992, 0, -36.99999999998992)
SketchLine_60.setName("SketchLine_61")
SketchConstraintCoincidence_94.setName("SketchConstraintCoincidence_95")
model.do()
RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "Sketch_9/Edge-SketchLine_65"), 360, 0, [model.selection("SOLID", "Extrusion_3_1")])
-RevolutionCut_1.result().setName("RevolutionCut_1_1")
model.do()
from GeomAPI import GeomAPI_Shape
SketchConstraintLength_4 = Sketch_3.setLength(SketchLine_26.result(), "d7*coeff")
model.do()
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_24r-SketchLine_26r-SketchLine_27r-SketchLine_28r-SketchLine_29r")], model.selection(), model.selection("FACE", "Extrusion_2_1/Generated_Face_6"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_2_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_30r-SketchLine_31r-SketchLine_32r-SketchLine_33r")], model.selection(), model.selection("FACE", "Extrusion_1_1/To_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), "d3*coeff", True)
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
SketchProjection_5 = Sketch_4.addProjection(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"))
SketchConstraintRadius_7 = Sketch_5.setRadius(SketchCircle_1.results()[1], "r_trou")
model.do()
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchCircle_1_2f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_6"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
Sketch_6 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_6"))
SketchCircle_2 = Sketch_6.addCircle(70, -17.5, 5)
SketchLine_48 = Sketch_6.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_1"))
SketchConstraintDistance_24.setName("SketchConstraintDistance_25")
model.do()
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_16"), 0, model.selection(), 0, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"))
SketchLine_51 = Sketch_7.addLine(110, 21.46600893000899, 110, 7.22841614740048)
SketchLine_51.setAuxiliary(True)
[SketchArc_17, SketchLine_63, SketchLine_64, SketchArc_18, SketchLine_65, SketchLine_66] = SketchConstraintMirror_2.mirrored()
model.do()
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchArc_16_2r-SketchLine_61f-SketchLine_62r"), model.selection("FACE", "Sketch_7/Face-SketchArc_18_2r-SketchLine_65f-SketchLine_66r"), model.selection("FACE", "Sketch_7/Face-SketchArc_17_2r-SketchLine_64r-SketchLine_66r"), model.selection("WIRE", "Sketch_7/Wire-SketchArc_15_2r-SketchLine_54f-SketchLine_55r")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_10"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_5_1")], [model.selection("SOLID", "Extrusion_3_1"), model.selection("SOLID", "ExtrusionCut_3_1")])
-Boolean_1.result().setName("Boolean_1_1")
model.do()
from GeomAPI import GeomAPI_Shape
model.do()
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), "10*coeff", 0)
ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_3_2f")], model.selection(), "p_trou1*coeff", 0, [model.selection("SOLID", "Extrusion_1_1")])
-ExtrusionCut_1.result().setName("ExtrusionCut_1_1")
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_1_2r")], model.selection(), "p2_trou1*coeff", 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
-ExtrusionCut_2.result().setName("ExtrusionCut_2_1")
ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_4_2f")], model.selection(), "p_trou2*coeff", 0, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "ExtrusionCut_2_1")])
-ExtrusionCut_3.result().setName("ExtrusionCut_3_1")
-ExtrusionCut_3.results()[1].setName("ExtrusionCut_3_2")
ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_2_2r")], model.selection(), "p2_trou*coeff", 0, [model.selection("SOLID", "ExtrusionCut_3_2")])
-ExtrusionCut_4.result().setName("ExtrusionCut_4_1")
Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), "22.5*coeff", False)
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), "45*coeff", True)
Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
model.do()
Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_9r-SketchLine_12r-SketchLine_14r-SketchLine_26r-SketchLine_27r-SketchLine_28r")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), 0, model.selection(), 0)
Boolean_1 = model.addSmash(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], [model.selection("SOLID", "ExtrusionCut_4_1")])
-Boolean_1.result().setName("Boolean_1_1")
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchCircle_8_2f")], model.selection(), 10, 0, [model.selection("SOLID", "Boolean_1_1_1")])
-ExtrusionCut_5.result().setName("ExtrusionCut_5_1")
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_8_2f")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_5_1_1")])
-ExtrusionCut_6.result().setName("ExtrusionCut_6_1")
Axis_4 = model.addAxis(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1_2/Modfied_1"))
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchProjection_7 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OY"))
model.do()
Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_4/Wire-SketchLine_19f-SketchLine_20f-SketchLine_24f-SketchLine_21f-SketchLine_22f-SketchLine_23f")], model.selection(), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), 0, model.selection(), 0)
Boolean_2 = model.addSmash(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_6_1_1"), model.selection("SOLID", "Extrusion_4_1")], [model.selection("SOLID", "ExtrusionCut_6_1_2")])
-Boolean_2.result().setName("Boolean_2_1")
ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_9_2f")], model.selection(), 0, 10, [model.selection("SOLID", "Boolean_2_1_1")])
-ExtrusionCut_7.result().setName("ExtrusionCut_7_1")
ExtrusionCut_8 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_9_2f")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_7_1_1")])
-ExtrusionCut_8.result().setName("ExtrusionCut_8_1")
-Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Boolean_2_1_1/Modified_1"))
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Boolean_2_1_1/Modified_Face_1"))
SketchPoint_3 = Sketch_5.addPoint(model.selection("VERTEX", "PartSet/Origin"))
SketchPoint_3.setName("SketchPoint_2")
SketchPoint_3.result().setName("SketchPoint_2")
SketchConstraintRadius_14.setName("SketchConstraintRadius_12")
model.do()
ExtrusionCut_9 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-SketchCircle_10_2f")], model.selection(), 0, "10*coeff", [model.selection("SOLID", "Extrusion_6_1")])
-ExtrusionCut_9.result().setName("ExtrusionCut_9_1")
ExtrusionCut_10 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchArc_7_2r-SketchArc_10_2f-SketchLine_44r-SketchArc_12_2r-SketchArc_13_2r-SketchLine_48r-SketchLine_43f-SketchArc_14_2f"), model.selection("FACE", "Sketch_1/Face-SketchCircle_11_2f"), model.selection("WIRE", "Sketch_1/Wire-SketchLine_50f-SketchArc_15_2f-SketchArc_16_2r-SketchLine_51r-SketchArc_17_2r-SketchLine_52f"), model.selection("FACE", "Sketch_1/Face-SketchLine_53f-SketchArc_18_2r-SketchLine_54f-SketchArc_19_2r-SketchArc_20_2f-SketchLine_55r-SketchArc_21_2f-SketchArc_22_2r"), model.selection("FACE", "Sketch_1/Face-SketchArc_8_2r-SketchArc_9_2f-SketchLine_42r-SketchLine_45f-SketchLine_46r-SketchArc_11_2r")], model.selection(), model.selection("FACE", "ExtrusionCut_3_2/Modfied_1"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_8_1_2")])
Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_9_1/Modfied_1"))
SketchLine_50 = Sketch_8.addLine(37, 14.80042035331162, 37, -14)
SketchConstraintRadius_16.setName("SketchConstraintRadius_17")
model.do()
ExtrusionCut_12 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchArc_25_2r-SketchLine_67f-SketchLine_68f")], model.selection(), 0, "100*coeff", [model.selection("SOLID", "Extrusion_5_1")])
-ExtrusionCut_12.result().setName("ExtrusionCut_12_1")
model.do()
from GeomAPI import GeomAPI_Shape