ADD_SUBDIRECTORY (src/ConnectorPlugin)
ENDIF(${HAVE_SALOME})
+ADD_SUBDIRECTORY (test.models)
+
ENABLE_TESTING()
+IF(ADD_MODELS_TESTS)
+ ADD_CUSTOM_TARGET(run_unit_tests COMMAND ${CMAKE_CTEST_COMMAND} -C "${CMAKE_BUILD_TYPE}" -LE "models_tests")
+ENDIF(ADD_MODELS_TESTS)
+
# Add the uninstall target for eclipse IDE
if (CMAKE_GENERATOR MATCHES "NMake Makefiles")
configure_file("${CMAKE_SOURCE_DIR}/CMakeCommon/cmake_uninstall.cmake.in"
mkdir %ROOT_DIR%\build
cd %ROOT_DIR%\build
+REM Add -DADD_MODELS_TESTS=TRUE to enable test models
cmake %SRC_DIR% -G "Visual Studio 10 Win64" -DPYTHON_EXECUTABLE=%PYTHONHOME%\python.exe -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=%ROOT_DIR%\install
start "" %MSVC_EXE% SHAPER.sln
export TOOLS_DIR=$(pwd)
export HOME_OLD=$HOME
+# to use patched OCCT 7.1.0 for SHAPER
+export CUSTOM_CAS_ROOT=1
+export ENV_FOR_LAUNCH=1
+
source /dn64/series8x/work/init.sh 2016-12-26
export HOME=$HOME_OLD
export SHAPER_ROOT_DIR=$(cd ${SOURCES_DIR}/.. && pwd)/install
source ${TOOLS_DIR}/env_linux.sh
-source ${TOOLS_DIR}/env_salome.sh
\ No newline at end of file
+source ${TOOLS_DIR}/env_salome.sh
for (anIt = theValues.begin(); anIt != theValues.end(); anIt++) {
ModuleBase_ViewerPrsPtr aValue = *anIt;
ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aValue->object());
- if (theToValidate && aRes.get() && acceptSubShape(aValue->shape(), aRes))
- aSelected.append(aValue);
+ if (theToValidate && aRes.get()) {
+ if (myShapeTypeCombo->currentIndex() > 3)
+ aSelected.append(aValue);
+ else if (acceptSubShape(aValue->shape(), aRes))
+ aSelected.append(aValue);
+ }
}
AttributeSelectionListPtr aSelList =
myFeature->data()->selectionList(CollectionPlugin_Field::SELECTED_ID());
INCLUDE(Common)
INCLUDE(XMLProcessing)
+FIND_PACKAGE(SWIG REQUIRED)
+INCLUDE(${SWIG_USE_FILE})
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events
${PYTHON_INCLUDE_DIR})
Config_Translator.cpp
)
+SET(CMAKE_SWIG_FLAGS -threads -Wall)
+SET_SOURCE_FILES_PROPERTIES(ConfigAPI.i PROPERTIES CPLUSPLUS ON)
+SET_SOURCE_FILES_PROPERTIES(ConfigAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
+SET(SWIG_SCRIPTS
+ ${CMAKE_CURRENT_BINARY_DIR}/ConfigAPI.py
+)
+SET(SWIG_LINK_LIBRARIES
+ Config
+ ${PYTHON_LIBRARIES}
+)
+SWIG_ADD_MODULE(ConfigAPI python ConfigAPI.i ${PROJECT_HEADERS})
+SWIG_LINK_LIBRARIES(ConfigAPI ${SWIG_LINK_LIBRARIES})
+IF(WIN32)
+ SET_TARGET_PROPERTIES(_ConfigAPI PROPERTIES DEBUG_OUTPUT_NAME _ConfigAPI_d)
+ENDIF(WIN32)
+
+
SET(XML_RESOURCES
${CMAKE_CURRENT_BINARY_DIR}/plugins.xml
dataModel.xml
INSTALL(TARGETS Config DESTINATION ${SHAPER_INSTALL_BIN})
INSTALL(FILES ${XML_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
+
+INSTALL(TARGETS _ConfigAPI DESTINATION ${SHAPER_INSTALL_SWIG})
+INSTALL(FILES ${SWIG_SCRIPTS} DESTINATION ${SHAPER_INSTALL_SWIG})
--- /dev/null
+/* Config.i */
+
+%module ConfigAPI
+%{
+ #include "Config_swig.h"
+%}
+
+// to avoid error on this
+#define CONFIG_EXPORT
+
+%include "typemaps.i"
+%include "std_string.i"
+
+%include "Config_ModuleReader.h"
}
}
-void Config_ModuleReader::loadScript(const std::string& theFileName)
+void Config_ModuleReader::loadScript(const std::string& theFileName, bool theSendErr)
{
/* acquire python thread */
PyGILState_STATE gstate = PyGILState_Ensure();
Py_XDECREF(pvalue);
Py_XDECREF(ptraceback);
}
- Events_InfoMessage("Config_ModuleReader", anErrorMsg).send();
+ if (theSendErr)
+ Events_InfoMessage("Config_ModuleReader", anErrorMsg).send();
}
/* release python thread */
/// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform
CONFIG_EXPORT static void loadLibrary(const std::string& theLibName);
/// loads the python module with specified name
- CONFIG_EXPORT static void loadScript(const std::string& theFileName);
+ /// \param theFileName name of the script
+ /// \param theSendErr send error message in case of faile
+ CONFIG_EXPORT static void loadScript(const std::string& theFileName, bool theSendErr = true);
/*!
* Extends set of modules, used for dependency checking (if there is no
* required module in the set, a plugin will not be loaded)
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: Config_swig.h
+// Created: Jan 16, 2017
+// Author: Vitaly SMETANNIKOV
+
+#ifndef SRC_CONFIG_SWIG_H_
+#define SRC_CONFIG_SWIG_H_
+
+ #include "Config_ModuleReader.h"
+
+#endif /* SRC_CONFIG_SWIG_H_ */
<plugin library="CollectionPlugin" configuration="plugin-Collection.xml"/>
<plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
<plugin script="addons_Features" configuration="addons_Features.xml"/>
- <plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="Geometry"/>
+ <plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="GEOM"/>
<plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
@DEFAULT_SOLVER@
<!--
ModelHighAPI
GeomAPI
GeomAlgoAPI
- XAO
+ XAOShaper
)
SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES})
SketchConstraintRadius_4 = Sketch_2.setRadius(SketchArc_1.results()[1], 10)
model.do()
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_24f-SketchLine_28f-SketchLine_26f-SketchLine_27f-SketchArc_1_2f-SketchArc_2_2f-SketchArc_3_2f-SketchArc_4_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/To_Face_1"), -30, model.selection(), 0)
-Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "Extrusion_1_1/From_Face_1&Extrusion_1_1/Generated_Face_1"), "inclinaison")
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "Extrusion_1_1/From_Face_1&Extrusion_1_1/Generated_Face_8"), "inclinaison")
Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Rotation_1_1")], model.selection("EDGE", "PartSet/OZ"), "angle1")
Recover_1 = model.addRecover(Part_1_doc, Rotation_2, [Rotation_1.result()])
Rotation_3 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Recover_1_1")], model.selection("EDGE", "PartSet/OZ"), "angle2")
GeomAPI_Ax2.h
GeomAPI_Ax3.h
GeomAPI_Trsf.h
- GeomAPI_Angle.h
GeomAPI_Angle2d.h
GeomAPI_Wire.h
)
GeomAPI_Ax3.cpp
GeomAPI_IPresentable.cpp
GeomAPI_Trsf.cpp
- GeomAPI_Angle.cpp
GeomAPI_Angle2d.cpp
GeomAPI_Wire.cpp
)
+++ /dev/null
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File: GeomAPI_Angle.cpp
-// Created: 19 April 2016
-// Author: Artem ZHIDKOV
-
-#include <GeomAPI_Angle.h>
-#include <GeomAPI_Dir.h>
-#include <GeomAPI_Lin.h>
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_XYZ.h>
-
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_XYZ.hxx>
-
-/// \struct ThreePoints
-/// \brief Used to store info about angle point and state.
-struct ThreePoints {
- gp_Pnt myCenter;
- gp_Pnt myFirst;
- gp_Pnt mySecond;
- bool myReversed[2];
-};
-
-#define MY_ANGLE implPtr<ThreePoints>()
-#define PI 3.1415926535897932
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& theFirst,
- const std::shared_ptr<GeomAPI_Pnt>& theSecond)
-{
- ThreePoints* aResult = new ThreePoints;
- aResult->myCenter = gp_Pnt(theCenter->x(), theCenter->y(), theCenter->z());
- aResult->myFirst = gp_Pnt(theFirst->x(), theFirst->y(), theFirst->z());
- aResult->mySecond = gp_Pnt(theSecond->x(), theSecond->y(), theSecond->z());
- aResult->myReversed[0] = aResult->myReversed[1] = false;
- return aResult;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theStart1,
- const std::shared_ptr<GeomAPI_Pnt>& theEnd1,
- const std::shared_ptr<GeomAPI_Pnt>& theStart2,
- const std::shared_ptr<GeomAPI_Pnt>& theEnd2)
-{
- std::shared_ptr<GeomAPI_Lin> aLine1(new GeomAPI_Lin(theStart1, theEnd1));
- std::shared_ptr<GeomAPI_Lin> aLine2(new GeomAPI_Lin(theStart2, theEnd2));
- std::shared_ptr<GeomAPI_Pnt> aCenter = aLine1->intersect(aLine2);
- bool isParallel = !aCenter;
- if (isParallel)
- aCenter = theStart1;
- std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
- if (isParallel)
- aPoint1 = aPoint2 = theEnd1;
- else {
- aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
- aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
- }
- ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
- anAngle->myReversed[0] = aPoint1 == theStart1;
- anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
- return anAngle;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
-{
- std::shared_ptr<GeomAPI_Pnt> aCenter = theLine1->intersect(theLine2);
- if (!aCenter)
- aCenter = theLine1->location();
- double aCoeff = theReversed1 ? -1.0 : 1.0;
- std::shared_ptr<GeomAPI_Pnt> aPoint1(new GeomAPI_Pnt(
- aCenter->xyz()->added(theLine1->direction()->xyz()->multiplied(aCoeff))));
- aCoeff = theReversed2 ? -1.0 : 1.0;
- std::shared_ptr<GeomAPI_Pnt> aPoint2(new GeomAPI_Pnt(
- aCenter->xyz()->added(theLine2->direction()->xyz()->multiplied(aCoeff))));
- ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
- anAngle->myReversed[0] = theReversed1;
- anAngle->myReversed[1] = theReversed2;
- return anAngle;
-}
-
-
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine2)
- : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
- : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint2)
- : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
-{
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::center()
-{
- gp_Pnt aPnt = MY_ANGLE->myCenter;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::firstPoint()
-{
- gp_Pnt aPnt = MY_ANGLE->myFirst;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::secondPoint()
-{
- gp_Pnt aPnt = MY_ANGLE->mySecond;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-double GeomAPI_Angle::angleDegree()
-{
- return angleRadian() * 180.0 / PI;
-}
-
-double GeomAPI_Angle::angleRadian()
-{
- ThreePoints* anAngle = MY_ANGLE;
- gp_Dir aDir1(anAngle->myFirst.XYZ() - anAngle->myCenter.XYZ());
- gp_Dir aDir2(anAngle->mySecond.XYZ() - anAngle->myCenter.XYZ());
- return aDir1.Angle(aDir2);
-}
-
-bool GeomAPI_Angle::isReversed(int theIndex)
-{
- return MY_ANGLE->myReversed[theIndex & 0x1];
-}
+++ /dev/null
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File: GeomAPI_Angle.h
-// Created: 19 April 2016
-// Author: Artem ZHIDKOV
-
-#ifndef GeomAPI_Angle_H_
-#define GeomAPI_Angle_H_
-
-#include <GeomAPI_Interface.h>
-
-class GeomAPI_Lin;
-class GeomAPI_Pnt;
-
-/// \class GeomAPI_Angle
-/// \ingroup DataModel
-/// \brief Build an angle in 3D
-class GeomAPI_Angle : public GeomAPI_Interface
-{
-public:
- /// Creation of an angle defined by two lines' start, end points
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine2);
- /// Creation of an angle defined by two lines taking into account their orientation
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2);
- /// Creation of an angle defined by three points
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint2);
-
- /// Returns central point of the angle
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> center();
- /// Returns point on the first edge
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> firstPoint();
- /// Returns point on the second edge
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> secondPoint();
-
- /// Returns value of the angle in degrees
- GEOMAPI_EXPORT double angleDegree();
- /// Returns value of the angle in radians
- GEOMAPI_EXPORT double angleRadian();
-
- /// Returns \c true if the line is reversed during angle calculation.
- /// If theIndex = 0, the result corresponds to the first line,
- /// if theIndex = 1, the to the second line
- GEOMAPI_EXPORT bool isReversed(int theIndex);
-};
-
-#endif
-
double aFirst, aLast;
const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ if (aCurve.IsNull())
+ return false;
double A, B, C, D;
thePlane->coefficients(A, B, C, D);
GeomAPI
GeomAlgoImpl
ModelAPI
- XAO
+ XAOShaper
${CAS_OCAF}
${CAS_SHAPE}
${CAS_TKBO}
#include <BRep_Builder.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <Geom_Plane.hxx>
+#include <Geom_TrimmedCurve.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
return aStart;
}
+static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theInitialShapes)
+{
+ // Try to find edge lying on the one of original edges.
+ // First found edge will be taken as a start edge for the result wire
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theInitialShapes.begin();
+ for (; aFeatIt != theInitialShapes.end(); aFeatIt++) {
+ std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
+ const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
+ if (anEdge.ShapeType() != TopAbs_EDGE)
+ continue;
+
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+ aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+
+ TopExp_Explorer anExp(theShape, TopAbs_EDGE);
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Edge& aShapeEdge = TopoDS::Edge(anExp.Current());
+ double aF, aL;
+ Handle(Geom_Curve) aShapeCurve = BRep_Tool::Curve(aShapeEdge, aF, aL);
+ if (aShapeCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+ aShapeCurve = Handle(Geom_TrimmedCurve)::DownCast(aShapeCurve)->BasisCurve();
+
+ if (aCurve != aShapeCurve)
+ continue;
+
+ // the edge is found, search vertex
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(aShapeEdge, aV1, aV2);
+ return fabs(aF - aFirst) <= fabs(aL - aFirst) ? aV1 : aV2;
+ }
+ }
+
+ // start vertex is not found, use algorithm to search vertex with the greatest coordinates
+ return findStartVertex(theShape);
+}
+
void GeomAlgoAPI_SketchBuilder::createFaces(
const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
TopoDS_Wire aWire = TopoDS::Wire(aWireExp.Current());
// to make faces equal on different platforms, we will find
- // a vertex with greater coordinates and start wire from it
- TopoDS_Vertex aStartVertex = findStartVertex(aWire);
+ // a vertex lying on an edge with the lowest index in the list of initial edges
+ TopoDS_Vertex aStartVertex = findStartVertex(aWire, theFeatures);
TopoDS_Wire aNewWire;
aBuilder.MakeWire(aNewWire);
void Model_AttributeBoolean::setValue(bool theValue)
{
- Standard_Boolean aValue = theValue ? Standard_True : Standard_False;
+ Standard_Integer aValue = theValue ? 1 : 0;
if (!myIsInitialized || myBool->Get() != aValue) {
if (myBool.IsNull())
myBool = TDataStd_Integer::Set(myLab, 0);
bool Model_AttributeBoolean::value()
{
- return myIsInitialized && myBool->Get() == Standard_True ;
+ return myIsInitialized && myBool->Get() == 1;
}
Model_AttributeBoolean::Model_AttributeBoolean(TDF_Label& theLabel)
return theFlag;
}
+void Model_AttributeSelection::split(
+ ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType)
+{
+ TopTools_ListOfShape aSubs;
+ for(TopoDS_Iterator anExplorer(theNewShape); anExplorer.More(); anExplorer.Next()) {
+ if (!anExplorer.Value().IsNull() &&
+ anExplorer.Value().ShapeType() == theType) {
+ aSubs.Append(anExplorer.Value());
+ } else { // invalid case; bad result shape, so, impossible to split easily
+ aSubs.Clear();
+ break;
+ }
+ }
+ if (aSubs.Extent() > 1) { // ok to split
+ TopTools_ListIteratorOfListOfShape aSub(aSubs);
+ GeomShapePtr aSubSh(new GeomAPI_Shape);
+ aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+ setValue(theContext, aSubSh);
+ for(aSub.Next(); aSub.More(); aSub.Next()) {
+ GeomShapePtr aSubSh(new GeomAPI_Shape);
+ aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+ myParent->append(theContext, aSubSh);
+ }
+ }
+}
+
bool Model_AttributeSelection::update()
{
TDF_Label aSelLab = selectionLabel();
// shape type shoud not not changed: if shape becomes compound of such shapes, then split
if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
anOldShape.ShapeType() != aNewShape.ShapeType() &&
- aNewShape.ShapeType() == TopAbs_COMPOUND) {
- TopTools_ListOfShape aSubs;
- for(TopoDS_Iterator anExplorer(aNewShape); anExplorer.More(); anExplorer.Next()) {
- if (!anExplorer.Value().IsNull() &&
- anExplorer.Value().ShapeType() == anOldShape.ShapeType()) {
- aSubs.Append(anExplorer.Value());
- } else { // invalid case; bad result shape, so, impossible to split easily
- aSubs.Clear();
- break;
- }
- }
- if (aSubs.Extent() > 1) { // ok to split
- TopTools_ListIteratorOfListOfShape aSub(aSubs);
- GeomShapePtr aSubSh(new GeomAPI_Shape);
- aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
- setValue(aContext, aSubSh);
- for(aSub.Next(); aSub.More(); aSub.Next()) {
- GeomShapePtr aSubSh(new GeomAPI_Shape);
- aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
- myParent->append(aContext, aSubSh);
- }
- }
+ (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID))
+ {
+ split(aContext, aNewShape, anOldShape.ShapeType());
}
owner()->data()->sendAttributeUpdated(this); // send updated if shape is changed
}
if (aFaceCurve == aCurve) {
int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
anOrientations[anID] = anOrient;
- registerSubShape(
- selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, anOrientations,
- aSubNames, Handle(TDataStd_IntPackedMap)(), anOrient);
+
+ TDF_Label aLab = selectionLabel().FindChild(anID);
+ std::string aName = "Edge-" + Model_SelectionNaming::shortName(aConstr, 0);
+ TNaming_Builder aBuilder(aLab);
+ aBuilder.Generated(anEdge);
+ aMyDoc->addNamingName(aLab, aName.c_str());
+ TDataStd_Name::Set(aLab, aName.c_str());
+
+ if (anOrient != 0) {
+ // store the orientation of edge relatively to face if needed
+ TDataStd_Integer::Set(aLab, anOrient);
+ }
}
}
} else { // put vertices of the selected edge to sub-labels
// add edges to sub-label to support naming for edges selection
- TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX);
+ int aDelta = kSTART_VERTEX_DELTA;
int aTagIndex = anID + kSTART_VERTEX_DELTA;
- for(; anEdgeExp.More(); anEdgeExp.Next(), aTagIndex += kSTART_VERTEX_DELTA) {
+ for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX);
+ anEdgeExp.More();
+ anEdgeExp.Next(),
+ aTagIndex += kSTART_VERTEX_DELTA,
+ aDelta += kSTART_VERTEX_DELTA) {
TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current());
- std::stringstream anAdditionalName;
- registerSubShape(
- selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, anOrientations,
- aSubNames);
+ TDF_Label aLab = selectionLabel().FindChild(aTagIndex);
+ std::string aName = "Vertex-"
+ + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA);
+ TNaming_Builder aBuilder(aLab);
+ aBuilder.Generated(aV);
+ aMyDoc->addNamingName(aLab, aName.c_str());
+ TDataStd_Name::Set(aLab, aName.c_str());
}
}
}
// update scope to reset to a new one
myScope.Clear();
myRef.setValue(aModifierResFound);
+ // if context shape type is changed to more complicated and this context is selected, split
+ if (myParent &&!aSubShape.get() && aModifierResFound->shape().get() && aContext->shape().get())
+ {
+ TopoDS_Shape anOldShape = aContext->shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aNewShape = aModifierResFound->shape()->impl<TopoDS_Shape>();
+ if (!anOldShape.IsNull() && !aNewShape.IsNull() &&
+ anOldShape.ShapeType() != aNewShape.ShapeType() &&
+ (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) {
+ // prepare for split in "update"
+ TDF_Label aSelLab = selectionLabel();
+ split(aContext, aNewShape, anOldShape.ShapeType());
+ }
+ }
update(); // it must recompute a new sub-shape automatically
}
}
#include "Model_AttributeReference.h"
#include <ModelAPI_AttributeSelection.h>
#include <TDF_LabelMap.hxx>
+#include <TopoDS_Shape.hxx>
class Model_AttributeSelectionList;
/// Sets the parent attribute
void setParent(Model_AttributeSelectionList* theParent);
+ /// Splits theNewShape into sub-shapes of theType type (for the list parent of this attribute)
+ void split(ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType);
+
friend class Model_Data;
friend class Model_AttributeSelectionList;
};
if (aFirstCall) {
// to be sure that plugins are loaded,
// even before the first "createFeature" call (in unit tests)
+
LoadPluginsInfo();
// creation of the root document is always outside of the transaction, so, avoid checking it
setCheckTransactions(false);
{
if (myPluginsInfoLoaded) // nothing to do
return;
-
+ Config_ModuleReader::loadScript("salome.shaper.initConfig", false);
// Read plugins information from XML files
Config_ModuleReader aModuleReader(Config_FeatureMessage::MODEL_EVENT());
aModuleReader.readAll();
Test1512.py
TestDoubleArray.py
Test1757.py
+ Test1998.py
)
aPlane = aPartSet.addFeature("Plane")
aPlane.string("creation_method").setValue("by_other_plane")
aPlane.string("by_other_plane_option").setValue("by_distance_from_other")
-aPlane.selection("plane").selectSubShape("face", "Part_1/Extrusion_1_1/Generated_Face_3")
+aPlane.selection("plane").selectSubShape("face", "Part_1/Extrusion_1_1/Generated_Face_1")
aPlane.real("distance").setValue(0.001)
aPlane.boolean("reverse").setValue(False)
aSession.finishOperation()
--- /dev/null
+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(-106.3464837049742, -78.0445969125214, -108.0617495711835, 165.5231560891939)
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_1")])
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s")])
+model.end()
+
+assert(model.checkPythonDump())
// standard definitions
%include "typemaps.i"
%include "std_list.i"
+%include "std_pair.i"
%include "std_string.i"
%include "std_shared_ptr.i"
%template(RefAttrList) std::list<ModelHighAPI_RefAttr>;
%template(RefList) std::list<ModelHighAPI_Reference>;
+// std::pair -> []
+%template(ResultSubShapePair) std::pair<std::shared_ptr<ModelAPI_Result>, std::shared_ptr<GeomAPI_Shape> >;
+
// fix compilarion error: ‘res*’ was not declared in this scope
%typemap(freearg) const std::list<ModelHighAPI_RefAttr> & {}
//==================================================================================================
void ModelHighAPI_Selection::setName(const std::string& theName)
{
- if (myVariantType == VT_ResultSubShapePair)
- myResultSubShapePair.first->data()->setName(theName);
+ if (myVariantType == VT_ResultSubShapePair) {
+ std::shared_ptr<ModelAPI_Result> aResult = myResultSubShapePair.first;
+ if(!aResult.get()) {
+ return;
+ }
+ aResult->data()->setName(theName);
+ }
}
void ModelHighAPI_Selection::setColor(int theRed, int theGreen, int theBlue)
aDeflectionAttr->setValue(theValue);
}
-ModelHighAPI_Selection ModelHighAPI_Selection::subResult(int theIndex)
+int ModelHighAPI_Selection::numberOfSubs() const
+{
+ if (myVariantType != VT_ResultSubShapePair)
+ return 0;
+
+ ResultCompSolidPtr aCompSolid =
+ std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(myResultSubShapePair.first);
+ if (!aCompSolid)
+ return 0;
+
+ return aCompSolid->numberOfSubs();
+}
+
+ModelHighAPI_Selection ModelHighAPI_Selection::subResult(int theIndex) const
{
if (myVariantType != VT_ResultSubShapePair)
return ModelHighAPI_Selection();
MODELHIGHAPI_EXPORT
void setDeflection(double theValue);
- /// Return sub-result for ResultCompSolid
+ /// Returns the number of sub-elements.
MODELHIGHAPI_EXPORT
- ModelHighAPI_Selection subResult(int theIndex);
+ int numberOfSubs() const;
+
+ /// Returns the sub-result by zero-base index.
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Selection subResult(int theIndex) const;
private:
VariantType myVariantType;
//--------------------------------------------------------------------------------------
#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Tools.h>
+#include <ModelAPI_ResultParameter.h>
//--------------------------------------------------------------------------------------
ParametersAPI_Parameter::ParametersAPI_Parameter(
const std::shared_ptr<ModelAPI_Feature> & theFeature)
}
}
+void ParametersAPI_Parameter::setValue(const double theValue)
+{
+ // convert value to the expression string
+ std::ostringstream aValueStr;
+ aValueStr<<theValue;
+ fillAttribute(aValueStr.str(), expression());
+ execute();
+}
+
+double ParametersAPI_Parameter::value() {
+ ResultParameterPtr aRes =
+ std::dynamic_pointer_cast<ModelAPI_ResultParameter>(feature()->firstResult());
+ // it may raise an exception if result is invalid
+ return aRes->data()->real(ModelAPI_ResultParameter::VALUE())->value();
+}
+
ParametersAPI_Parameter::~ParametersAPI_Parameter()
{
}
ModelAPI_AttributeString, /** Comment */
)
+ /// Just sets the numeric value to the parameter (it resets the previous expression)
+ PARAMETERSAPI_EXPORT void setValue(const double theValue);
+ /// Returns the current value of the parameter: the expression result.
+ PARAMETERSAPI_EXPORT double value();
+
/// Dump wrapped feature
PARAMETERSAPI_EXPORT
virtual void dump(ModelHighAPI_Dumper& theDumper) const;
}
}
}
-
- ResultBodyPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObject);
- if( aResult.get() )
- theMenu->addAction(myMenuMgr->action("SELECT_PARENT_CMD"));
}
}
bool aNotDeactivate = (aCurrentOp == 0);
// Display sketcher objects
QStringList anInfo;
+ Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
FeaturePtr aFeature = myCurrentSketch->subFeature(i);
#ifdef DEBUG_SKETCHER_ENTITIES
std::list<ResultPtr> aResults = aFeature->results();
std::list<ResultPtr>::const_iterator aIt;
for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
- (*aIt)->setDisplayed(true);
+ if ((*aIt)->isDisplayed())
+ // Display object if it was created outside of GUI
+ aECreator->sendUpdated((*aIt), EVENT_DISP);
+ else
+ (*aIt)->setDisplayed(true);
}
- aFeature->setDisplayed(true);
+ if (aFeature->isDisplayed())
+ aECreator->sendUpdated(aFeature, EVENT_DISP);
+ else
+ aFeature->setDisplayed(true);
}
#ifdef DEBUG_SKETCHER_ENTITIES
QString anInfoStr = anInfo.join(";\t");
(aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
- /// check external line created on Trihedron Axis
- /// selection of a point on external edge referenced to AIS_Trihedron axis
- /// should be prohibited or point should be replaced to "Origin". The second
- /// case is implemented because of not correct AIS_Trihedron origin point highlight
- /// When AIS is corrected(exactly priority of origin and stayed vertex by highlight)
- /// the next check should be moved to Partset 2d point widget in isValidSelectionCustom
- bool isAxis = isAxisSelected(theObject);
- if (isAxis)
- aRes = ResultPtr(); // to rely on code below that found the Origin result
-
// if there is no object,
// it means that this is the origin point: search it in the module document
if (!aRes.get()) {
return ResultPtr();
}
-bool PartSet_Tools::isAxisSelected(const ObjectPtr& theObject)
-{
- bool isAxis = false;
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
- if (aRes.get()) {
- // check if result belongs to external feature
- // in this case we should use as a result reference of external feature
- FeaturePtr aResFeature = ModelAPI_Feature::feature(aRes);
- std::shared_ptr<SketchPlugin_Feature> aSPFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aResFeature);
- if (aSPFeature.get() && aSPFeature->isExternal()) {
- AttributeSelectionPtr aAttr = aResFeature->selection(
- SketchPlugin_SketchEntity::EXTERNAL_ID());
- if (aAttr) { /// check if the result is Axis
- ResultPtr anExternalRes = std::dynamic_pointer_cast<ModelAPI_Result>(aAttr->context());
- FeaturePtr aResFeature = ModelAPI_Feature::feature(anExternalRes);
- isAxis = aResFeature->getKind() == "Axis"; //ConstructionPlugin_Axis::ID()
- }
- }
- }
- return isAxis;
-}
-
bool PartSet_Tools::isContainPresentation(const QList<ModuleBase_ViewerPrsPtr>& theSelected,
const ModuleBase_ViewerPrsPtr& thePrs)
{
CompositeFeaturePtr theSketch,
const bool theTemporary = false);
-
- /// Checks if the shape is Origin, the conditions are the shape is a vertex and
- /// selected feature is an external feature created on Axis
- /// \param theObject a selected object in the viewer
- /// \return boolean value
- static bool isAxisSelected(const ObjectPtr& theObject);
-
/// Checks whether the list of selected presentations contains the given one
/// \param theSelected a list of presentations
/// \param thePrs a presentation to be found
std::shared_ptr<SketchPlugin_Feature> aSPFeature;
if (aSelectedFeature.get() != NULL)
aSPFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
- if ((!aSPFeature && !aShape.IsNull()) ||
- (aSPFeature.get() && aSPFeature->isExternal())) {
- ResultPtr aFixedObject;
+
+ ResultPtr aFixedObject;
+ bool aSketchExternalFeature = aSPFeature.get() && aSPFeature->isExternal();
+ if ((!aSPFeature && !aShape.IsNull()) || aSketchExternalFeature) {
+ aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
+ if (aSketchExternalFeature && !aFixedObject.get()) {/// local selection on external feature
+ anExternal = false;
+ }
+ else {
anExternal = true;
- aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
if (!aFixedObject.get())
aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
- double aX, aY;
- 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;
+ 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
+ setPoint(aX, aY);
+ }
+ else {
+ if (getPoint2d(aView, aShape, aX, aY))
setPoint(aX, aY);
- }
- else {
- if (getPoint2d(aView, aShape, aX, aY))
- setPoint(aX, aY);
- else
- setValueState(Stored); // in case of edge selection, Apply state should also be updated
- bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX ||
- isOrphanPoint(aSelectedFeature, mySketch, aX, aY);
- if (anExternal) {
- // we should not stop reentrant operation on external objects because
- anOrphanPoint = true;
- // they are not participate in the contour creation excepting external vertices
- if (aShape.ShapeType() == TopAbs_VERTEX) {
- FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject);
- if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) {
- anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY);
- }
- }
- else {
- // point is taken from mouse event and set in attribute.
- // It should be done before setting
- // coinident constraint to the external line. If a point is created, it should be
- // in the mouse clicked point
- gp_Pnt aPoint =
- PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
- double aX, anY;
- PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY);
- setPoint(aX, anY);
+ else
+ setValueState(Stored); // in case of edge selection, Apply state should also be updated
+ bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX ||
+ isOrphanPoint(aSelectedFeature, mySketch, aX, aY);
+ if (anExternal) {
+ // we should not stop reentrant operation on external objects because
+ anOrphanPoint = true;
+ // they are not participate in the contour creation excepting external vertices
+ if (aShape.ShapeType() == TopAbs_VERTEX) {
+ FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject);
+ if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) {
+ anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY);
}
}
- if (aFixedObject.get())
- setConstraintWith(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());
+ }
+ if (aFixedObject.get())
+ setConstraintWith(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());
- if (!anOrphanPoint)
- emit vertexSelected(); // it stops the reentrant operation
+ if (!anOrphanPoint)
+ emit vertexSelected(); // it stops the reentrant operation
- emit focusOutWidget(this);
- }
+ emit focusOutWidget(this);
}
+ }
if (!anExternal) {
double aX, aY;
bool isProcessed = false;
INSTALL(DIRECTORY geom model examples DESTINATION ${SHAPER_INSTALL_PYTHON_API})
INSTALL(FILES __init__.py DESTINATION ${SHAPER_INSTALL_PYTHON_API})
INSTALL(FILES __init__.py DESTINATION ${_pydir}/salome)
+INSTALL(FILES initConfig.py DESTINATION ${SHAPER_INSTALL_PYTHON_API})
# --------- Unit tests -----------
INCLUDE(UnitTest)
class SketcherAddArc(SketcherTestCase):
def test_arc_by_coords(self):
- arc = self.sketch.addArc(0, 1, 0, 0, 1, 1, 0)
+ arc = self.sketch.addArc(0, 1, 0, 0, 1, 1, False)
model.do()
self.assertEqual(arc.startPoint().x(), 0)
self.assertEqual(arc.startPoint().y(), 0)
center = geom.Pnt2d(0, 1)
start = geom.Pnt2d(0, 0)
end = geom.Pnt2d(1, 1)
- arc = self.sketch.addArc(center, start, end, 0)
+ arc = self.sketch.addArc(center, start, end, False)
model.do()
self.assertEqual(arc.startPoint().x(), 0)
self.assertEqual(arc.startPoint().y(), 0)
def test_modify_arc(self):
# Note: arc will modify startPoint and endPoint to be in circle
- arc = self.sketch.addArc(0, 1, 0, 0, 1, 1, 0)
- arc.setByCenterStartEnd(0, 0, 1, 1, -1, -1, 0)
+ arc = self.sketch.addArc(0, 1, 0, 0, 1, 1, False)
+ arc.setByCenterStartEnd(0, 0, 1, 1, -1, -1, False)
model.do()
self.assertEqual(arc.center().x(), 0)
self.assertEqual(arc.center().y(), 0)
def bottom_body():
# Create XOY sketch
- sketch = model.addSketch(part, "Extrusion_1_1/Generated_Face_3")
+ sketch = model.addSketch(part, "Extrusion_1_1/Generated_Face_5")
# Create base polygon
points = [(0, 0), (0, L), (P, L), (P, 16 + 16), (P - 20, 16 + 16), (P - 20, 16), (P, 16), (P, 0)]
sketch.setCoincident(arc.endPoint(), h1.startPoint())
# Binding
- left_e = sketch.addLine("Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1_1")
+ left_e = sketch.addLine("Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1_1")
sketch.setCoincident(left_e.startPoint(), left.endPoint())
sketch.setCoincident(left_e.endPoint(), left.startPoint())
def body_3():
# Create XOZ sketch
- sketch = model.addSketch(part, "Boolean_1_1/Modified_4")
+ sketch = model.addSketch(part, "Boolean_1_1/Modified_2")
# Create base polygon
H, L, l, r = 28, 40, 8, 12
sketch.setRadius(arc, r)
# Binding
- bottom_e = sketch.addLine("Boolean_1_1/Modified_5&Boolean_1_1/Modified_8")
+ bottom_e = sketch.addLine("Boolean_1_1/Modified_7&Boolean_1_1/Modified_5")
sketch.setCoincident(bottom_e, bottom.startPoint())
sketch.setCoincident(bottom_e.startPoint(), bottom.endPoint())
--- /dev/null
+"""This script inspects existing modules in SALOME and registrs them in
+Module reader
+"""
+
+import salome
+import SALOME_ModuleCatalog
+import ConfigAPI
+
+obj = salome.naming_service.Resolve('Kernel/ModulCatalog')
+catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
+aCorbaModules = catalog.GetComponentList()
+for aName in aCorbaModules:
+ ConfigAPI.Config_ModuleReader.addDependencyModule(aName)
from partset import *
from primitives import *
from gdml import *
+from tests import *
--- /dev/null
+from tests import *
\ No newline at end of file
--- /dev/null
+from GeomAlgoAPI import *
+import math
+
+
+def generateTests(theFeature, theFeatureName, theTestsList = []):
+ """ Generates tests for theFeature.
+ :param theFeature: feature to test. Should be ModelHighAPI_Interface.
+ :param theFeatureName: feature name to put in test commands.
+ :param theTestsList: list of test to be generated. If empty generates all tests.
+ """
+ if "testNbResults" in theTestsList or len(theTestsList) == 0:
+ aNbResults = len(theFeature.results())
+ print "model.testNbResults({}, {})".format(theFeatureName, aNbResults)
+
+ if "testNbSubResults" in theTestsList or len(theTestsList) == 0:
+ aNbResults = len(theFeature.results())
+ aNbSubResults = []
+ for anIndex in range(0, aNbResults):
+ aNbSubResults.append(theFeature.results()[anIndex].numberOfSubs())
+ print "model.testNbSubResults({}, {})".format(theFeatureName, aNbSubResults)
+
+ if "testResultsVolumes" in theTestsList or len(theTestsList) == 0:
+ aNbResults = len(theFeature.results())
+ aResultsVolumes = []
+ for anIndex in range(0, aNbResults):
+ aResultsVolumes.append(GeomAlgoAPI_ShapeTools_volume(theFeature.results()[anIndex].resultSubShapePair()[0].shape()))
+ print "model.testResultsVolumes({}, [{}])".format(theFeatureName, ", ".join("{:0.27f}".format(i) for i in aResultsVolumes))
+
+
+def testNbResults(theFeature, theExpectedNbResults):
+ """ Tests number of feature results.
+ :param theFeature: feature to test.
+ :param theExpectedNbResults: expected number of results.
+ """
+ aNbResults = len(theFeature.results())
+ assert (aNbResults == theExpectedNbResults), "Number of results: {}. Expected: {}.".format(aNbResults, theExpectedNbResults)
+
+
+def testNbSubResults(theFeature, theExpectedNbSubResults):
+ """ Tests number of feature sub-results for each result.
+ :param theFeature: feature to test.
+ :param theExpectedNbSubResults: list of sub-results numbers. Size of list should be equal to len(theFeature.results()).
+ """
+ aNbResults = len(theFeature.results())
+ aListSize = len(theExpectedNbSubResults)
+ assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
+ for anIndex in range(0, aNbResults):
+ aNbSubResults = theFeature.results()[anIndex].numberOfSubs()
+ anExpectedNbSubResults = theExpectedNbSubResults[anIndex]
+ assert (aNbSubResults == anExpectedNbSubResults), "Number of sub-results for result[{}]: {}. Expected: {}.".format(anIndex, aNbSubResults, anExpectedNbSubResults)
+
+
+def testResultsVolumes(theFeature, theExpectedResultsVolumes, theNbSignificantDigits = 10):
+ """ Tests results volumes.
+ :param theFeature: feature to test.
+ :param theExpectedResultsVolumes: list of results volumes. Size of list should be equal to len(theFeature.results()).
+ """
+ aNbResults = len(theFeature.results())
+ aListSize = len(theExpectedResultsVolumes)
+ assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
+ for anIndex in range(0, aNbResults):
+ aResultVolume = GeomAlgoAPI_ShapeTools_volume(theFeature.results()[anIndex].resultSubShapePair()[0].shape())
+ aResultVolumeStr = "{:0.27f}".format(aResultVolume).lstrip("0").lstrip(".").lstrip("0")
+ anExpectedResultVolume = theExpectedResultsVolumes[anIndex]
+ anExpectedResultVolumeStr = "{:0.27f}".format(anExpectedResultVolume).lstrip("0").lstrip(".").lstrip("0")
+ assert (aResultVolumeStr[:theNbSignificantDigits] == anExpectedResultVolumeStr[:theNbSignificantDigits]), "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
void SHAPERGUI::initialize(CAM_Application* theApp)
{
LightApp_Module::initialize(theApp);
- inspectSalomeModules();
myWorkshop->startApplication();
LightApp_Application* anApp = dynamic_cast<LightApp_Application*>(theApp);
application()->putInfo(theInfo, theMSecs);
}
-void SHAPERGUI::inspectSalomeModules()
-{
- QStringList aModuleNames;
- getApp()->modules(aModuleNames, false);
- foreach(QString eachModule, aModuleNames) {
- Config_ModuleReader::addDependencyModule(eachModule.toStdString());
- }
-}
-
bool SHAPERGUI::abortAllOperations()
{
return workshop()->operationMgr()->abortAllOperations();
/// \brief Set flag about opened document state
void setIsOpened(bool theOpened) { myIsOpened = theOpened; }
- /// Register current modules of SALOME
- void inspectSalomeModules();
-
public slots:
/// \brief The method is redefined to connect to the study viewer before the data
/// model is filled by opened file. This file open will flush redisplay signals for,
//--------------------------------------------------------------------------------------
#include "SketchAPI_Projection.h"
-//--------------------------------------------------------------------------------------
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Circle.h>
+
+#include <SketchAPI_Line.h>
+#include <SketchAPI_Circle.h>
+#include <SketchAPI_Arc.h>
+
#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Selection.h>
#include <ModelHighAPI_Tools.h>
}
//--------------------------------------------------------------------------------------
-std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Projection::createdFeature() const
+std::shared_ptr<SketchAPI_SketchEntity> SketchAPI_Projection::createdFeature() const
{
AttributeRefAttrPtr aProjectedRefAttr = projectedFeature();
FeaturePtr aProjectedFeature = ModelAPI_Feature::feature(aProjectedRefAttr->object());
+ std::shared_ptr<SketchAPI_SketchEntity> anEntity;
+
+ if(!aProjectedFeature.get()) {
+ return anEntity;
+ }
+
+ aProjectedFeature->getKind() == SketchPlugin_Line::ID() ?
+ anEntity.reset(new SketchAPI_Line(aProjectedFeature)) :
+ aProjectedFeature->getKind() == SketchPlugin_Circle::ID() ?
+ anEntity.reset(new SketchAPI_Circle(aProjectedFeature)) :
+ anEntity.reset(new SketchAPI_Arc(aProjectedFeature));
- return std::shared_ptr<ModelHighAPI_Interface>(new ModelHighAPI_Interface(aProjectedFeature));
+ return anEntity;
}
//--------------------------------------------------------------------------------------
/// Returns created feature
SKETCHAPI_EXPORT
- std::shared_ptr<ModelHighAPI_Interface> createdFeature() const;
+ std::shared_ptr<SketchAPI_SketchEntity> createdFeature() const;
/// Dump wrapped feature
SKETCHAPI_EXPORT
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_Session.h>
if (!anAIS)
anAIS = AISObjectPtr(new GeomAPI_AISObject);
anAIS->createShape(aShape);
- anAIS->setWidth(5);
+ std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
+ aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
+
+ bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
+
std::vector<int> aColor;
- aColor = Config_PropManager::color("Visualization", "sketch_entity_color",
- SKETCH_ENTITY_COLOR);
- anAIS->setColor(aColor[0], aColor[1], aColor[2]);
+ double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
+ int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
+ if (isConstruction) {
+ aColor = Config_PropManager::color("Visualization", "sketch_auxiliary_color",
+ SKETCH_AUXILIARY_COLOR);
+ aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
+ aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
+ }
+ else {
+ aColor = Config_PropManager::color("Visualization", "sketch_entity_color",
+ SKETCH_ENTITY_COLOR);
+ }
+ anAIS->setColor(aColor[0], aColor[1], aColor[2]);
+ anAIS->setWidth(aWidth + 1);
+ anAIS->setLineStyle(aLineStyle);
}
return anAIS;
}
void SketchPlugin_ConstraintSplit::fillAttribute(const AttributePtr& theModifiedAttribute,
const AttributePtr& theSourceAttribute)
{
- AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theModifiedAttribute);
- AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theSourceAttribute);
-
- if (aModifiedAttribute.get() && aSourceAttribute.get())
- aModifiedAttribute->setValue(aSourceAttribute->pnt());
+ std::string anAttributeType = theModifiedAttribute->attributeType();
+ if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
+ AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theModifiedAttribute);
+ AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSourceAttribute);
+
+ if (aModifiedAttribute.get() && aSourceAttribute.get())
+ aModifiedAttribute->setValue(aSourceAttribute->pnt());
+ }
+ else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
+ AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+ theModifiedAttribute);
+ AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+ theSourceAttribute);
+
+ if (aModifiedAttribute.get() && aSourceAttribute.get())
+ aModifiedAttribute->setValue(aSourceAttribute->value());
+ }
}
FeaturePtr SketchPlugin_ConstraintSplit::createLineFeature(const FeaturePtr& theBaseFeature,
fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr);
fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr);
+
+ fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
+ theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
+
aFeature->execute(); // to obtain result
return aFeature;
fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr);
fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr);
+ fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
+ theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
+
/// fill referersed state of created arc as it is on the base arc
if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
# --- rules ---
-ADD_LIBRARY(XAO SHARED ${XAO_SOURCES} ${XAO_HEADERS})
-TARGET_LINK_LIBRARIES(XAO ${PROJECT_LIBRARIES})
-INSTALL(TARGETS XAO DESTINATION ${SHAPER_INSTALL_BIN})
+ADD_LIBRARY(XAOShaper SHARED ${XAO_SOURCES} ${XAO_HEADERS})
+TARGET_LINK_LIBRARIES(XAOShaper ${PROJECT_LIBRARIES})
+INSTALL(TARGETS XAOShaper DESTINATION ${SHAPER_INSTALL_BIN})
# libraries to link to
SET(_link_LIBRARIES
${CPPUNIT_LIBRARIES}
- XAO
+ XAOShaper
)
# --- sources ---
{
setAllEnabled();
XGUI_Selection* aSelection = myWorkshop->selector()->selection();
- //if (aSelection->getSelected(ModuleBase_ISelection::Viewer).size() > 0)
- if (aSelection->getSelected().size() > 0)
+ if (aSelection->getSelected(ModuleBase_ISelection::AllControls).size() > 0)
updateOnViewSelection();
FeaturePtr anActiveFeature = FeaturePtr();
}
}
}
+ } else {
+ rebuildDataTree();
+ break;
}
} else {
rebuildDataTree();
XGUI_Displayer* aDisplayer = myWorkshop->displayer();
for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner();
- try {
- // It is checking of existence of presentation object
- // BUG of OCCT
- Handle(AIS_InteractiveObject) aTest = aContext->DetectedInteractive();
- } catch (...) {
- continue;
- }
if (!anOwner.IsNull()) {
if (aSelectedIds.contains((long)anOwner.get()))
continue;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
+ module()->closeDocument();
SessionPtr aSession = ModelAPI_Session::get();
aSession->closeAll();
aSession->load(myCurrentDir.toLatin1().constData());
else if (theId == "SHOW_CMD") {
showObjects(aObjects, true);
mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
+ updateCommandStatus();
}
- else if (theId == "HIDE_CMD")
+ else if (theId == "HIDE_CMD") {
showObjects(aObjects, false);
+ updateCommandStatus();
+ }
else if (theId == "SHOW_ONLY_CMD") {
showOnlyObjects(aObjects);
mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
+ updateCommandStatus();
}
else if (theId == "SHADING_CMD")
setDisplayMode(aObjects, XGUI_Displayer::Shading);
aObj->setDisplayed(false);
}
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ updateCommandStatus();
} else if (theId == "SELECT_VERTEX_CMD") {
setViewerSelectionMode(TopAbs_VERTEX);
} else if (theId == "SELECT_EDGE_CMD") {
if (DFBrowser_FirstCall) {
Handle(CDF_Application) anApplication = CDF_Session::CurrentSession()->CurrentApplication();
DFBrowserAPI_Communicator* aCommunicator =
- DFBrowserAPI_Communicator::loadPluginLibrary("DFBrowser.dll");
- aCommunicator->setApplication(anApplication);
+ DFBrowserAPI_Communicator::loadPluginLibrary("TKDFBrowser.dll");
+ if (aCommunicator) {
+ aCommunicator->setApplication(anApplication);
+ Handle(AIS_InteractiveContext) aContext = viewer()->AISContext();
+ if (aContext)
+ aCommunicator->setContext(aContext);
+ }
DFBrowser_FirstCall = false;
}
}
void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
{
foreach (ObjectPtr aObj, theList) {
- /*
- ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
- if (aPartRes) {
- DocumentPtr aDoc = aPartRes->partDoc();
- SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), isVisible)
- SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), isVisible)
- SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), isVisible)
- } else {
- */
- aObj->setDisplayed(isVisible);
- //}
+ aObj->setDisplayed(isVisible);
}
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
}
// Show only objects from the list
foreach (ObjectPtr aObj, theList) {
- /*
- ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
- if (aPartRes) {
- DocumentPtr aDoc = aPartRes->partDoc();
- SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), true)
- SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), true)
- SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), true)
- } else {
- */
- aObj->setDisplayed(true);
- //}
+ aObj->setDisplayed(true);
}
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
}
--- /dev/null
+# Copyright (C) 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE
+
+IF(ADD_MODELS_TESTS)
+ ENABLE_TESTING()
+
+ file(GLOB pyFiles
+ "*.py"
+ )
+
+ if (WIN32) # different separators and path to libraries variable name
+ SET(_JUSTPATH "${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_BIN};${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_SWIG};${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_PLUGIN_FILES};${SUIT_LIB_DIR};$ENV{PATH}")
+ STRING(REPLACE "\\" "/" _JUSTPATH "${_JUSTPATH}")
+ STRING(REPLACE ";" "\\;" _JUSTPATH "${_JUSTPATH}")
+ SET(_PYTHONPATH "${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_SWIG};${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_PLUGIN_FILES};${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_ADDONS};$ENV{PYTHONPATH}")
+ STRING(REPLACE "\\" "/" _PYTHONPATH "${_PYTHONPATH}")
+ STRING(REPLACE ";" "\\;" _PYTHONPATH "${_PYTHONPATH}")
+ else()
+ SET(_LD_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_BIN}:${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_SWIG}:${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_PLUGIN_FILES}:${SUIT_LIB_DIR}:$ENV{LD_LIBRARY_PATH}")
+ SET(_PYTHONPATH "${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_SWIG}:${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_PLUGIN_FILES}:${CMAKE_INSTALL_PREFIX}/${SHAPER_INSTALL_ADDONS}:$ENV{PYTHONPATH}")
+ endif()
+
+ foreach(eachFilePath ${pyFiles})
+ # Strip the ".py" suffix
+ GET_FILENAME_COMPONENT(aTestName ${eachFilePath} NAME_WE)
+
+ # Add "SubprojectName_" prefix
+ GET_FILENAME_COMPONENT(aSubprojectName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+ SET(aTestName "${aSubprojectName}_${aTestName}")
+
+ # Full path to the python test file beeing executed
+ SET(aTestFilePath "${eachFilePath}")
+ IF(EXISTS ${aTestFilePath})
+ ADD_TEST(NAME ${aTestName}
+ COMMAND ${PYTHON_EXECUTABLE} ${aTestFilePath})
+ if (WIN32) # different path to libraries variable name
+ SET_TESTS_PROPERTIES(${aTestName} PROPERTIES
+ ENVIRONMENT "PATH=${_JUSTPATH};PYTHONPATH=${_PYTHONPATH}"
+ LABELS "models_tests")
+ else()
+ SET_TESTS_PROPERTIES(${aTestName} PROPERTIES
+ ENVIRONMENT "LD_LIBRARY_PATH=${_LD_LIBRARY_PATH};PYTHONPATH=${_PYTHONPATH}"
+ LABELS "models_tests")
+ endif()
+ # Debug output...
+ # MESSAGE(STATUS "Test added: ${aTestName} file: ${aTestFilePath}")
+ ELSE(EXISTS ${aTestFilePath})
+ MESSAGE(WARNING "Can not find the test file: ${aTestFilePath}")
+ ENDIF(EXISTS ${aTestFilePath})
+ endforeach(eachFilePath ${ARGN})
+
+ ADD_CUSTOM_TARGET(run_models_tests COMMAND ${CMAKE_CTEST_COMMAND} -C "${CMAKE_BUILD_TYPE}" -L "models_tests")
+ENDIF(ADD_MODELS_TESTS)
\ No newline at end of file
--- /dev/null
+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, "R", "40")
+model.addParameter(Part_1_doc, "h", "3")
+model.addParameter(Part_1_doc, "R2", "33.5")
+model.addParameter(Part_1_doc, "h2", "4")
+model.addParameter(Part_1_doc, "R3", "25.9")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(0, 0, 40)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchPoint_1.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], "R")
+SketchLine_1 = Sketch_1.addLine(0, 0, -20.88093073029438, 34.1172497695333)
+SketchLine_1.setAuxiliary(True)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), "h", 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
+SketchProjection_1 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchCircle_2 = Sketch_2.addCircle(0, 0, 33.5)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_2.results()[1], "R2")
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchCircle_2.center())
+SketchConstraintCoincidence_5.setName("SketchConstraintCoincidence_14")
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2f")], model.selection(), "h2", 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [], model.selection(), "h2*3", 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/To_Face_1"))
+SketchCircle_3 = Sketch_3.addCircle(0, 0, 28.25)
+SketchConstraintRadius_3 = Sketch_3.setRadius(SketchCircle_3.results()[1], 28.25)
+SketchProjection_2 = Sketch_3.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchCircle_3.center(), SketchAPI_Line(SketchLine_3).startPoint())
+Extrusion_3.setNestedSketch(Sketch_3)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [], model.selection(), "h2", 0)
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_3_1/To_Face_1"))
+SketchProjection_3 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+SketchLine_4 = SketchProjection_3.createdFeature()
+SketchCircle_4 = Sketch_4.addCircle(0, 0, 25.9)
+SketchConstraintRadius_4 = Sketch_4.setRadius(SketchCircle_4.results()[1], "R3")
+SketchConstraintCoincidence_7 = Sketch_4.setCoincident(SketchAPI_Line(SketchLine_4).startPoint(), SketchCircle_4.center())
+SketchConstraintCoincidence_7.setName("SketchConstraintCoincidence_15")
+Extrusion_4.setNestedSketch(Sketch_4)
+Extrusion_5 = model.addExtrusion(Part_1_doc, [], model.selection(), "h2", 0)
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_4_1/To_Face_1"))
+SketchProjection_4 = Sketch_5.addProjection(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+SketchLine_5 = SketchProjection_4.createdFeature()
+SketchCircle_5 = Sketch_5.addCircle(0, 0, 8)
+SketchConstraintRadius_5 = Sketch_5.setRadius(SketchCircle_5.results()[1], 8)
+SketchConstraintCoincidence_8 = Sketch_5.setCoincident(SketchAPI_Line(SketchLine_5).startPoint(), SketchCircle_5.center())
+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")], [])
+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)
+SketchConstraintRadius_6 = Sketch_6.setRadius(SketchCircle_6.results()[1], 4.2)
+SketchPoint_2 = Sketch_6.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_9 = Sketch_6.setCoincident(SketchPoint_2.coordinates(), SketchCircle_6.center())
+SketchConstraintCoincidence_9.setName("SketchConstraintCoincidence_17")
+ExtrusionCut_1.setNestedSketch(Sketch_6)
+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"))
+SketchConstraintCoincidence_10 = Sketch_7.setCoincident(SketchCircle_7.center(), SketchLine_6.result())
+SketchConstraintRadius_7 = Sketch_7.setRadius(SketchCircle_7.results()[1], 66)
+SketchConstraintDistance_1 = Sketch_7.setDistance(SketchCircle_7.center(), SketchLine_6.startPoint(), 85)
+SketchMultiRotation_1 = Sketch_7.addRotation([SketchCircle_7.results()[1]], SketchLine_6.startPoint(), 120, 3)
+[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")])
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_22"))
+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)
+SketchConstraintCoincidence_11 = Sketch_8.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_8.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintCoincidence_12 = Sketch_8.setCoincident(SketchLine_7.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_13 = Sketch_8.setCoincident(SketchLine_8.endPoint(), SketchLine_9.result())
+SketchConstraintMirror_1 = Sketch_8.addMirror(SketchLine_9.result(), [SketchLine_7.result(), SketchLine_8.result()])
+[SketchLine_10, SketchLine_11] = SketchConstraintMirror_1.mirrored()
+SketchConstraintLength_1 = Sketch_8.setLength(SketchLine_7.result(), 7)
+SketchConstraintDistance_2 = Sketch_8.setDistance(SketchLine_9.startPoint(), SketchLine_7.result(), 11)
+SketchConstraintDistance_3 = Sketch_8.setDistance(SketchLine_8.endPoint(), SketchLine_9.startPoint(), 30)
+SketchMultiRotation_2_objects = [SketchLine_11.result(), SketchLine_10.result(), SketchLine_8.result(), SketchLine_7.result()]
+SketchMultiRotation_2 = Sketch_8.addRotation(SketchMultiRotation_2_objects, SketchLine_9.startPoint(), 120, 3)
+[SketchLine_11, SketchLine_12, SketchLine_13, SketchLine_10, SketchLine_14, SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18, SketchLine_19] = SketchMultiRotation_2.rotated()
+SketchLine_18.setName("SketchLine_15")
+SketchLine_18.result().setName("SketchLine_15")
+SketchLine_17.setName("SketchLine_18")
+SketchLine_17.result().setName("SketchLine_18")
+SketchLine_16.setName("SketchLine_14")
+SketchLine_16.result().setName("SketchLine_14")
+SketchLine_15.setName("SketchLine_17")
+SketchLine_15.result().setName("SketchLine_17")
+SketchLine_14.setName("SketchLine_13")
+SketchLine_14.result().setName("SketchLine_13")
+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")])
+model.end()
+
+model.testNbResults(ExtrusionCut_3, 1)
+model.testNbSubResults(ExtrusionCut_3, [0])
+model.testResultsVolumes(ExtrusionCut_3, [34439.077343526856566313654184341])