CMAKE_POLICY(SET CMP0020 OLD) # disable automatic linking to qtmain.lib
ENDIF(WIN32)
-SET (SHAPER_Version 9.4.0)
+SET (SHAPER_Version 9.5.0)
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH})
.. toctree::
:titlesonly:
- :maxdepth: 2
+ :maxdepth: 3
General/Introduction.rst
General/Tutorial.rst
<insert here>
+
+.. toctree::
+ :hidden:
+
General/TUI_scripts.rst
cd /d %SALOME_ROOT_DIR%\WORK
call set_env.bat %1
-if "%2" == run (
+if "%2" == "run" (
call "%PDIR%\env_launch.bat"
) else (
call "%PDIR%\env_compile.bat"
--- /dev/null
+# Copyright (C) 2016-2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# ============================================================ #
+# #
+# Attention: Keep this file for correct execution on Windows #
+# #
+# ============================================================ #
aPartRes = ModelAPI.modelAPI_ResultPart(ModelAPI.modelAPI_Result(aPartObject))
aPartDoc = aPartRes.partDoc()
if aPartDoc is None and aPartObject is not None:
- EventsAPI.Events_InfoMessage("PublishToStudy", "For publish to SHAPER-STUDY some Part is not activated", self).send()
+ EventsAPI.Events_InfoMessage("PublishToStudy", "To publish to SHAPER-STUDY, activate Parts in SHAPER", self).send()
break
- aPartFeatureId = aPartSet.feature(aPartRes).data().featureId()
+ aPartFeatureId = aPartSet.feature(aPartRes.original()).data().featureId()
# Collects all features of exported results to find results of the same features and extend id.
# Map from feature index to index of result. If index is zero (initial), no surrfix to entry is added.
aFeaturesIndices = {}
else:
aSelList = aRef.selectionList("group_list")
aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
- for aSelIndex in range(aSelList.size()):
- aSelection = aSelList.value(aSelIndex)
- if aSelection.contextObject():
- aShape = aSelection.value()
- if aShape:
- allShapesList = [] # collect all sub-shapes selected in the group
- if aShape.shapeType() == 0 or aShape.shapeType() != aSelType: # compound or whole res
- anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
- while anExplorer.more():
- allShapesList.append(anExplorer.current())
- anExplorer.next()
- else:
- allShapesList.append(aShape)
- # get index of each selected shape: if 0, this sub-shape is not in our result
- for aSelected in allShapesList:
- anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, aSelected)
- if anId > 0 and not anId in aGroupHasIndex:
- aGroupIndices.append(anId)
- aGroupHasIndex[anId] = 0
+ for aGroupRes in aRef.results():
+ aShape = aGroupRes.shape()
+ anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
+ while anExplorer.more():
+ anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current())
+ if anId > 0 and not anId in aGroupHasIndex:
+ aGroupIndices.append(anId)
+ aGroupHasIndex[anId] = 0
+ anExplorer.next()
if len(aGroupIndices): # create group
aGroupFeatureId = aRef.data().featureId()
if theFields:
def fillField(self, theField, theFeature, theEngine, theSelectionIndices):
aTables = theFeature.tables("values")
aValType = aTables.type() # type of the values
- theField.SetValuesType(aValType)
+ aValTypeToSet = aValType
+ if aValType == 3: # strings do not supported by SMESH, so, make them empty boolean table
+ aValTypeToSet = 0
+ theField.SetValuesType(aValTypeToSet)
aNumSteps = aTables.tables() # number of steps is number of tables
aSteps = []
for aVal in range(aNumSteps):
<translation>Toutes les pièces de l'assemblage ne sont pas à jour, rien n'est publié. Veuillez mettre la dernière fonctionnalité à jour.</translation>
</message>
<message>
- <source>For publish to SHAPER-STUDY some Part is not activated</source>
- <translation>Pour la publication sur SHAPER-STUDY, une pièce n'est pas activée</translation>
+ <source>To publish to SHAPER-STUDY, activate Parts in SHAPER</source>
+ <translation>Pour publier dans SHAPER-STUDY, activez les pièces dans SHAPER</translation>
</message>
</context>
</TS>
TestPlane.py
TestPlane_ErrorMsg.py
TestPlane_FaceValidator.py
+ Test19207.py
+ Test19471.py
)
new ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes());
aFactory->registerValidator("ConstructionPlugin_ValidatorPointThreeNonParallelPlanes",
new ConstructionPlugin_ValidatorPointThreeNonParallelPlanes());
+ aFactory->registerValidator("ConstructionPlugin_ValidatorNotFeature",
+ new ConstructionPlugin_ValidatorNotFeature());
Config_PropManager::registerProp(SKETCH_TAB_NAME, "planes_size", "Size", Config_Prop::DblSpin,
PLANE_SIZE, "0", "1000");
return true;
}
+//==================================================================================================
+bool ConstructionPlugin_ValidatorNotFeature::isValid(
+ const AttributePtr& theAttribute,
+ const std::list<std::string>& /*theArguments*/,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionPtr aSelAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ if (!aSelAttr) {
+ theError = "Wrong attribute";
+ return false;
+ }
+
+ FeaturePtr aContextFeature = aSelAttr->contextFeature();
+ if (aContextFeature) {
+ theError = "Feature should not be selected";
+ return false;
+ }
+ return true;
+}
+
+//==================================================================================================
+
std::shared_ptr<GeomAPI_Edge> getEdge(const GeomShapePtr theShape)
{
GeomEdgePtr anEdge;
Events_InfoMessage& theError) const;
};
+/// \class ConstructionPlugin_ValidatorNotFeature
+/// \ingroup Validators
+/// \brief A validator for selection of a result but not a feature.
+class ConstructionPlugin_ValidatorNotFeature : public ModelAPI_AttributeValidator
+{
+public:
+ //! \return True if the attribute is valid.
+ //! \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
\ No newline at end of file
<translation>Select an edge.</translation>
</message>
</context>
+ <context>
+ <name>Point:edge:ConstructionPlugin_ValidatorNotFeature</name>
+ <message>
+ <source>Wrong attribute</source>
+ <translation>Wrong attribute.</translation>
+ </message>
+ <message>
+ <source>Feature should not be selected</source>
+ <translation>Feature should not be selected.</translation>
+ </message>
+ </context>
<context>
<name>Point:edge_for_point_projection</name>
<message>
<translation>Sélectionnez l'arête de référence.</translation>
</message>
</context>
+ <context>
+ <name>Point:edge:ConstructionPlugin_ValidatorNotFeature</name>
+ <message>
+ <source>Wrong attribute</source>
+ <translation>Attribut incorrect.</translation>
+ </message>
+ <message>
+ <source>Feature should not be selected</source>
+ <translation>La fonction ne doit pas être sélectionnée.</translation>
+ </message>
+ </context>
<context>
<name>Point:edge_for_point_projection</name>
<message>
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+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.27564593372983, -98.06529667720862, 118.6032908025252, -158.4943424420008)
+SketchLine_2 = Sketch_1.addLine(48.47982068764622, 136.9061129612801, 209.0029126232743, 12.63448992263632)
+model.do()
+Filling_1 = model.addFilling(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")])
+Plane_1 = model.addPlane(Part_1_doc, model.selection("FACE", "Filling_1_1"), 10, False)
+model.end()
+
+from ModelAPI import *
+factory = ModelAPI_Session.get().validators()
+assert(factory.validate(Plane_1.feature()))
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+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, 5, 0, 0)
+Point_3 = model.addPoint(Part_1_doc, 20, 0, 0)
+Edge_1 = model.addEdge(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("VERTEX", "Point_2"))
+Point_4 = model.addPoint(Part_1_doc, model.selection("EDGE", "all-in-Edge_1"), 10, False, False)
+model.end()
+
+assert(Point_4.feature().error() != "")
icon="icons/Construction/edge.png"
shape_types="edge">
<validator id="GeomValidators_Finite"/>
+ <validator id="ConstructionPlugin_ValidatorNotFeature"/>
</shape_selector>
<radiobox id="offset_type">
<radio id="offset_type_by_distance"
# Check exported file
aRefPath = os.path.join(os.getenv("DATA_DIR"), "Shapes", "Xao", "box2.xao")
- import filecmp
- assert filecmp.cmp(theFile, aRefPath)
+ # endlines may be different on different platforms, thus compare files line-by-line
+ areFilesEqual = True
+ with open(theFile, 'r') as file, open(aRefPath, 'r') as ref:
+ l1 = l2 = True
+ while l1 and l2 and areFilesEqual:
+ l1 = file.readline()
+ l2 = ref.readline()
+ areFilesEqual = l1 == l2
+ assert areFilesEqual
if __name__ == '__main__':
with TemporaryDirectory() as tmp_dir:
Test2817.py
Test19065.py
Test19066.py
+ Test19115.py
+ Test19196.py
TestFillet1D_ErrorMsg.py
TestFillet1D_Vertices_1.py
TestFillet1D_Vertices_2.py
// in boolean operation and will be added to result.
bool isProcessCompsolid = !isSimpleCreation || !aFuseVersion.empty();
ListOfShape aShapesToAdd;
+ int aNbCompsolids = 0; // number of compsolids, which subs is taken into operation
+ bool hasSeparateSolids = false; // are solids or full results exist
for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjectsHierarchy.begin();
isProcessCompsolid && anObjectsIt != anObjectsHierarchy.end();
++anObjectsIt) {
GeomShapePtr aParent = anObjectsHierarchy.parent(anObject, false);
if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
+ ++aNbCompsolids;
// mark all subs of this parent as precessed to avoid handling twice
aParent = anObjectsHierarchy.parent(anObject);
anObjectsHierarchy.splitCompound(aParent, aUsed, aNotUsed);
aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end());
}
+ else
+ hasSeparateSolids = true;
}
+ bool isSingleCompsolid = aNbCompsolids == 1 && !hasSeparateSolids;
ListOfShape anOriginalShapes = aSolidsToFuse;
anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end());
}
// If we have compsolids then cut with not used solids all others.
- if (!aShapesToAdd.empty()) {
+ if (!aShapesToAdd.empty() && !isSingleCompsolid) {
aSolidsToFuse.clear();
for (ListOfShape::iterator
anIt = anOriginalShapes.begin(); anIt != anOriginalShapes.end(); anIt++) {
}
GeomTrsfPtr aTrsf(new GeomAPI_Trsf);
- aTrsf->setTranslation(aFirstPoint, aSecondPoint);
+ if (aFirstPoint && aSecondPoint) {
+ aTrsf->setTranslation(aFirstPoint, aSecondPoint);
+ }
return aTrsf;
}
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from GeomAPI 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, "h", "1")
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 0.5, "h")
+Cylinder_2 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 0.1, "h")
+Cylinder_3 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 0.4, "h")
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 0.1, False)
+Partition_1_objects = [model.selection("SOLID", "Cylinder_1_1"), model.selection("SOLID", "Cylinder_2_1"), model.selection("SOLID", "Cylinder_3_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "PartSet/YOZ"), model.selection("FACE", "PartSet/XOZ")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True)
+Box_1 = model.addBox(Part_1_doc, 0.7, 0.1, 0.05)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], 0, -0.05, "0.75*h")
+Recover_1 = model.addRecover(Part_1_doc, Partition_1, [Cylinder_1.result()])
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], [model.selection("SOLID", "Recover_1_1")], keepSubResults = True)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Partition_1_1_14/Modified_Face&PartSet/XOZ/XOZ")])
+Recover_2 = model.addRecover(Part_1_doc, Face_1, [Partition_1.result()], True)
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("COMPSOLID", "Recover_2_1"), model.selection("SOLID", "Cut_1_1")], keepSubResults = True)
+model.end()
+
+Fuse_objects = [model.selection("SOLID", "Partition_2_1_14"), model.selection("SOLID", "Partition_2_1_25"), model.selection("SOLID", "Partition_2_1_24")]
+
+
+import time
+
+tStart = time.time()
+
+model.begin()
+Union_1 = model.addUnion(Part_1_doc, Fuse_objects, keepSubResults = True)
+model.do()
+
+tUnion = time.time() - tStart
+
+model.testNbResults(Union_1, 1)
+model.testNbSubResults(Union_1, [23])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.SOLID, [23])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.FACE, [139])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.EDGE, [550])
+model.testNbSubShapes(Union_1, GeomAPI_Shape.VERTEX, [1100])
+model.testResultsVolumes(Union_1, [0.78640233633346512398532])
+
+model.begin()
+Part_1_doc.removeFeature(Union_1.feature())
+model.end()
+
+tStart = time.time()
+
+model.begin()
+Fuse_1 = model.addFuse(Part_1_doc, Fuse_objects, keepSubResults = True)
+model.do()
+
+tFuse = time.time() - tStart
+
+model.testNbResults(Fuse_1, 1)
+model.testNbSubResults(Fuse_1, [23])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [23])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.FACE, [139])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [550])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [1100])
+model.testResultsVolumes(Fuse_1, [0.78640233633346512398532])
+
+print("Elapsed time of Union: {}".format(tUnion))
+print("Elapsed time of Fuse: {}".format(tFuse))
+
+assert(tFuse <= tUnion * 1.5)
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from GeomAPI import *
+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_ext", "80")
+model.addParameter(Part_1_doc, "r_int", "60")
+model.addParameter(Part_1_doc, "r_cut", "30")
+model.addParameter(Part_1_doc, "h", "200")
+ParamSize = model.addParameter(Part_1_doc, "size", "r_int*3/4")
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "r_int", "h")
+Cylinder_2 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "r_ext", "h")
+Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "r_ext")
+Sphere_2 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "r_int")
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Sphere_1_1")], axis = model.selection("EDGE", "PartSet/OY"), angle = 90, keepSubResults = True)
+Rotation_2 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Sphere_2_1")], axis = model.selection("EDGE", "PartSet/OY"), angle = 90, keepSubResults = True)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Rotation_1_1"), model.selection("SOLID", "Rotation_2_1")], axis = model.selection("EDGE", "PartSet/OZ"), distance = "h", keepSubResults = True)
+Fuse_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1"), model.selection("SOLID", "Translation_1_2")], removeEdges = True, keepSubResults = True)
+Fuse_2 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Cylinder_2_1"), model.selection("SOLID", "Translation_1_1")], removeEdges = True, keepSubResults = True)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Fuse_1_1"), model.selection("SOLID", "Fuse_2_1")], keepSubResults = True)
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 124.9999999998943, 0, 45.00000000000152)
+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())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result())
+SketchLine_3 = Sketch_1.addLine(0, 45.00000000000152, -45, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-45, 0, 0, -45.00000000000152)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(0, -45.00000000000152, 44.99999999998636, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(44.99999999998636, 0, 0, 45.00000000000152)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.endPoint())
+SketchLine_7 = Sketch_1.addLine(0, -45.00000000000152, 0, -124.9999999997331)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_7.startPoint())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_7.result())
+SketchLine_8 = Sketch_1.addLine(-45, 0, -125, 0)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_8.result())
+SketchLine_9 = Sketch_1.addLine(44.99999999998636, 0, 124.9999999999994, 0)
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_10 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.result())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_10.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_8.startPoint(), SketchLine_10.result())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_2.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_8.result(), "r_ext")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_8.startPoint(), SketchLine_7.result(), "size", True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_8.result(), SketchLine_1.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_9.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_7.result(), SketchLine_9.result())
+model.do()
+Wire_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_8"), model.selection("EDGE", "Sketch_1/SketchLine_4"), model.selection("EDGE", "Sketch_1/SketchLine_7"), model.selection("EDGE", "Sketch_1/SketchLine_5"), model.selection("EDGE", "Sketch_1/SketchLine_9"), model.selection("EDGE", "Sketch_1/SketchLine_6"), model.selection("EDGE", "Sketch_1/SketchLine_3"), model.selection("EDGE", "Sketch_1/SketchLine_1")]
+Wire_1 = model.addWire(Part_1_doc, Wire_1_objects, False)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), "h", 0)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), "h", False)
+Split_1 = model.addSplit(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], [model.selection("FACE", "Plane_1"), model.selection("SHELL", "Extrusion_1_1")], keepSubResults = True)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Split_1_1_7/Modified_Face&Plane_1/Plane_1&new_weak_name_3"))
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Edge_2"), True)
+SketchLine_11 = SketchProjection_3.createdFeature()
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Edge_5"), True)
+SketchLine_12 = SketchProjection_4.createdFeature()
+SketchProjection_5 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Edge_6"), True)
+SketchLine_13 = SketchProjection_5.createdFeature()
+SketchProjection_6 = Sketch_2.addProjection(model.selection("EDGE", "Extrusion_1_1/To_Edge_3"), True)
+SketchLine_14 = SketchProjection_6.createdFeature()
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), "r_cut/sqrt(2)", 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchProjection_7 = Sketch_3.addProjection(model.selection("EDGE", "Split_1_1_3/Modified_Edge&Extrusion_1_1/To_Edge_4"), True)
+SketchLine_15 = SketchProjection_7.createdFeature()
+SketchProjection_8 = Sketch_3.addProjection(model.selection("EDGE", "Split_1_1_9/Modified_Edge&Extrusion_1_1/To_Edge_4"), True)
+SketchLine_16 = SketchProjection_8.createdFeature()
+SketchProjection_9 = Sketch_3.addProjection(model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchProjection_3][Extrusion_2_1/Generated_Face&Sketch_2/SketchProjection_4]"), True)
+SketchLine_17 = SketchProjection_9.createdFeature()
+SketchLine_18 = Sketch_3.addLine(-45.00000000000152, 221.2132034355964, -99.71358592313776, 275.9267893638306)
+SketchLine_19 = Sketch_3.addLine(-99.71358592313776, 275.9267893638306, -80, 200)
+SketchConstraintCoincidence_14 = Sketch_3.setCoincident(SketchLine_18.endPoint(), SketchLine_19.startPoint())
+SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchAPI_Line(SketchLine_16).endPoint(), SketchLine_19.endPoint())
+SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_18.startPoint(), SketchAPI_Line(SketchLine_17).endPoint())
+SketchConstraintAngle_1 = Sketch_3.setAngle(SketchLine_18.result(), SketchLine_16.result(), 45, type = "")
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchProjection_9f-SketchLine_18f-SketchLine_19f-SketchProjection_8r-SketchProjection_7r")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "PartSet/OZ"), 4, keepSubResults = True)
+Plane_5 = model.addPlane(Part_1_doc, model.selection("VERTEX", "AngularCopy_1_1_1/MV:Rotated&Sketch_3/SketchLine_19_StartVertex&Sketch_3/SketchLine_18_EndVertex"), model.selection("VERTEX", "AngularCopy_1_1_4/MV:Rotated&Sketch_3/SketchLine_19_StartVertex&Sketch_3/SketchLine_18_EndVertex"), model.selection("VERTEX", "AngularCopy_1_1_4/MV:Rotated&Sketch_3/SketchLine_18_StartVertex&Sketch_3/SketchProjection_9_EndVertex"))
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
+SketchLine_20 = Sketch_4.addLine(-71.93873905691365, 265.6178566586798, -194.0624420262377, 195.1097038792864)
+SketchProjection_10 = Sketch_4.addProjection(model.selection("VERTEX", "Sketch_3/SketchLine_18_EndVertex"), False)
+SketchPoint_1 = SketchProjection_10.createdFeature()
+SketchConstraintCoincidence_17 = Sketch_4.setCoincident(SketchLine_20.startPoint(), SketchPoint_1.result())
+SketchProjection_11 = Sketch_4.addProjection(model.selection("VERTEX", "AngularCopy_1_1_4/MV:Rotated&Sketch_3/SketchLine_19_StartVertex&Sketch_3/SketchLine_18_EndVertex"), False)
+SketchPoint_2 = SketchProjection_11.createdFeature()
+SketchConstraintCoincidence_18 = Sketch_4.setCoincident(SketchLine_20.endPoint(), SketchPoint_2.result())
+SketchProjection_12 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_3/SketchLine_18"), True)
+SketchLine_21 = SketchProjection_12.createdFeature()
+SketchProjection_13 = Sketch_4.addProjection(model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchProjection_3][Extrusion_2_1/To_Face]"), True)
+SketchLine_22 = SketchProjection_13.createdFeature()
+SketchProjection_14 = Sketch_4.addProjection(model.selection("EDGE", "AngularCopy_1_1_4/ME:Rotated&Sketch_3/SketchLine_18"), True)
+SketchLine_23 = SketchProjection_14.createdFeature()
+model.do()
+Face_2 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchLine_20r-SketchProjection_14r-SketchProjection_13f-SketchProjection_12f")])
+AngularCopy_2 = model.addMultiRotation(Part_1_doc, [model.selection("FACE", "Face_2_1")], model.selection("EDGE", "PartSet/OZ"), 4, keepSubResults = True)
+Split_2_objects_2 = [model.selection("SOLID", "Extrusion_2_1"), model.selection("COMPOUND", "AngularCopy_1_1"), model.selection("COMPOUND", "AngularCopy_2_1")]
+Split_2 = model.addSplit(Part_1_doc, [model.selection("COMPSOLID", "Split_1_1")], Split_2_objects_2, keepSubResults = True)
+Group_1_objects = [model.selection("FACE", "Split_2_1_7/Modified_Face&Cylinder_1_1/Face_1"), model.selection("FACE", "Split_2_1_8/Modified_Face&Cylinder_1_1/Face_1"), model.selection("FACE", "Split_2_1_9/Modified_Face&Cylinder_1_1/Face_1"), model.selection("FACE", "Split_2_1_10/Modified_Face&Cylinder_1_1/Face_1")]
+Group_1 = model.addGroup(Part_1_doc, "Faces", Group_1_objects)
+Group_1.setName("shared_face_cyl")
+Group_1.result().setName("shared_face_cyl")
+model.end()
+
+model.testNbResults(Split_2, 1)
+model.testNbSubResults(Split_2, [20])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.SOLID, [20])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.FACE, [120])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.EDGE, [492])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.VERTEX, [984])
+model.testResultsVolumes(Split_2, [5093568.888962713])
+
+model.begin()
+ParamSize.expression().setValue("r_int/2")
+model.end()
+
+model.testNbResults(Split_2, 1)
+model.testNbSubResults(Split_2, [20])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.SOLID, [20])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.FACE, [120])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.EDGE, [492])
+model.testNbSubShapes(Split_2, GeomAPI_Shape.VERTEX, [984])
+model.testResultsVolumes(Split_2, [5093568.888962713])
+
+assert(model.checkPythonDump())
ExtrusionCut_3.setNestedSketch(Sketch_3)
model.do()
Shape = ExtrusionCut_3.results()[0].resultSubShapePair()[0].shape()
-checkMiddlePoint(Shape, 5.00008072, 5.079732577, 5.08050677)
+checkMiddlePoint(Shape, 5.00008072, 5.079732786, 5.08050663)
model.end()
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4])
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16])
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32])
-model.testResultsVolumes(Extrusion_1, [10769.186376787])
+model.testResultsVolumes(Extrusion_1, [5169.186376787])
ParamFrom.setValue(-20)
model.do()
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4])
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16])
model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32])
-model.testResultsVolumes(Extrusion_1, [5169.186376787])
+model.testResultsVolumes(Extrusion_1, [10769.186376787])
model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc)
.. toctree::
:titlesonly:
- :maxdepth: 1
+ :maxdepth: 2
+ booleanOperations.rst
angularCopyFeature.rst
chamferFeature.rst
- commonFeature.rst
copyFeature.rst
- cutFeature.rst
defeaturingFeature.rst
extrusionCutFeature.rst
extrusionFeature.rst
extrusionFuseFeature.rst
fillet1dFeature.rst
filletFeature.rst
- fuseFeature.rst
fuseFeatureFaces.rst
importResultFeature.rst
- intersectionFeature.rst
linearCopyFeature.rst
measurementFeature.rst
- partitionFeature.rst
pipeFeature.rst
placementFeature.rst
recoverFeature.rst
revolutionFeature.rst
revolutionFuseFeature.rst
rotationFeature.rst
- smashFeature.rst
- splitFeature.rst
symmetryFeature.rst
transformationFeature.rst
translationFeature.rst
- unionFeature.rst
--- /dev/null
+.. |common.icon| image:: images/bool_common.png
+ :height: 16px
+.. |cut.icon| image:: images/bool_cut.png
+ :height: 16px
+.. |fuse.icon| image:: images/bool_fuse.png
+ :height: 16px
+.. |smash.icon| image:: images/bool_smash.png
+ :height: 16px
+.. |split.icon| image:: images/bool_split.png
+ :height: 16px
+.. |partition.icon| image:: images/partition_btn.png
+ :height: 16px
+.. |inter.icon| image:: images/intersection_btn.png
+ :height: 16px
+.. |union.icon| image:: images/union_btn.png
+ :height: 16px
+
+
+.. _bopArguments:
+
+Arguments of Boolean Operations
+===============================
+
+This section describes the shapes applicable as arguments of Boolean Operations.
+First of all, the result of Boolean Operations depends on the dimension of arguments. The following table shows the dimension and corresponding types of shapes.
+
++-----------+----------------------------+
+| Dimension | Shape types |
++===========+============================+
+| 0 | VERTEX, COMPOUND |
++-----------+----------------------------+
+| 1 | EDGE, WIRE, COMPOUND |
++-----------+----------------------------+
+| 2 | FACE, SHELL, COMPOUND |
++-----------+----------------------------+
+| 3 | SOLID, COMPSOLID, COMPOUND |
++-----------+----------------------------+
+
+*Note*: COMPOUND may consist of any shape combinations, therefore, it is present is each row.
+
+The next table aligns an operation and the dimensions of its arguments.
+Construction planes (mentioned PLANE) can be used in several operations, but not included in the table above due to their infinite nature.
+
++-------------------------+---------------------------+-------------------------+
+| Operation | Dimension of objects (DO) | Dimension of tools (DT) |
++=========================+===========================+=========================+
+| |common.icon| | Any | Any (+ PLANE) |
+| :ref:`featureCommon` | | |
++-------------------------+---------------------------+-------------------------+
+| |cut.icon| | Any | Not less than **DO** |
+| :ref:`featureCut` | | |
++-------------------------+---------------------------+-------------------------+
+| |fuse.icon| | Any | Any |
+| :ref:`featureFuse` | | |
++-------------------------+---------------------------+-------------------------+
+| |inter.icon| | 1 or 2 | --- |
+| :ref:`featureIntersect` | | |
++-------------------------+---------------------------+-------------------------+
+| |partition.icon| | Any (+ PLANE) | --- |
+| :ref:`featurePartition` | | |
++-------------------------+---------------------------+-------------------------+
+| |smash.icon| | 2 (planar FACE only) or 3 | Equal to **DO** |
+| :ref:`featureSmash` | | |
++-------------------------+---------------------------+-------------------------+
+| |split.icon| | Any | Any (+ PLANE) |
+| :ref:`featureSplit` | | |
++-------------------------+---------------------------+-------------------------+
+| |union.icon| | 3 (SOLIDs from COMPSOLID) | --- |
+| :ref:`featureUnion` | | |
++-------------------------+---------------------------+-------------------------+
--- /dev/null
+
+.. _booleanOperations:
+
+Boolean Operations
+==================
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ commonFeature.rst
+ cutFeature.rst
+ fuseFeature.rst
+ intersectionFeature.rst
+ partitionFeature.rst
+ smashFeature.rst
+ splitFeature.rst
+ unionFeature.rst
+ booleanArguments.rst
- **Objects** contains a list of objects selected in the Object Browser or in the Viewer.
If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be cut from
other objects (to avoid self-intersection) and added to the result.
-- **Tools** contains a list of objects selected in the Object Browser or in the Viewer, which will be fused with tool objects.
- If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored.
+- **Tools** contains a list of objects selected in the Object Browser or in the Viewer, which will be intersected with tool objects.
+ If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored.
- **See preview** button shows a result of the operation.
+Any kind of shape is supported as an object or a tool of Common. Moreover, constructions planes can be selected as tools.
+
**TUI Command**:
.. py:function:: model.addCommon(Part_doc, objects, tools)
-.. _featureCut:
.. |bool_cut.icon| image:: images/bool_cut.png
:height: 16px
+.. _featureCut:
+
Cut
===
Non-selected subshapes from compsolids/compounds will be ignored.
- **See preview** button shows a result of the operation.
+The minimal dimension of Tool Objects should be not less than the maximal dimension of Main Objects.
+
**TUI Command**:
.. py:function:: model.addCut(Part_doc, mainObjects, toolObjects)
.. |bool_fuse.icon| image:: images/bool_fuse.png
:height: 16px
+.. _featureFuse:
+
Fuse
====
**Simple**
-- **Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be fused with tool objects.
- If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored.
+- **Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be fused to a single result.
+ If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will cut the fuse shape then will be joined to the result.
- **Remove intersection edges** - if enabled, edges that lie on the same surface will be removed.
- **See preview** - button shows a result of the operation.
.. |intersection_btn.icon| image:: images/intersection_btn.png
+.. _featureIntersect:
+
Intersection
============
**Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be intersected.
+All intersected objects should be 1- or 2-dimensional (edges, faces, shells). However, it is allowed to select 3-dimensional objects, but only their shells will be taken into operation.
+
**TUI Command**:
.. py:function:: model.addIntersection(Part_doc, Objects)
.. |partition_btn.icon| image:: images/partition_btn.png
+.. _featurePartition:
+
Partition
=========
**Partition operation**
-**Base Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be partitioned.
+**Base Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be partitioned. Constuction planes are allowed too if at least one non-construction entity is selected.
**TUI Command**:
.. |bool_smash.icon| image:: images/bool_smash.png
:height: 16px
+.. _featureSmash:
+
Smash
=====
If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored.
- **See preview** button shows a result of the operation.
+Main objects and Tools objects should have the same dimension. There are supported 2-dimensional (face) or 3-dimensional (solid, compsolid) arguments.
+
**TUI Command**:
.. py:function:: model.addSmash(Part_doc, mainObjects, toolObjects)
.. |bool_split.icon| image:: images/bool_split.png
:height: 16px
+.. _featureSplit:
+
Split
=====
**Split operation**
- **Main Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be cut and splitted by tool objects.
-- **Tool Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will cut and split the main objects.
+- **Tool Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will cut and split the main objects. Construction planes may be selected too.
- **See preview** button shows a result of the operation.
**TUI Command**:
.. |union_btn.icon| image:: images/union_btn.png
+.. _featureUnion:
+
Union
=====
+**Caution**. This operation is obsolete. Fuse operation should be used instead.
+
Union feature implements a Boolean operation for creation of a union of selected objects.
To create a Union in the active part:
<source path="boolean_split_widget.xml"/>
</feature>
<feature id="Union" title="Union" tooltip="Perform union operations with shapes"
- icon="icons/Features/union.png" helpfile="unionFeature.html">
+ icon="icons/Features/union.png" helpfile="unionFeature.html" internal="1">
<source path="union_widget.xml"/>
</feature>
<feature id="Remove_SubShapes" title="Remove Sub-Shapes" tooltip="Allows to remove sub-shapes from wires, shells, compsolids and compounds"
TestFilter_BelongsTo_Exclude.py
TestFilter_OnPlane.py
TestFilter_OnPlane_Exclude.py
+ TestFilter_OnPlane_Multi.py
TestFilter_OnLine.py
TestFilter_OnLine_Exclude.py
+ TestFilter_OnLine_Multi.py
TestFilter_OnGeometry_Edge1.py
TestFilter_OnGeometry_Edge2.py
TestFilter_OnGeometry_Face1.py
TestFilter_OnPlaneSide_Plane.py
TestFilter_OnPlaneSide_Exclude_Face.py
TestFilter_OnPlaneSide_Exclude_Plane.py
+ TestFilter_OnPlaneSide_Multi.py
TestFilter_OppositeToEdge.py
TestFilter_OppositeToEdge_Exclude.py
TestFilter_RelativeToSolid_In.py
TestFilter_RelativeToSolid_Exclude_NotOn.py
TestFilter_RelativeToSolid_Exclude_InAndOn.py
TestFilter_RelativeToSolid_Exclude_OutAndOn.py
+ TestFilter_RelativeToSolid_Multi.py
TestFilter_ExternalFaces1.py
TestFilter_ExternalFaces2.py
TestFilter_ExternalFaces_Exclude1.py
TestFilter_TopoConnectedFaces_Prop_Exclude_Face1.py
TestFilter_TopoConnectedFaces_Prop_Exclude_Face2.py
TestFilter_TopoConnectedFaces_Prop_Exclude_Face3.py
+ TestFilter_TopoConnectedFaces_Multi.py
Test2946.py
Test2951.py
+ Test3241.py
Test17924.py
Test17962.py
- TestFilter_OnLine_Multi.py
- TestFilter_OnPlane_Multi.py
- TestFilter_OnPlaneSide_Multi.py
- TestFilter_RelativeToSolid_Multi.py
- TestFilter_TopoConnectedFaces_Multi.py
+ Test19190.py
)
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+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(87.62648221343873, 42.39493620569578, -76.44861660079052, 42.39493620569578)
+SketchLine_2 = Sketch_1.addLine(-76.44861660079052, 42.39493620569578, -76.44861660079052, -42.23747486149789)
+SketchLine_3 = Sketch_1.addLine(-76.44861660079052, -42.23747486149789, 87.62648221343873, -42.23747486149789)
+SketchLine_4 = Sketch_1.addLine(87.62648221343873, -42.23747486149789, 87.62648221343873, 42.39493620569578)
+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(-32.93478260869566, 42.39493620569578, -17.36561264822134, -42.23747486149789)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_1.result())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_3.result())
+SketchLine_6 = Sketch_1.addLine(34.93083003952569, -42.23747486149789, 44.11264822134387, 42.39493620569579)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.startPoint(), SketchLine_3.result())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_1.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1")], model.selection(), 100, 0)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 35, 120)
+Fuse_1_objects_1 = [model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Cylinder_1_1"), model.selection("SOLID", "Extrusion_1_1_3")]
+Fuse_1 = model.addFuse(Part_1_doc, Fuse_1_objects_1, removeEdges = True, keepSubResults = True)
+Fuse_1.result().setColor(76, 76, 153)
+Fuse_1.result().subResult(0).setColor(254, 127, 127)
+Fuse_1.result().subResult(1).setColor(153, 153, 76)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Fuse_1_1_2/Modified_Face&Sketch_1/SketchLine_2"), 75, True)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Fuse_1_1_2"), "on"])])
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Fuse_1, 1)
+model.testNbSubResults(Fuse_1, [2])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.FACE, [14])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [54])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [108])
+model.testResultsVolumes(Fuse_1, [1465576.14])
+
+solid1 = Fuse_1.result().subResult(0).resultSubShapePair()[0]
+solid2 = Fuse_1.result().subResult(1).resultSubShapePair()[0]
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(solid1.shape(), GeomAPI_Shape.FACE)
+Reference[model.selection(solid1, exp.current())] = False; exp.next()
+Reference[model.selection(solid1, exp.current())] = True; exp.next()
+while exp.more():
+ Reference[model.selection(solid1, exp.current())] = False
+ exp.next()
+exp = GeomAPI_ShapeExplorer(solid2.shape(), GeomAPI_Shape.FACE)
+while exp.more():
+ Reference[model.selection(solid1, exp.current())] = True
+ exp.next()
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from GeomAPI import *
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchCircle_1 = Sketch_1.addCircle(0, 0, 40)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 40)
+model.do()
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f"), 10, False)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchCircle_1"), True)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchCircle_2 = Sketch_2.addCircle(0, 0, 50)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchCircle_2.center())
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_2.results()[1], 50)
+model.do()
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), 10, False)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
+SketchProjection_3 = Sketch_3.addProjection(model.selection("VERTEX", "Sketch_1/SketchCircle_1"), True)
+SketchPoint_3 = SketchProjection_3.createdFeature()
+SketchCircle_3 = Sketch_3.addCircle(0, 0, 53)
+SketchConstraintCoincidence_3 = Sketch_3.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchCircle_3.center())
+SketchConstraintRadius_3 = Sketch_3.setRadius(SketchCircle_3.results()[1], 53)
+model.do()
+Filling_1_objects = [model.selection("EDGE", "Sketch_1/SketchCircle_1_2"), model.selection("EDGE", "Sketch_2/SketchCircle_2_2"), model.selection("EDGE", "Sketch_3/SketchCircle_3_2")]
+Filling_1 = model.addFilling(Part_1_doc, Filling_1_objects)
+Sketch_4 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchProjection_4 = Sketch_4.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_4 = SketchProjection_4.createdFeature()
+SketchProjection_5 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OX"), True)
+SketchLine_1 = SketchProjection_5.createdFeature()
+SketchMultiRotation_1 = Sketch_4.addRotation([SketchLine_1.result()], SketchAPI_Point(SketchPoint_4).coordinates(), 360, 12, True)
+[SketchLine_1, SketchLine_2, SketchLine_3, SketchLine_4, SketchLine_5, SketchLine_6, SketchLine_7, SketchLine_8, SketchLine_9, SketchLine_10, SketchLine_11, SketchLine_12] = SketchMultiRotation_1.rotated()
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], False)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Edge_1")], model.selection(), model.selection("FACE", "Plane_2"), 0, model.selection(), 0)
+Split_1 = model.addSplit(Part_1_doc, [model.selection("FACE", "Filling_1_1")], [model.selection("COMPOUND", "Extrusion_1_1")], keepSubResults = True)
+FilterFace = model.filters(Part_1_doc, [model.addFilter(name = "OnGeometry", args = [model.selection("FACE", "Split_1_1_1")])])
+model.end()
+
+Reference = {}
+ResultSplit = Split_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultSplit.shape(), GeomAPI_Shape.FACE)
+while exp.more():
+ Reference[model.selection(ResultSplit, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_1_doc, model, FilterFace, Reference)
.. _filtersPlugin:
-Filters Plugin
-==============
+Filters plug-in
+===============
Filters plug-in provides a collection of filters used Filters property panel (for example see :ref:`groupPage` feature).
return newBSpline2d(thePoles, theWeights, theDegree, thePeriodic);
int anAuxPole = 0;
- if (thePeriodic && thePoles.front()->distance(thePoles.back()) < Precision::Confusion())
- anAuxPole = -1;
+ if (thePeriodic && thePoles.front()->distance(thePoles.back()) < Precision::Confusion()) {
+ // additionally check the number of poles is greater than needed for th periodic B-spline
+ int aNbPoles = 0;
+ std::list<int>::const_iterator it = theMults.begin();
+ for (++it; it != theMults.end(); ++it)
+ aNbPoles += *it;
+ if ((int)thePoles.size() > aNbPoles)
+ anAuxPole = -1;
+ }
// collect arrays of poles, weights, knots and multiplicities
TColgp_Array1OfPnt2d aPoles(1, (int)thePoles.size() + anAuxPole);
#include "GeomAPI_Cone.h"
#include "GeomAPI_Torus.h"
+#include <Bnd_Box2d.hxx>
+#include <BndLib_Add2dCurve.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <gp_Cone.hxx>
#include <gp_Torus.hxx>
+static void optimalBounds(const TopoDS_Face& theFace, double& theUMin, double& theUMax,
+ double& theVMin, double& theVMax);
+
GeomAPI_Face::GeomAPI_Face()
: GeomAPI_Shape()
Handle(Geom_Surface) anOwnSurf = baseSurface(anOwnFace);
Handle(Geom_Surface) anOtherSurf = baseSurface(anOtherFace);
+ if (anOwnSurf == anOtherSurf)
+ return true;
// case of two elementary surfaces
if (anOwnSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) &&
if (aFace.IsNull())
return anInnerPoint;
- BRepGProp_Face aProp(aFace);
double aUMin, aUMax, aVMin, aVMax;
- aProp.Bounds(aUMin, aUMax, aVMin, aVMax);
+ optimalBounds(aFace, aUMin, aUMax, aVMin, aVMax);
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
if (aSurf.IsNull())
anInnerPoint = GeomPointPtr(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
return anInnerPoint;
}
+
+
+// ================== Auxiliary functions ========================
+
+void optimalBounds(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Bnd_Box2d& theBndBox)
+{
+ Standard_Real aFirst, aLast;
+ const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast);
+ if (aC2D.IsNull())
+ return;
+
+ Standard_Real aXmin = 0.0, aYmin = 0.0, aXmax = 0.0, aYmax = 0.0;
+ Standard_Real aUmin, aUmax, aVmin, aVmax;
+ Bnd_Box2d aBoxC, aBoxS;
+ BndLib_Add2dCurve::AddOptimal(aC2D, aFirst, aLast, 0., aBoxC);
+ if (aBoxC.IsVoid())
+ return;
+
+ aBoxC.Get(aXmin, aYmin, aXmax, aYmax);
+
+ TopLoc_Location aLoc;
+ Handle(Geom_Surface) aS = BRep_Tool::Surface(theFace, aLoc);
+ aS->Bounds(aUmin, aUmax, aVmin, aVmax);
+
+ if (aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
+ {
+ const Handle(Geom_RectangularTrimmedSurface) aSt =
+ Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
+ aS = aSt->BasisSurface();
+ }
+
+ //
+ if (!aS->IsUPeriodic())
+ {
+ Standard_Boolean isUPeriodic = Standard_False;
+
+ // Additional verification for U-periodicity for B-spline surfaces.
+ // 1. Verify that the surface is U-closed (if such flag is false). Verification uses 2 points.
+ // 2. Verify periodicity of surface inside UV-bounds of the edge. It uses 3 or 6 points.
+ if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
+ (aXmin < aUmin || aXmax > aUmax))
+ {
+ Standard_Real aTol2 = 100 * Precision::SquareConfusion();
+ isUPeriodic = Standard_True;
+ gp_Pnt P1, P2;
+ // 1. Verify that the surface is U-closed
+ if (!aS->IsUClosed())
+ {
+ Standard_Real aVStep = aVmax - aVmin;
+ for (Standard_Real aV = aVmin; aV <= aVmax; aV += aVStep)
+ {
+ P1 = aS->Value(aUmin, aV);
+ P2 = aS->Value(aUmax, aV);
+ if (P1.SquareDistance(P2) > aTol2)
+ {
+ isUPeriodic = Standard_False;
+ break;
+ }
+ }
+ }
+ // 2. Verify periodicity of surface inside UV-bounds of the edge
+ if (isUPeriodic) // the flag still not changed
+ {
+ Standard_Real aV = (aVmin + aVmax) * 0.5;
+ Standard_Real aU[6]; // values of U lying out of surface boundaries
+ Standard_Real aUpp[6]; // corresponding U-values plus/minus period
+ Standard_Integer aNbPnt = 0;
+ if (aXmin < aUmin)
+ {
+ aU[0] = aXmin;
+ aU[1] = (aXmin + aUmin) * 0.5;
+ aU[2] = aUmin;
+ aUpp[0] = aU[0] + aUmax - aUmin;
+ aUpp[1] = aU[1] + aUmax - aUmin;
+ aUpp[2] = aU[2] + aUmax - aUmin;
+ aNbPnt += 3;
+ }
+ if (aXmax > aUmax)
+ {
+ aU[aNbPnt] = aUmax;
+ aU[aNbPnt + 1] = (aXmax + aUmax) * 0.5;
+ aU[aNbPnt + 2] = aXmax;
+ aUpp[aNbPnt] = aU[aNbPnt] - aUmax + aUmin;
+ aUpp[aNbPnt + 1] = aU[aNbPnt + 1] - aUmax + aUmin;
+ aUpp[aNbPnt + 2] = aU[aNbPnt + 2] - aUmax + aUmin;
+ aNbPnt += 3;
+ }
+ for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
+ {
+ P1 = aS->Value(aU[anInd], aV);
+ P2 = aS->Value(aUpp[anInd], aV);
+ if (P1.SquareDistance(P2) > aTol2)
+ {
+ isUPeriodic = Standard_False;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!isUPeriodic)
+ {
+ if ((aXmin < aUmin) && (aUmin < aXmax))
+ {
+ aXmin = aUmin;
+ }
+ if ((aXmin < aUmax) && (aUmax < aXmax))
+ {
+ aXmax = aUmax;
+ }
+ }
+ }
+
+ if (!aS->IsVPeriodic())
+ {
+ Standard_Boolean isVPeriodic = Standard_False;
+
+ // Additional verification for V-periodicity for B-spline surfaces.
+ // 1. Verify that the surface is V-closed (if such flag is false). Verification uses 2 points.
+ // 2. Verify periodicity of surface inside UV-bounds of the edge. It uses 3 or 6 points.
+ if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
+ (aYmin < aVmin || aYmax > aVmax))
+ {
+ Standard_Real aTol2 = 100 * Precision::SquareConfusion();
+ isVPeriodic = Standard_True;
+ gp_Pnt P1, P2;
+ // 1. Verify that the surface is V-closed
+ if (!aS->IsVClosed())
+ {
+ Standard_Real aUStep = aUmax - aUmin;
+ for (Standard_Real aU = aUmin; aU <= aUmax; aU += aUStep)
+ {
+ P1 = aS->Value(aU, aVmin);
+ P2 = aS->Value(aU, aVmax);
+ if (P1.SquareDistance(P2) > aTol2)
+ {
+ isVPeriodic = Standard_False;
+ break;
+ }
+ }
+ }
+ // 2. Verify periodicity of surface inside UV-bounds of the edge
+ if (isVPeriodic) // the flag still not changed
+ {
+ Standard_Real aU = (aUmin + aUmax) * 0.5;
+ Standard_Real aV[6]; // values of V lying out of surface boundaries
+ Standard_Real aVpp[6]; // corresponding V-values plus/minus period
+ Standard_Integer aNbPnt = 0;
+ if (aYmin < aVmin)
+ {
+ aV[0] = aYmin;
+ aV[1] = (aYmin + aVmin) * 0.5;
+ aV[2] = aVmin;
+ aVpp[0] = aV[0] + aVmax - aVmin;
+ aVpp[1] = aV[1] + aVmax - aVmin;
+ aVpp[2] = aV[2] + aVmax - aVmin;
+ aNbPnt += 3;
+ }
+ if (aYmax > aVmax)
+ {
+ aV[aNbPnt] = aVmax;
+ aV[aNbPnt + 1] = (aYmax + aVmax) * 0.5;
+ aV[aNbPnt + 2] = aYmax;
+ aVpp[aNbPnt] = aV[aNbPnt] - aVmax + aVmin;
+ aVpp[aNbPnt + 1] = aV[aNbPnt + 1] - aVmax + aVmin;
+ aVpp[aNbPnt + 2] = aV[aNbPnt + 2] - aVmax + aVmin;
+ aNbPnt += 3;
+ }
+ for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
+ {
+ P1 = aS->Value(aU, aV[anInd]);
+ P2 = aS->Value(aU, aVpp[anInd]);
+ if (P1.SquareDistance(P2) > aTol2)
+ {
+ isVPeriodic = Standard_False;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!isVPeriodic)
+ {
+ if ((aYmin < aVmin) && (aVmin < aYmax))
+ {
+ aYmin = aVmin;
+ }
+ if ((aYmin < aVmax) && (aVmax < aYmax))
+ {
+ aYmax = aVmax;
+ }
+ }
+ }
+
+ aBoxS.Update(aXmin, aYmin, aXmax, aYmax);
+
+ theBndBox.Add(aBoxS);
+}
+
+void optimalBounds(const TopoDS_Face& theFace, double& theUMin, double& theUMax,
+ double& theVMin, double& theVMax)
+{
+ Bnd_Box2d aBB;
+
+ for (TopExp_Explorer anExp(theFace, TopAbs_EDGE); anExp.More(); anExp.Next())
+ optimalBounds(theFace, TopoDS::Edge(anExp.Current()), aBB);
+
+ aBB.Get(theUMin, theVMin, theUMax, theVMax);
+}
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
if(aShapeType == TopAbs_VERTEX) {
return true;
} else if(aShapeType == TopAbs_FACE) {
- const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
- Handle(Standard_Type) aType = aSurface->DynamicType();
-
- if(aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
+ if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
- Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
- aType = aTrimSurface->BasisSurface()->DynamicType();
+ Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
+ aSurface = aTrimSurface->BasisSurface();
}
- return (aType == STANDARD_TYPE(Geom_Plane)) == Standard_True;
+ return GeomLib_IsPlanarSurface(aSurface).IsPlanar();
} else {
BRepBuilderAPI_FindPlane aFindPlane(aShape);
bool isFound = aFindPlane.Found() == Standard_True;
#include <gp_Pnt.hxx>
#include <Precision.hxx>
+static TopoDS_Shape* buildVertex(const gp_Pnt& thePoint)
+{
+ TopoDS_Vertex aVertex;
+ BRep_Builder aBuilder;
+ aBuilder.MakeVertex(aVertex, thePoint, Precision::Confusion());
+ return new TopoDS_Shape(aVertex);
+}
+
GeomAPI_Vertex::GeomAPI_Vertex()
: GeomAPI_Shape()
{
}
}
+GeomAPI_Vertex::GeomAPI_Vertex(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
+{
+ setImpl(buildVertex(thePoint->impl<gp_Pnt>()));
+}
+
GeomAPI_Vertex::GeomAPI_Vertex(double theX, double theY, double theZ)
{
- TopoDS_Vertex aVertex;
- BRep_Builder aBuilder;
- aBuilder.MakeVertex(aVertex, gp_Pnt(theX, theY, theZ), Precision::Confusion());
- setImpl(new TopoDS_Shape(aVertex));
+ setImpl(buildVertex(gp_Pnt(theX, theY, theZ)));
}
std::shared_ptr<GeomAPI_Pnt> GeomAPI_Vertex::point()
GEOMAPI_EXPORT
GeomAPI_Vertex(const std::shared_ptr<GeomAPI_Shape>& theShape);
+ /// Creation of vertex by the given point.
+ GEOMAPI_EXPORT
+ GeomAPI_Vertex(const std::shared_ptr<GeomAPI_Pnt>& thePoint);
+
/// Creation of vertex by 3d coordinates.
GEOMAPI_EXPORT
GeomAPI_Vertex(double theX, double theY, double theZ);
Standard_Boolean bRunParallel = Standard_True;
aBuilder->SetRunParallel(bRunParallel);
+ // Set fuzzy value to eliminate thin results
+ static const Standard_Real aFuzzy = 1.e-5;
+ aBuilder->SetFuzzyValue(aFuzzy);
+
// Building and getting result.
aBuilder->Perform();
if (aBuilder->HasErrors())
return aShape;
}
+static void changeOrientationIfNeeded(const TopoDS_Shape& theShape, gp_Vec& theNormal)
+{
+ TopExp_Explorer anExp(theShape, TopAbs_VERTEX);
+ gp_Pnt aPnt0 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
+ gp_Dir aDir01;
+ for (anExp.Next(); anExp.More(); anExp.Next()) {
+ gp_Pnt aPnt1 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
+ if (aPnt1.SquareDistance(aPnt0) > Precision::SquareConfusion()) {
+ aDir01 = gp_Dir(gp_Vec(aPnt0, aPnt1));
+ break;
+ }
+ }
+ gp_Vec aNormal;
+ for (; anExp.More(); anExp.Next()) {
+ gp_Pnt aPnt2 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
+ if (aPnt2.SquareDistance(aPnt0) > Precision::SquareConfusion()) {
+ aNormal = gp_Vec(aDir01) ^ gp_Vec(aPnt0, aPnt2);
+ if (aNormal.SquareMagnitude() > Precision::SquareConfusion())
+ break;
+ }
+ }
+ if (anExp.More() && aNormal.XYZ().Dot(theNormal.XYZ()) < -Precision::Confusion()) {
+ // directions differ, reverse the normal
+ theNormal.Reverse();
+ }
+}
//==================================================================================================
GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape,
BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
if(aFindPlane.Found() == Standard_True)
{
+ bool checkOrientation = false;
Handle(Geom_Plane) aPlane;
if(aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) {
TopExp_Explorer anExp(aBaseShape, TopAbs_FACE);
aPlane = Handle(Geom_Plane)::DownCast(aSurface);
} else {
aPlane = aFindPlane.Plane();
+ checkOrientation = true;
}
gp_Pnt aLoc = aPlane->Axis().Location();
aBaseVec = aPlane->Axis().Direction();
+
+ if (checkOrientation) {
+ // to stabilize the result of algorithm, if base shape is a wire, compare the orientation
+ // of calculated plane with the normal vector got iterating on vertices
+ changeOrientationIfNeeded(aBaseShape, aBaseVec);
+ }
+
aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
aBaseDir.reset(new GeomAPI_Dir(aBaseVec.X(), aBaseVec.Y(), aBaseVec.Z()));
}
void GeomAlgoAPI_SketchBuilder::build(
const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
- const std::shared_ptr<GeomAPI_Dir>& /*theDirX*/,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
const std::shared_ptr<GeomAPI_Dir>& theNorm,
const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges)
{
BRep_Builder aBuilder;
// Planar face, where the sketch was built
- Handle(Geom_Surface) aPlane(new Geom_Plane(theOrigin->impl<gp_Pnt>(), theNorm->impl<gp_Dir>()));
+ gp_Ax3 aPlnAxes(theOrigin->impl<gp_Pnt>(), theNorm->impl<gp_Dir>(), theDirX->impl<gp_Dir>());
+ Handle(Geom_Surface) aPlane(new Geom_Plane(aPlnAxes));
TopoDS_Face aPlnFace;
aBuilder.MakeFace(aPlnFace, aPlane, Precision::Confusion());
BOPAlgo_Builder* aBB = new BOPAlgo_Builder;
aBB->AddArgument(aPlnFace);
// Set fuzzy value for BOP, because PlaneGCS can solve the set of constraints with
- // the precision up to 1e-5 if the sketch contains arcs.
- static const double THE_FUZZY_TOL = 1.e-5;
+ // the precision up to 5.e-5 if the sketch contains arcs.
+ static const double THE_FUZZY_TOL = 5.e-5;
aBB->SetFuzzyValue(THE_FUZZY_TOL);
setImpl(aBB);
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepClass_FaceClassifier.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopoDS.hxx>
const double theTolerance)
{
GeomPointPtr aMiddlePoint = theShape->middlePoint();
- theClassifier.Perform(aMiddlePoint->impl<gp_Pnt>(), theTolerance);
+ gp_Pnt aPointOnFace = aMiddlePoint->impl<gp_Pnt>();
+ if (theShape->shapeType() == GeomAPI_Shape::FACE) {
+ // middle point may be out of face (within a hole),
+ // in this case, find the nearest point on the face
+ const TopoDS_Face& aFace = theShape->impl<TopoDS_Face>();
+ BRepClass_FaceClassifier aFaceClassifier(aFace, aPointOnFace, theTolerance);
+ if (aFaceClassifier.State() == TopAbs_OUT) {
+ BRepBuilderAPI_MakeVertex aVertex(aPointOnFace);
+ BRepExtrema_DistShapeShape aDistance(aVertex.Vertex(), aFace);
+ if (aDistance.NbSolution())
+ aPointOnFace = aDistance.PointOnShape2(1);
+ }
+ }
+ theClassifier.Perform(aPointOnFace, theTolerance);
return stateToState(theClassifier.State());
}
}
}
}
+ else
+ aValid = false;
}
else if (anAttributeType == ModelAPI_AttributeReference::typeId()) {
AttributeReferencePtr anAttr =
aCalculatedValue[1]);
}
}
+
+void InitializationPlugin_EvalListener::initDataModel()
+{
+ myInterp->runString("salome_iapp.register_module_in_study(\"Shaper\")");
+}
INITIALIZATIONPLUGIN_EXPORT
virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
+ // performs the python call to initialize high level data model on internal data model creation
+ void initDataModel();
+
protected:
/// Evaluates theExpression and returns its value.
double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
if (aDoc != ModelAPI_Session::get()->moduleDocument())
return;
+ myEvalListener->initDataModel();
+
std::list<FeaturePtr> aFeatures;
// the viewer update should be blocked in order to avoid the features blinking before they are
Py_XDECREF(_local_context);
PyInterp_Interp::closeContext();
}
+
+bool InitializationPlugin_PyInterp::runString(std::string theString)
+{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+ return PyRun_SimpleString(theString.c_str());
+}
/// Evaluates theExpression and returns its value.
double evaluate(const std::string& theExpression, std::string& theError);
+ /// Runs the string command in the python interpreter. Returns true if no error is in result.
+ bool runString(std::string theString);
+
protected:
/// Returns error message.
std::string errorMessage();
void Model_AttributeSelection::concealedFeature(
const FeaturePtr theFeature, const FeaturePtr theStop, const bool theCheckCopy,
- std::list<FeaturePtr>& theConcealers, const ResultPtr theResultOfFeature)
+ std::list<FeaturePtr>& theConcealers, const ResultPtr theResultOfFeature,
+ const bool theCheckWholeFeature)
{
std::set<FeaturePtr> alreadyProcessed;
alreadyProcessed.insert(theFeature);
}
std::list<ResultPtr>::const_iterator aRootIter = aRootRes.cbegin();
for(; aRootIter != aRootRes.cend(); aRootIter++) {
- std::list<ResultPtr> allRes;
- allRes.push_back(*aRootIter);
+ std::list<DataPtr> allRes;
+ allRes.push_back((*aRootIter)->data());
ResultBodyPtr aRootBody = ModelAPI_Tools::bodyOwner(*aRootIter, true);
if (!aRootBody.get())
aRootBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRootIter);
if (aRootBody.get()) {
- ModelAPI_Tools::allSubs(aRootBody, allRes);
- }
- for(std::list<ResultPtr>::iterator aRIter = allRes.begin(); aRIter != allRes.end(); aRIter++) {
- const std::set<AttributePtr>& aRefs = (*aRIter)->data()->refsToMe();
+ std::list<ResultPtr> allSub;
+ ModelAPI_Tools::allSubs(aRootBody, allSub);
+ for(std::list<ResultPtr>::iterator anIt = allSub.begin(); anIt != allSub.end(); anIt++)
+ allRes.push_back((*anIt)->data());
+ }
+ if (theCheckWholeFeature)
+ allRes.push_back(theFeature->data());
+ for(std::list<DataPtr>::iterator aRIter = allRes.begin(); aRIter != allRes.end(); aRIter++) {
+ const std::set<AttributePtr>& aRefs = (*aRIter)->refsToMe();
std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
for (; aRef != aRefs.cend(); aRef++) {
if (!aRef->get() || !(*aRef)->owner().get())
}
}
}
- // in case sketch line was selected for wire, but wire was concealed and not such line anymore,
- // so, actually, the sketch element was selected (which is never concealed)
- if (aResult != theCurrent && aResult->isConcealed())
- aResult = theCurrent;
+ // in case sketch line was selected for wire, but wire was concealed and there is no such line
+ // anymore, so, actually, the sketch element was selected (which is never concealed)
+ if (aResult != theCurrent && theCurrent->groupName() == ModelAPI_ResultConstruction::group()) {
+ std::list<FeaturePtr> aConcealers;
+ FeaturePtr aResFeature = aDoc->feature(aResult);
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ concealedFeature(aResFeature, aThisFeature, false, aConcealers, aResult, true);
+ if (aConcealers.size())
+ aResult = theCurrent;
+ }
return aResult;
}
/// Updates the arguments of selection if something was affected by creation
/// or reorder of features upper in the history line (issue #1757)
/// Returns theRemove true if this attribute must be removed (become deleted)
- MODEL_EXPORT virtual void updateInHistory(bool& theRemove);
+ MODEL_EXPORT virtual void updateInHistory(bool& theRemove) override;
// Implementation of the name generator method from the Selector package
// This method returns the context name by the label of the sub-selected shape
/// theResultOfFeature if not null defines exact referenced result of a feature
void concealedFeature(
const FeaturePtr theFeature, const FeaturePtr theStop, const bool theCheckCopy,
- std::list<FeaturePtr>& theConcealers, const ResultPtr theResultOfFeature);
+ std::list<FeaturePtr>& theConcealers, const ResultPtr theResultOfFeature,
+ const bool theCheckWholeFeature = false);
friend class Model_Data;
friend class Model_AttributeSelectionList;
{
std::shared_ptr<Model_Session> aSession =
std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get());
+ if (!aSession->hasModuleDocument() || !myObjs)
+ return FeaturePtr(); // this may be on close of the document
FeaturePtr aFeature = aSession->createFeature(theID, this);
if (!aFeature)
return aFeature;
bool Model_Objects::isLater(FeaturePtr theLater, FeaturePtr theCurrent) const
{
+ if (theLater->getKind() == "InternalSelectionInPartFeature")
+ return true;
std::shared_ptr<Model_Data> aLaterD = std::static_pointer_cast<Model_Data>(theLater->data());
std::shared_ptr<Model_Data> aCurrentD = std::static_pointer_cast<Model_Data>(theCurrent->data());
if (aLaterD.get() && aLaterD->isValid() && aCurrentD.get() && aCurrentD->isValid()) {
AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature();
AttributeSelectionPtr aThisAttr = aSelAttr->value(theIndex - 1);
if (aThisAttr.get()) {
- return aThisAttr->update();
+ if (aThisAttr->update()) {
+ bool aRemove = false;
+ aThisAttr->updateInHistory(aRemove);
+ return true; // it was updated
+ }
}
}
return false; // something is wrong
{
Model_Application::getApplication()->deleteAllDocuments();
static const Events_ID aDocChangeEvent = Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED);
+ myCurrentDoc = NULL;
static std::shared_ptr<Events_Message> aMsg(new Events_Message(aDocChangeEvent));
Events_Loop::loop()->send(aMsg);
Events_Loop::loop()->flush(aDocChangeEvent);
anApp->createDocument(0); // 0 is a root ID
// creation of the root document is always outside of the transaction, so, avoid checking it
setCheckTransactions(true);
+ if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id())) {
+ myCurrentDoc = moduleDocument();
+ static std::shared_ptr<Events_Message> aMsg(
+ new Events_Message(Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)));
+ Events_Loop::loop()->send(aMsg);
+ }
}
return anApp->rootDocument();
}
std::shared_ptr<ModelAPI_Document> Model_Session::activeDocument()
{
- if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id()))
- myCurrentDoc = moduleDocument();
+ if (!myCurrentDoc || !Model_Application::getApplication()->hasDocument(myCurrentDoc->id())) {
+ return moduleDocument();
+ }
return myCurrentDoc;
}
#include <Model_Document.h>
#include <Model_Data.h>
#include <Model_Objects.h>
-#include <Model_AttributeSelection.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
aFeatures.push_back(*anObjIter);
} else {
aResults.push_back(*anObjIter);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*anObjIter);
+ if (aPart.get() && aPart->data().get() && aPart->data()->isValid()) {
+ aPart->shape(); // to update the shape on creation of the result
+ }
}
}
}
bool isObligatory = aFactory->isCase(theFeature, theFeature->data()->id(aSel));
if (isObligatory)
aState = ModelAPI_StateInvalidArgument;
+ } else if (theFeature->getKind() == "Sketch" && aSel->id() == "External" &&
+ aSel->isInitialized()) {
+ // #19703 : if sketch plane was selected, but after context disappears, it must become invalid
+ aSel->update();
+ if (aSel->isInvalid()) {
+ aState = ModelAPI_StateInvalidArgument;
+ }
}
}
// update the selection list attributes if any
(*anObj)->data()->attributes(ModelAPI_AttributeSelection::typeId());
std::list<AttributePtr>::iterator aRefsIter = aRefs.begin();
for (; aRefsIter != aRefs.end(); aRefsIter++) {
- std::shared_ptr<Model_AttributeSelection> aSel =
- std::dynamic_pointer_cast<Model_AttributeSelection>(*aRefsIter);
+ AttributeSelectionPtr aSel =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
bool aRemove = false;
aSel->updateInHistory(aRemove);
}
std::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
for(int a = aSel->size() - 1; a >= 0; a--) {
- std::shared_ptr<Model_AttributeSelection> aSelAttr =
- std::dynamic_pointer_cast<Model_AttributeSelection>(aSel->value(a));
+ AttributeSelectionPtr aSelAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(aSel->value(a));
if (aSelAttr.get()) {
- bool theRemove = false;
- aSelAttr->updateInHistory(theRemove);
- if (theRemove) {
+ bool aRemove = false;
+ aSelAttr->updateInHistory(aRemove);
+ if (aRemove) {
aRemoveSet.insert(a);
}
}
Test19019_2.py
Test19031.py
Test19058.py
+ Test19217.py
+ Test19707.py
+ Test19726.py
)
/// Makes the current local selection becomes all sub-shapes with same base geometry.
MODELAPI_EXPORT virtual void combineGeometrical() = 0;
+ /// Updates the arguments of selection if something was affected by creation
+ /// or reorder of features upper in the history line.
+ /// Returns theRemove true if this attribute must be removed (become deleted)
+ MODELAPI_EXPORT virtual void updateInHistory(bool& theRemove) = 0;
+
protected:
/// Objects are created for features automatically
MODELAPI_EXPORT ModelAPI_AttributeSelection();
--- /dev/null
+# Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Test if the Model_AttributeSelection::newestContext method work in case
+# the initial shell is concealed by multi-rotation (all-feature selection)
+# and the same sketch is used by a next shell.
+
+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"))
+SketchCircle_1 = Sketch_1.addCircle(47.53111880904039, 63.23707920074999, 11.27757708463696)
+model.do()
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("COMPOUND", "all-in-Shell_1")], model.selection("EDGE", "PartSet/OZ"), 3, keepSubResults = True)
+Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")])
+model.end()
+
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Shell_2.feature()))
+
+assert(model.checkPythonDump())
\ No newline at end of file
--- /dev/null
+# Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+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(-59.0465954847056, -128.5053642637967, 53.14364970069066, -170.5009266857805)
+SketchLine_2 = Sketch_1.addLine(53.14364970069066, -170.5009266857805, 137.6705343466976, -112.5874503884433)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(137.6705343466976, -112.5874503884433, 64.87485797099055, -26.90480166687218)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(64.87485797099055, -26.90480166687218, 3.969957323886124, -72.35673939469255)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(3.969957323886124, -72.35673939469255, -79.2369959888606, -34.8592213882167)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-79.2369959888606, -34.8592213882167, -59.0465954847056, -128.5053642637967)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_6.endPoint())
+SketchLine_7 = Sketch_1.addLine(53.14364970069066, -170.5009266857805, 3.969957323886124, -72.35673939469255)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_7.endPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.startPoint(), SketchLine_1.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_3"))
+SketchCircle_1 = Sketch_2.addCircle(110.5461396183937, -4.403937604408839, 25.15832463432426)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.end()
+
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Sketch_2.feature()))
+assert(aFactory.validate(Extrusion_2.feature()))
+
+# update the first extrusion to make the second bas plane selection invalid
+model.begin()
+Extrusion_1.setBase([model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_7f-SketchLine_5f-SketchLine_6f")])
+model.end()
+
+# check that the second sketch and extrusion become invalid
+assert(len(Sketch_2.results()) == 0)
+assert(len(Extrusion_2.results()) == 0)
--- /dev/null
+# Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from ModelAPI 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("XOZ"))
+SketchCircle_1 = Sketch_1.addCircle(18.39021699364881, 11.50401662688171, 4.123179523509023)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.do()
+Translation_1 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_1/")], axis = model.selection("EDGE", "Part_1/([Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/From_Face])([Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face])"), distance = 20, keepSubResults = True)
+aName1 = Translation_1.axisObject().namingName()
+model.end()
+
+# update the extrusion in the part, so, outside the part selection must be moved in history
+model.begin()
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], axis = model.selection("EDGE", "PartSet/OY"), angle = 45)
+model.do()
+aSession = ModelAPI_Session.get()
+aSession.setActiveDocument(partSet)
+model.end()
+
+# check that name was changed to the rotation
+aName2 = Translation_1.axisObject().namingName()
+assert(aName1 != aName2)
+assert(len(aName2) > 7)
+
+assert(model.checkPythonDump())
#include <GeomAPI_PlanarEdges.h>
#include <GeomAPI_Pnt.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
#ifdef WIN32
#pragma warning(disable : 4996) // for sprintf
for (std::list<GeomShapePtr>::const_iterator aSubIt = aSubs.begin();
aSubIt != aSubs.end(); ++aSubIt) {
GeomPointPtr aMiddlePoint = (*aSubIt)->middlePoint();
- if (aMiddlePoint && aMiddlePoint->distance(thePoint) < theTolerance)
+ if (!aMiddlePoint)
+ continue;
+
+ double aDistance = aMiddlePoint->distance(thePoint);
+ bool isFound = aDistance < theTolerance;
+ // issue #19019: special workaround for faces, because if the face contains B-spline contour,
+ // the middle point is calculated with respect to its poles, but not a curve itself.
+ // Thus is some operations (like BOP) the curve may have different number of poles
+ // from time to time, as a result, the face parametric boundaries are floating
+ // as well as the middle point.
+ // The workaround is to find a distance from the picking point to the face, if the distance
+ // between the picking point and the middle point on the face is small to some extend.
+ static const double THE_THRESHOLD = 100.;
+ if (!isFound && aDistance < THE_THRESHOLD * theTolerance && (*aSubIt)->isFace()) {
+ GeomVertexPtr aVertex(new GeomAPI_Vertex(thePoint));
+ aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aVertex, *aSubIt);
+ isFound = aDistance < theTolerance;
+ }
+ if (isFound)
aFoundSubs.push_back(*aSubIt);
}
return aFoundSubs;
void ModelHighAPI_Interface::setName(const std::string& theName)
{
- if (feature().get())
+ if (feature().get() && feature()->data()->isValid())
feature()->data()->setName(theName);
+ else {
+ std::cout<<"Error: set name "<<theName.c_str()<<" for an invalid feature"<<std::endl;
+ }
}
std::string ModelHighAPI_Interface::name() const
SessionPtr aMgr = ModelAPI_Session::get();
std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
- aParameter = aDoc->addFeature("Parameter");
+ aParameter = aDoc->addFeature("Parameter", false);
if (aParameter.get()) {
AttributeStringPtr aNameAttr = aParameter->string("variable");
aNameAttr->setValue(aParamName.toStdString());
void ModuleBase_WidgetSelectionFilter::onShowOnly(bool theShow)
{
- if (myPreview.IsNull())
- return;
Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
-
if (theShow) {
AIS_ListOfInteractive aList;
aCtx->DisplayedObjects(AIS_KOI_Shape, -1, aList);
- aList.Remove(myPreview);
+ if (!myPreview.IsNull())
+ aList.Remove(myPreview);
if (aList.Size() > 0)
myListIO = aList;
}
AIS_ListOfInteractive::const_iterator aIt;
Handle(AIS_Shape) aShapeIO;
+ bool isModified = false;
for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) {
aShapeIO = Handle(AIS_Shape)::DownCast(*aIt);
if (!aShapeIO.IsNull()) {
- if (theShow)
- aCtx->Erase(aShapeIO, false);
+ if (theShow) {
+ if (aCtx->IsDisplayed(aShapeIO)) {
+ aCtx->Erase(aShapeIO, false);
+ isModified = true;
+ }
+ }
else {
- aCtx->Display(aShapeIO, false);
- std::shared_ptr<GeomAPI_AISObject> anAISObj = AISObjectPtr(new GeomAPI_AISObject());
- anAISObj->setImpl(new Handle(AIS_InteractiveObject)(aShapeIO));
- myWorkshop->applyCurrentSelectionModes(anAISObj);
+ if (!aCtx->IsDisplayed(aShapeIO)) {
+ aCtx->Display(aShapeIO, false);
+ std::shared_ptr<GeomAPI_AISObject> anAISObj = AISObjectPtr(new GeomAPI_AISObject());
+ anAISObj->setImpl(new Handle(AIS_InteractiveObject)(aShapeIO));
+ myWorkshop->applyCurrentSelectionModes(anAISObj);
+ isModified = true;
+ }
}
}
}
- myWorkshop->viewer()->update();
+ if (isModified)
+ myWorkshop->viewer()->update();
}
void ModuleBase_WidgetSelectionFilter::updateSelectBtn()
{
int aNb = myValues.size();
myNbLbl->setText(QString::number(aNb));
- if (aNb == 0)
+ if (aNb == 0) {
myFeature->setError(translate("Selection is empty").toStdString(), false, false);
+ myShowBtn->setChecked(false);
+ onShowOnly(false);
+ myShowBtn->setEnabled(false);
+ }
else {
myFeature->setError("", false, false);
myFeature->data()->execState(ModelAPI_StateDone);
+ myShowBtn->setEnabled(true);
}
}
/// Restart sketcher operations automatically
if (!mySketchReentrantMgr->operationCommitted(theOperation)) {
-
- ModuleBase_OperationFeature* aFOperation =
- dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
- if (aFOperation && !aFOperation->isEditOperation()) {
- // the selection is cleared after commit the create operation
- // in order to do not use the same selected objects in the restarted operation
- // for common behaviour, the selection is cleared even if the operation is not restarted
- getWorkshop()->selector()->clearSelection();
- }
+ getWorkshop()->selector()->clearSelection();
}
}
/// deactivate of overconstraint listener should be performed after Sketch abort (#2176)
if (PartSet_SketcherMgr::isSketchOperation(theOperation))
overconstraintListener()->setActive(false);
+
+ getWorkshop()->selector()->clearSelection();
}
//******************************************************
void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMessage)
{
if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ if (!aMgr->hasModuleDocument()) // if document is closed, do not call the document creation
+ return;
// Do not change activation of parts if an operation active
static QStringList aAllowActivationList;
if (aAllowActivationList.isEmpty())
(!aAllowActivationList.contains(myWorkshop->currentOperation()->id())))
return;
XGUI_Workshop* aWorkshop = getWorkshop();
- XGUI_DataTree* aTreeView = aWorkshop->objectBrowser()->treeView();
- QLabel* aLabel = aWorkshop->objectBrowser()->activeDocLabel();
- QPalette aPalet = aLabel->palette();
+ bool needUpdate = false;
+ XGUI_DataTree* aTreeView;
+ if (aWorkshop->objectBrowser()) {
+ aTreeView = aWorkshop->objectBrowser()->treeView();
+ QLabel* aLabel = aWorkshop->objectBrowser()->activeDocLabel();
+ QPalette aPalet = aLabel->palette();
- SessionPtr aMgr = ModelAPI_Session::get();
- DocumentPtr aActiveDoc = aMgr->activeDocument();
+ DocumentPtr aActiveDoc = aMgr->activeDocument();
- // Clear active part index if there is no Part documents
- // It could be not null if document was closed and opened a new
- // without closeDocument call
- if (aMgr->allOpenedDocuments().size() <= 1)
- myActivePartIndex = QModelIndex();
+ // Clear active part index if there is no Part documents
+ // It could be not null if document was closed and opened a new
+ // without closeDocument call
+ if (aMgr->allOpenedDocuments().size() <= 1)
+ myActivePartIndex = QModelIndex();
- XGUI_DataModel* aDataModel = aWorkshop->objectBrowser()->dataModel();
- QModelIndex aOldActive = myActivePartIndex;
- myActivePartIndex = aDataModel->documentRootIndex(aActiveDoc, 0);
- bool needUpdate = false;
- if (myActivePartIndex.isValid()) {
- needUpdate = aTreeView->isExpanded(myActivePartIndex);
- if (!needUpdate)
- aTreeView->setExpanded(myActivePartIndex, true);
- }
- if ((aOldActive != myActivePartIndex) && (aOldActive.isValid()))
- aTreeView->setExpanded(aOldActive, false);
+ XGUI_DataModel* aDataModel = aWorkshop->objectBrowser()->dataModel();
+ QModelIndex aOldActive = myActivePartIndex;
+ myActivePartIndex = aDataModel->documentRootIndex(aActiveDoc, 0);
+ if (myActivePartIndex.isValid()) {
+ needUpdate = aTreeView->isExpanded(myActivePartIndex);
+ if (!needUpdate)
+ aTreeView->setExpanded(myActivePartIndex, true);
+ }
+ if ((aOldActive != myActivePartIndex) && (aOldActive.isValid()))
+ aTreeView->setExpanded(aOldActive, false);
- aLabel->setPalette(aPalet);
+ aLabel->setPalette(aPalet);
+ }
aWorkshop->updateCommandStatus();
// Update displayed objects in order to update active color
// change deviation coefficient to provide more precise circle
// as there is no result, the shape is processed to correct deviation. To be unified
ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer);
- ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, DynamicHilightAttributes());
+ //This presentation is not used for selection, so it don't need highlighting
+ //ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, DynamicHilightAttributes());
if (myUseAISWidth) {
Handle(AIS_InteractiveObject) anIO = anIter.Value();
aRLast = aResults.end();
for (; aRIt != aRLast; aRIt++) {
ResultPtr aResult = *aRIt;
- GeomShapePtr aGeomShape = aResult->shape();
- appendShapeIfVisible(theWorkshop, aResult, aGeomShape, theObjectShapes);
+ if (!aResult->isDisabled()) {
+ GeomShapePtr aGeomShape = aResult->shape();
+ appendShapeIfVisible(theWorkshop, aResult, aGeomShape, theObjectShapes);
+ }
}
}
myShape = GeomAlgoAPI_FaceBuilder::squareFace(
myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize);
}
+ else if (myIsUseSizeOfView && (mySizeOfView > 0)) {
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(myShape));
+ std::shared_ptr<GeomAPI_Pln> aPlane = aFace->getPlane();
+ if (aPlane.get()) {
+ double anA, aB, aC, aD;
+ aPlane->coefficients(anA, aB, aC, aD);
+ std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
+ std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
+ std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
+ aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
+ std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
+ myShape = GeomAlgoAPI_FaceBuilder::squareFace(
+ myViewCentralPoint.get() ? myViewCentralPoint : anOrigPnt, aNormDir, mySizeOfView);
+ }
+ }
myPlane = createPreviewPlane();
aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
}
myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
launchEditing();
- if (aFeature.get() != NULL) {
- std::shared_ptr<SketchPlugin_Feature> aSPFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- if (aSPFeature.get() &&
- (aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID() ||
- aSPFeature->getKind() == SketchPlugin_ConstraintAngle::ID())) {
- DataPtr aData = aSPFeature->data();
- AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
- std::shared_ptr<GeomDataAPI_Point2D> aFPAttr =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aAttr);
- aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY);
- }
- }
} else if (isSketchOpe && isEditing) {
// If selected another object commit current result
bool aPrevLaunchingState = myIsEditLaunching;
if (aOCListener->isConflictingObject(theObject)) {
return Config_PropManager::color("Visualization", "sketch_overconstraint_color");
}
- if (aOCListener->isFullyConstrained()) {
- return Config_PropManager::color("Visualization", "sketch_fully_constrained_color");
- }
if (isDistanceKind(aKind)) {
return Config_PropManager::color("Visualization", "sketch_dimension_color");
}
+ if (isExternal(theFeature))
+ return Config_PropManager::color("Visualization", "sketch_external_color");
+
+ if (aOCListener->isFullyConstrained()) {
+ return Config_PropManager::color("Visualization", "sketch_fully_constrained_color");
+ }
if (aKind == SketchPlugin_ConstraintCoincidence::ID())
return std::vector<int>(3, 0);
- if (isExternal(theFeature))
- return Config_PropManager::color("Visualization", "sketch_external_color");
if (isConstruction)
return Config_PropManager::color("Visualization", "sketch_auxiliary_color");
anIntoResult->setValue(SKETCH_PROJECTION_INCLUDE_INTO_RESULT);
aProjectionFeature->execute();
+ ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ bool isValid = aValidators->validate(aProjectionFeature);
+
// if projection feature has not been created, exit
AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr(
SketchPlugin_Projection::PROJECTED_FEATURE_ID());
- if (!aRefAttr || !aRefAttr->isInitialized())
+ if (!isValid || !aRefAttr || !aRefAttr->isInitialized())
{
// remove external feature if the attribute is not filled
std::set<FeaturePtr> aFeatures;
#include <ModelAPI_Tools.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Events.h>
-#include <ModelAPI_ResultConstruction.h>
#include <ModuleBase_Operation.h>
#include <ModuleBase_ViewerPrs.h>
// 1. hide main planes if they have been displayed and display sketch preview plane
myPreviewPlanes->erasePreviewPlanes(myWorkshop);
+ QString aSizeOfViewStr = mySizeOfView->text();
+ bool isSetSizeOfView = false;
+ double aSizeOfView = 0;
+ if (!aSizeOfViewStr.isEmpty()) {
+ aSizeOfView = aSizeOfViewStr.toDouble(&isSetSizeOfView);
+ if (isSetSizeOfView && aSizeOfView <= 0) {
+ isSetSizeOfView = false;
+ }
+ }
PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
if (aModule) {
CompositeFeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
- bool isSetSizeOfView = false;
- double aSizeOfView = 0;
- QString aSizeOfViewStr = mySizeOfView->text();
- if (!aSizeOfViewStr.isEmpty()) {
- aSizeOfView = aSizeOfViewStr.toDouble(&isSetSizeOfView);
- if (isSetSizeOfView && aSizeOfView <= 0) {
- isSetSizeOfView = false;
- }
- }
aModule->sketchMgr()->previewSketchPlane()->setSizeOfView(aSizeOfView, isSetSizeOfView);
- if (myViewVisible->isChecked())
- aModule->sketchMgr()->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
+ // Call of createSketchPlane is managed by events Loop
+ //if (myViewVisible->isChecked())
+ // aModule->sketchMgr()->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
}
// 2. if the planes were displayed, change the view projection
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);
- }
+ if (isSetSizeOfView && 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);
}
}
if (myOpenTransaction) {
{
bool isOwnerSet = false;
- GeomShapePtr aShape = thePrs->shape();
+ const GeomShapePtr& aShape = thePrs->shape();
std::shared_ptr<GeomAPI_Dir> aDir;
- if (!aShape.get() || aShape->isNull()) {
- if (thePrs->object() && (feature() != thePrs->object())) {
- if (thePrs->object()->groupName() == ModelAPI_ResultConstruction::group()) {
- ResultConstructionPtr aConstruction =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(thePrs->object());
- if (aConstruction.get())
- aShape = aConstruction->shape();
- }
- }
- }
-
if (aShape.get() && !aShape->isNull()) {
const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
aDir = setSketchPlane(aTDShape);
isOwnerSet = aDir.get();
}
if (thePrs->object() && (feature() != thePrs->object())) {
- if (thePrs->object()->groupName() != ModelAPI_ResultConstruction::group()) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(thePrs->object());
- DataPtr aData = feature()->data();
- AttributeSelectionPtr aSelAttr =
- std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
- (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
- if (aSelAttr.get()) {
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePrs->object());
- if (aRes.get()) {
- GeomShapePtr aShapePtr;
- if (!aShape.get() || aShape->isNull()) { // selection happens in the OCC viewer
- aShapePtr = ModelAPI_Tools::shape(aRes);
- }
- else { // selection happens in OB browser
- aShapePtr = aShape;
- }
- if (aShapePtr.get() && aShapePtr->isFace()) {
- const TopoDS_Shape& aTDShape = aShapePtr->impl<TopoDS_Shape>();
- setSketchPlane(aTDShape);
- aSelAttr->setValue(aRes, aShapePtr);
- isOwnerSet = true;
- }
+ FeaturePtr aFeature = ModelAPI_Feature::feature(thePrs->object());
+ DataPtr aData = feature()->data();
+ AttributeSelectionPtr aSelAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+ (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+ if (aSelAttr.get()) {
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePrs->object());
+ if (aRes.get()) {
+ GeomShapePtr aShapePtr;
+ if (!aShape.get() || aShape->isNull()) { // selection happens in the OCC viewer
+ aShapePtr = ModelAPI_Tools::shape(aRes);
}
- else {
- aSelAttr->setValue(aFeature, GeomShapePtr());
- GeomShapePtr aSelShape = aSelAttr->value();
- if (!aSelShape.get() && aSelAttr->contextFeature().get() &&
- aSelAttr->contextFeature()->firstResult().get()) {
- aSelShape = aSelAttr->contextFeature()->firstResult()->shape();
- }
- if (aSelShape.get() && aSelShape->isPlanar()) {
- const TopoDS_Shape& aTDShape = aSelShape->impl<TopoDS_Shape>();
- setSketchPlane(aTDShape);
- isOwnerSet = true;
- }
+ else { // selection happens in OB browser
+ aShapePtr = aShape;
+ }
+ if (aShapePtr.get() && aShapePtr->isFace()) {
+ const TopoDS_Shape& aTDShape = aShapePtr->impl<TopoDS_Shape>();
+ setSketchPlane(aTDShape);
+ aSelAttr->setValue(aRes, aShapePtr);
+ isOwnerSet = true;
+ }
+ }
+ else {
+ aSelAttr->setValue(aFeature, GeomShapePtr());
+ GeomShapePtr aSelShape = aSelAttr->value();
+ if (!aSelShape.get() && aSelAttr->contextFeature().get() &&
+ aSelAttr->contextFeature()->firstResult().get()) {
+ aSelShape = aSelAttr->contextFeature()->firstResult()->shape();
+ }
+ if (aSelShape.get() && aSelShape->isPlanar()) {
+ const TopoDS_Shape& aTDShape = aSelShape->impl<TopoDS_Shape>();
+ setSketchPlane(aTDShape);
+ isOwnerSet = true;
}
}
}
.. _create_compound_Vertices:
.. |compoundVertices.icon| image:: images/compound.png
-compound Vertices
+Compound Vertices
=================
Compound Vertices is a feature and can be edited after execution.
.. _create_import_Parameters:
.. |importParameters.icon| image:: images/importParameters.png
-import Parameters
+Import Parameters
=================
Import Parameters is a macro-feature and can not be edited after execution.
#include <QMenu>
#include <QToolBar>
+#include <ModelAPI_Session.h>
+
#if OCC_VERSION_HEX < 0x070400
#define SALOME_PATCH_FOR_CTRL_WHEEL
#endif
#endif
createMenu(aId, aEditMenu);
+ if (!myInspectionPanel) {
+ myInspectionPanel = myWorkshop->inspectionPanel();
+ connect(myInspectionPanel->toggleViewAction(), SIGNAL(toggled(bool)),
+ this, SLOT(onWhatIs(bool)));
+ }
+ hideInternalWindows();
+
// Initialize viewer proxy if OCC viewer is already exist
ViewManagerList aOCCViewManagers;
application()->viewManagers(OCCViewer_Viewer::Type(), aOCCViewManagers);
}
}
}
+ SHAPERGUI_DataModel* aDataModel = dynamic_cast<SHAPERGUI_DataModel*>(dataModel());
+ aDataModel->initRootObject();
}
//******************************************************
//******************************************************
bool SHAPERGUI::activateModule(SUIT_Study* theStudy)
{
- bool isDone = LightApp_Module::activateModule(theStudy);
- loadToolbarsConfig();
+ ModelAPI_Session::get()->moduleDocument(); // initialize a root document if not done yet
+ // this must be done in the initialization and in activation (on the second activation
+ // initialization in not called, so SComponent must be added anyway
SHAPERGUI_DataModel* aDataModel = dynamic_cast<SHAPERGUI_DataModel*>(dataModel());
aDataModel->initRootObject();
+
+ bool isDone = LightApp_Module::activateModule(theStudy);
+ loadToolbarsConfig();
+
if (isDone) {
setMenuShown(true);
setToolShown(true);
aObjDoc->toggleViewAction()->setVisible(true);
}
- if (!myInspectionPanel) {
- myInspectionPanel = myWorkshop->inspectionPanel();
- connect(myInspectionPanel->toggleViewAction(), SIGNAL(toggled(bool)),
- this, SLOT(onWhatIs(bool)));
- }
myInspectionPanel->toggleViewAction()->setVisible(true);
myWorkshop->facesPanel()->toggleViewAction()->setVisible(true);
}
//******************************************************
-bool SHAPERGUI::deactivateModule(SUIT_Study* theStudy)
+void SHAPERGUI::hideInternalWindows()
{
- saveToolbarsConfig();
-
myProxyViewer->activateViewer(false);
setMenuShown(false);
setToolShown(false);
- myWorkshop->deactivateModule();
-
QObject* aObj = myWorkshop->objectBrowser()->parent();
QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
if (aObjDoc) {
aObjDoc->toggleViewAction()->setVisible(false);
}
- myIsInspectionVisible = myInspectionPanel->isVisible();
myInspectionPanel->hide();
myInspectionPanel->toggleViewAction()->setVisible(false);
- myIsFacesPanelVisible = myWorkshop->facesPanel()->isVisible();
myWorkshop->facesPanel()->hide();
myWorkshop->facesPanel()->toggleViewAction()->setVisible(false);
myWorkshop->propertyPanel()->hide();
myWorkshop->propertyPanel()->toggleViewAction()->setVisible(false);
+ myWorkshop->hidePanel(myWorkshop->facesPanel());
+}
+
+
+//******************************************************
+bool SHAPERGUI::deactivateModule(SUIT_Study* theStudy)
+{
+ saveToolbarsConfig();
+ myWorkshop->deactivateModule();
+
+ myIsInspectionVisible = myInspectionPanel->isVisible();
+ myIsFacesPanelVisible = myWorkshop->facesPanel()->isVisible();
+ hideInternalWindows();
+
+
// the active operation should be stopped for the next activation.
// There should not be active operation and visualized preview.
// Abort operation should be performed before the selection's remove
mySelector = 0;
}
- myWorkshop->hidePanel(myWorkshop->facesPanel());
//myWorkshop->contextMenuMgr()->disconnectViewer();
SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
void SHAPERGUI::publishToStudy()
{
- if (isActiveModule())
+ if (isActiveModule() && ModelAPI_Session::get()->hasModuleDocument())
myWorkshop->module()->launchOperation("PublishToStudy", false);
}
void saveToolbarsConfig();
void loadToolbarsConfig();
+
+ void hideInternalWindows();
+
/// List of registered nested actions
QStringList myNestedActionsList;
/// Creates a module root object if it has not been created yet
/// and append it to the active study. It is necessary for correct persistent
/// of the model.
- void initRootObject();
+ virtual void initRootObject() override;
/// Update data object
/// \param theObj an data object
Test3132.py
Test3154.py
Test3170.py
+ Test3240.py
Test19089.py
Test19101.py
TestArcBehavior.py
#include <cmath>
#include <regex>
#include <sstream>
+#include <vector>
const double tolerance = 1.e-7;
#define PI 3.1415926535897932
+// To support old types of GCC (less than 4.9), check the regular expressions are working
+#if (__cplusplus >= 201103L || _MSVC_LANG >= 201103L) && \
+ (__cplusplus >= 201402L || !defined(__GLIBCXX__) || \
+ (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
+ defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
+ (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4)))
+#define HAVE_WORKING_REGEX 1
+#else
+#define HAVE_WORKING_REGEX 0
+#endif
+
+
/// \brief Calculate intersection point of two lines
static std::shared_ptr<GeomAPI_Pnt2d> intersect(FeaturePtr theLine1, FeaturePtr theLine2);
return anAngle;
}
+#if !HAVE_WORKING_REGEX
+static bool parseString(const std::string& theString, std::ostringstream* theResult)
+{
+ // skip leading spaces
+ size_t aLength = theString.size();
+ size_t aPos = theString.find_first_not_of(' ');
+ if (aPos == std::string::npos)
+ return false;
+ // first should be a value
+ if (theString[aPos] == '-' || theString[aPos] == '+')
+ theResult[1] << theString[aPos++];
+ while (aPos < aLength && theString[aPos] >= '0' && theString[aPos] <= '9')
+ theResult[1] << theString[aPos++];
+ if (theString[aPos] != ' ') {
+ if (theString[aPos] != '.')
+ return false;
+ theResult[1] << theString[aPos++];
+ while (aPos < aLength && theString[aPos] >= '0' && theString[aPos] <= '9')
+ theResult[1] << theString[aPos++];
+ }
+
+ // next, find the sign
+ aPos = theString.find_first_not_of(' ', aPos);
+ if (aPos == std::string::npos)
+ return false;
+ if (theString[aPos] == '-' || theString[aPos] == '+')
+ theResult[2] << theString[aPos++];
+
+ // a variable should be at the end
+ aPos = theString.find_first_not_of(' ', aPos);
+ if (aPos == std::string::npos)
+ return false;
+ if (theString[aPos] != '(' || theString.back() != ')')
+ return false;
+ theResult[3] << theString.substr(aPos + 1, aLength - aPos - 2);
+
+ return true;
+}
+#endif
+
// Convert angle value or a text expression from one angle type to another
static void convertAngle(AttributeDoublePtr theAngle,
const int thePrevType, const int theNewType)
else {
// process the parametric value
std::string anAngleText = theAngle->text();
+#if HAVE_WORKING_REGEX
std::regex anAngleRegex("\\s*([-+]?[0-9]*\\.?[0-9]*)\\s*([-+])\\s*\\((.*)\\)$",
std::regex_constants::ECMAScript);
+#endif
double anAnglePrefix = 0.0;
static const char aSignPrefix[2] = { '-', '+' };
int aSignInd = 1;
+#if HAVE_WORKING_REGEX
std::smatch aResult;
if (std::regex_search(anAngleText, aResult, anAngleRegex)) {
+#else
+ // workaround to support old versions of GCC (less than 4.9)
+ std::ostringstream aResult[4];
+ if (parseString(anAngleText, aResult)) {
+#endif
anAnglePrefix = std::atof(aResult[1].str().c_str());
aSignInd = aResult[2].str()[0] == aSignPrefix[0] ? 0 : 1;
anAngleText = aResult[3].str();
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_BSpline.h>
#include <GeomAPI_Circ.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Ellipse.h>
SketchPlugin_Tools::findCoincidences(*anIt, SketchPlugin_Constraint::ENTITY_A(),
aCoinc, true);
- isValid = aCoinc.find(aOtherFea) != aCoinc.end();
+ std::set<FeaturePtr>::iterator aFoundCoinc = aCoinc.find(aOtherFea);
+ if (aFoundCoinc != aCoinc.end()) {
+ // do not take into account internal constraints
+ AttributeReferencePtr aParent =
+ (*aFoundCoinc)->reference(SketchPlugin_SketchEntity::PARENT_ID());
+ isValid = !aParent || !aParent->isInitialized() || aParent->value() != aRefFea;
+ }
}
}
theError.arg(anEdge->isClosed() ? "Error: Ellipse is orthogonal to the sketch plane."
: "Error: Elliptic Arc is orthogonal to the sketch plane.");
}
+ else if (anEdge->isBSpline()) {
+ // check B-spline is periodic and planar
+ std::shared_ptr<GeomAPI_Curve> aCurve(new GeomAPI_Curve(anEdge));
+ std::shared_ptr<GeomAPI_BSpline> aBSpline(new GeomAPI_BSpline(aCurve));
+ if (aBSpline->isPeriodic()) {
+ GeomPlanePtr aBSplinePlane = GeomAlgoAPI_ShapeTools::findPlane(ListOfShape(1, anEdge));
+ if (aBSplinePlane) {
+ std::shared_ptr<GeomAPI_Dir> aBSplineNormal = aBSplinePlane->direction();
+ double aDot = fabs(aNormal->dot(aBSplineNormal));
+ aValid = fabs(aDot - 1.0) <= tolerance * tolerance;
+ if (!aValid) {
+ // B-spline's plane is orthogonal to the sketch plane,
+ // thus, need to check whether B-spline is planar.
+ std::list<GeomPointPtr> aPoles = aBSpline->poles();
+ for (std::list<GeomPointPtr>::iterator it = aPoles.begin();
+ it != aPoles.end() && !aValid; ++it) {
+ if (aBSplinePlane->distance(*it) > tolerance)
+ aValid = true; // non-planar B-spline curve
+ }
+ if (!aValid)
+ theError = "Error: Periodic B-spline is orthogonal to the sketch plane.";
+ }
+ }
+ }
+ }
return aValid;
}
if (!aCopyAttr || !aCopyAttr->value())
return true; // feature is not a copy, thus valid
- // check the copy feature is already referred by the "Multi" feature
FeaturePtr aMultiFeature = ModelAPI_Feature::feature(theAttribute->owner());
+ // Collect original entities
+ std::set<FeaturePtr> anOriginalFeatures;
+ if (theArguments.size() > 1) {
+ AttributeRefListPtr anOrigList = aMultiFeature->reflist(theArguments.back());
+ for (int i = 0; i < anOrigList->size(); ++i)
+ {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anOrigList->object(i));
+ if (aFeature == anAttrOwnerFeature)
+ return true;
+ }
+ }
+
+ // check the copy feature is already referred by the "Multi" feature
AttributeRefListPtr aRefList = aMultiFeature->reflist(theArguments.front());
for (int i = 0; i < aRefList->size(); ++i)
{
<source>Error: Elliptic Arc is orthogonal to the sketch plane.</source>
<translation>Error: Elliptic Arc is orthogonal to the sketch plane.</translation>
</message>
+ <message>
+ <source>Error: Periodic B-spline is orthogonal to the sketch plane.</source>
+ <translation>Error: Periodic B-spline is orthogonal to the sketch plane.</translation>
+ </message>
<message>
<source>Error: Selected object is not supported for projection.</source>
<translation>Error: Selected object is not supported for projection.</translation>
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+ORIGIN = GeomAPI_Pnt(0, 0, 0)
+NB_COPIES = 8
+TOLERANCE = 1.e-7
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OX"), True)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchLine_1.result()], SketchAPI_Line(SketchLine_1).startPoint(), 360, NB_COPIES, True)
+[SketchLine_1, SketchLine_2, SketchLine_3, SketchLine_4, SketchLine_5, SketchLine_6, SketchLine_7, SketchLine_8] = SketchMultiRotation_1.rotated()
+model.do()
+model.end()
+
+model.testNbResults(Sketch_1, 1)
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.EDGE, [NB_COPIES])
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.VERTEX, [2 * NB_COPIES])
+
+midPnt = Sketch_1.defaultResult().shape().middlePoint()
+assert(midPnt.distance(ORIGIN) < TOLERANCE)
+
+assert(model.checkPythonDump())
<sketch_shape_selector id="ConstraintEntityA"
label="Mirror line" tooltip="Select mirror line" shape_types="edge">
<validator id="GeomValidators_ShapeType" parameters="line"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityC"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityC,ConstraintEntityB"/>
</sketch_shape_selector>
<sketch_multi_selector id="ConstraintMirrorList"
label="Segments"
shape_types="vertex">
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB,ConstraintEntityA"/>
</sketch_shape_selector>
<sketch_shape_selector
id="MultiTranslationEndPoint"
shape_types="vertex">
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB,ConstraintEntityA"/>
</sketch_shape_selector>
</groupbox>
</box>
shape_types="vertex">
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB,ConstraintEntityA"/>
</sketch_shape_selector>
<sketch_shape_selector
id="MultiTranslationEndPoint"
shape_types="vertex">
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB,ConstraintEntityA"/>
</sketch_shape_selector>
</groupbox>
</box>
tooltip="Center of rotation"
shape_types="vertex">
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
- <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB"/>
+ <validator id="SketchPlugin_ReplicationReference" parameters="ConstraintEntityB,ConstraintEntityA"/>
</sketch_shape_selector>
<toolbox id="AngleType">
<box id="FullAngle" title="Full angle" icon="icons/Sketch/angle_up_full_32x32.png">
bool SketcherPrs_LengthDimension::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
{
- gp_Pnt aPnt1, aPnt2;
+ gp_Pnt2d aPnt1, aPnt2;
return readyToDisplay(theConstraint, thePlane, aPnt1, aPnt2);
}
static bool isEqualPoints(ModelAPI_Feature* theConstraint,
- const gp_Pnt& thePoint1,
- const gp_Pnt& thePoint2)
+ const gp_Pnt2d& theP1, const gp_Pnt2d& theP2)
{
bool isEqual = false;
if (theConstraint->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID())
- isEqual = Abs(thePoint1.X() - thePoint2.X()) < Precision::Confusion();
+ isEqual = Abs(theP1.X() - theP2.X()) < Precision::Confusion();
else if (theConstraint->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
- isEqual = Abs(thePoint1.Y() - thePoint2.Y()) < Precision::Confusion();
- else
- isEqual = thePoint1.SquareDistance(thePoint2) < Precision::SquareConfusion();
+ isEqual = Abs(theP1.Y() - theP2.Y()) < Precision::Confusion();
+ else {
+ isEqual = theP1.SquareDistance(theP2) < Precision::SquareConfusion();
+ }
return isEqual;
}
{
if (!plane().get())
return;
- gp_Pnt aPnt1, aPnt2;
- bool aReadyToDisplay = readyToDisplay(myConstraint, plane(), aPnt1, aPnt2);
+ gp_Pnt2d aP1, aP2;
+ bool aReadyToDisplay = readyToDisplay(myConstraint, plane(), aP1, aP2);
if (aReadyToDisplay) {
- if (isEqualPoints(myConstraint, aPnt1, aPnt2)) {
+ if (isEqualPoints(myConstraint, aP1, aP2)) {
// adjust points to draw the dimension presentation
std::shared_ptr<GeomDataAPI_Dir> aDirAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
myConstraint->attribute(SketchPlugin_ConstraintDistance::DIRECTION_ID()));
y = 1.0;
else
x = 1.0;
- GeomPointPtr aCoord = plane()->to3D(x, y);
- gp_XYZ aDir(aCoord->x(), aCoord->y(), aCoord->z());
- aPnt1.ChangeCoord().Add(aDir * (-Precision::Confusion()));
- aPnt2.ChangeCoord().Add(aDir * Precision::Confusion());
+ gp_XY aDir(x, y);
+ aP1.ChangeCoord().Add(aDir * (-Precision::Confusion()));
+ aP2.ChangeCoord().Add(aDir * Precision::Confusion());
}
- myFirstPoint = aPnt1;
- mySecondPoint = aPnt2;
+ myFirstPoint = plane()->to3D(aP1.X(), aP1.Y())->impl<gp_Pnt>();
+ mySecondPoint = plane()->to3D(aP2.X(), aP2.Y())->impl<gp_Pnt>();
myDistance = SketcherPrs_Tools::getFlyoutDistance(myConstraint);
myPlane = gp_Pln(plane()->impl<gp_Ax3>());
bool SketcherPrs_LengthDimension::readyToDisplay(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane,
- gp_Pnt& thePnt1, gp_Pnt& thePnt2)
+ gp_Pnt2d& thePnt1, gp_Pnt2d& thePnt2)
{
if (!thePlane)
return false;
std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aLineData->attribute(SketchPlugin_Line::END_ID()));
- thePnt1 = thePlane->to3D(aStartPoint->x(), aStartPoint->y())->impl<gp_Pnt>();
- thePnt2 = thePlane->to3D(aEndPoint->x(), aEndPoint->y())->impl<gp_Pnt>();
+ thePnt1 = gp_Pnt2d(aStartPoint->x(), aStartPoint->y());
+ thePnt2 = gp_Pnt2d(aEndPoint->x(), aEndPoint->y());
return true;
} else if (theConstraint->getKind() == SketchPlugin_ConstraintDistance::ID() ||
if (!aPnt_A || !aPnt_B) // Objects not found
return false;
- /*if (theConstraint->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID()) {
- if (fabs(aPnt_A->x() - aPnt_B->x()) < Precision::Confusion())
- return false;
- }
- else if (theConstraint->getKind() == SketchPlugin_ConstraintDistanceVertical::ID()) {
- if (fabs(aPnt_A->y() - aPnt_B->y()) < Precision::Confusion())
- return false;
- }*/
-
// Get points from these object
- std::shared_ptr<GeomAPI_Pnt> aPoint1 = thePlane->to3D(aPnt_A->x(), aPnt_A->y());
- std::shared_ptr<GeomAPI_Pnt> aPoint2 = thePlane->to3D(aPnt_B->x(), aPnt_B->y());
- thePnt1 = aPoint1->impl<gp_Pnt>();
- thePnt2 = aPoint2->impl<gp_Pnt>();
+ thePnt1 = gp_Pnt2d(aPnt_A->x(), aPnt_A->y());
+ thePnt2 = gp_Pnt2d(aPnt_B->x(), aPnt_B->y());
return true;
}
return false;
private:
static bool readyToDisplay(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane,
- gp_Pnt& thePnt1, gp_Pnt& thePnt2);
+ gp_Pnt2d& thePnt1, gp_Pnt2d& thePnt2);
/// Set the direction for horizontal/vertical constraint
void setDirection(ModelAPI_Feature* theConstraint,
canBeShaded = aDisplayer->canBeShaded(aObject);
}
if (aShape.get()) {
- if (aShape->isPlanar()) {
- hasPlanar = true;
- }
+ hasPlanar = (aShape->isFace() && aShape->isPlanar());
}
}
if (isVisible) {
}
}
else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
- DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
- ModuleBase_ITreeNode* aRoot = myRoot->findRoot(aDoc);
- if (aRoot) {
- updateSubTree(aRoot);
+ if (ModelAPI_Session::get()->hasModuleDocument()) {
+ DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument();
+ ModuleBase_ITreeNode* aRoot = myRoot->findRoot(aDoc);
+ if (aRoot) {
+ updateSubTree(aRoot);
+ }
}
}
else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) {
Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
if (!BROwnr.IsNull() && BROwnr->HasShape()) {
const TopoDS_Shape& aShape = BROwnr->Shape();
+
+ Handle(ModuleBase_ResultPrs) aResPrs =
+ Handle(ModuleBase_ResultPrs)::DownCast(BROwnr->Selectable());
+ TopoDS_Shape aRealShape;
+ if (!aResPrs.IsNull()) {
+ aRealShape = aResPrs->originalShape();
+ }
+
if (aShape.IsNull())
continue;
// isSame should be used here as it does not check orientation of shapes
// despite on isEqual of shapes or IsBound for shape in QMap. Orientation is
// different for Edges shapes in model shape and owner even if this is the same shape
- if (ModuleBase_Tools::isSameShape(aParameterShape, aShape)) {
+ bool isSame = ModuleBase_Tools::isSameShape(aParameterShape, aShape);
+ if (!isSame) {
+ // In case of using HideFaces panel we can have instead of an original shape
+ // a compaund of faces which represent original shape with hidden faces.
+ // So, we have to compare the parameter with original shape
+ if (!aRealShape.IsNull())
+ isSame = ModuleBase_Tools::isSameShape(aParameterShape, aRealShape);
+ }
+ if (isSame) {
Handle(AIS_InteractiveObject) anOwnerPresentation =
Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
ResultConstructionPtr aConstr = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aObj);
FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
if (aFeature) {
- notDelete = (!aFeature->isInHistory()) && aConstr->isInfinite();
+ notDelete = (!aFeature->isInHistory()) && (aConstr && aConstr->isInfinite());
if (notDelete) {
anObjects.removeAll(aObj);
aIt--;
GeomShapePtr aPlanarFace;
foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) {
GeomShapePtr aShape = aPrs->shape();
- if (aShape.get() && aShape->isPlanar()) {
+ if (aShape.get() && aShape->isFace() && aShape->isPlanar()) {
aPlanarFace = aShape;
break;
}
# Test reexecution after parameter change
Parameter_H.setValue(14)
model.do()
-model.testResultsVolumes(ExtrusionCut_2, [10205.255531030932615976780653000])
+model.testResultsVolumes(ExtrusionCut_2, [10205.25717])
Parameter_H.setValue(12)
model.end()
aPartFeature = locals()["Part_1"]
model.testNbResults(aPartFeature, 1)
model.testNbSubResults(aPartFeature, [0])
- model.testNbSubShapes(aPartFeature, GeomAPI_Shape.SOLID, [552])
- model.testNbSubShapes(aPartFeature, GeomAPI_Shape.FACE, [4086])
- model.testNbSubShapes(aPartFeature, GeomAPI_Shape.EDGE, [17086])
- model.testNbSubShapes(aPartFeature, GeomAPI_Shape.VERTEX, [34172])
- model.testResultsVolumes(aPartFeature, [55.645173358299])
+ model.testNbSubShapes(aPartFeature, GeomAPI_Shape.SOLID, [553])
+ model.testNbSubShapes(aPartFeature, GeomAPI_Shape.FACE, [4089])
+ model.testNbSubShapes(aPartFeature, GeomAPI_Shape.EDGE, [17094])
+ model.testNbSubShapes(aPartFeature, GeomAPI_Shape.VERTEX, [34188])
+ model.testResultsVolumes(aPartFeature, [55.64517345856])
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+if __name__ == "__main__":
+ Part_1 = locals()["Part_1"]
+ model.testNbResults(Part_1, 1)
+ model.testNbSubResults(Part_1, [0])
+ model.testNbSubShapes(Part_1, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_1, GeomAPI_Shape.FACE, [20])
+ model.testNbSubShapes(Part_1, GeomAPI_Shape.EDGE, [104])
+ model.testNbSubShapes(Part_1, GeomAPI_Shape.VERTEX, [208])
+ model.testResultsVolumes(Part_1, [937708.6935593])
+
+ Part_2 = locals()["Part_2"]
+ model.testNbResults(Part_2, 1)
+ model.testNbSubResults(Part_2, [0])
+ model.testNbSubShapes(Part_2, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_2, GeomAPI_Shape.FACE, [12])
+ model.testNbSubShapes(Part_2, GeomAPI_Shape.EDGE, [60])
+ model.testNbSubShapes(Part_2, GeomAPI_Shape.VERTEX, [120])
+ model.testResultsVolumes(Part_2, [256665.8235477])
+
+ Part_3 = locals()["Part_3"]
+ model.testNbResults(Part_3, 1)
+ model.testNbSubResults(Part_3, [0])
+ model.testNbSubShapes(Part_3, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_3, GeomAPI_Shape.FACE, [12])
+ model.testNbSubShapes(Part_3, GeomAPI_Shape.EDGE, [60])
+ model.testNbSubShapes(Part_3, GeomAPI_Shape.VERTEX, [120])
+ model.testResultsVolumes(Part_3, [2719045.0529109])
+
+ Part_4 = locals()["Part_4"]
+ model.testNbResults(Part_4, 1)
+ model.testNbSubResults(Part_4, [0])
+ model.testNbSubShapes(Part_4, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_4, GeomAPI_Shape.FACE, [6])
+ model.testNbSubShapes(Part_4, GeomAPI_Shape.EDGE, [24])
+ model.testNbSubShapes(Part_4, GeomAPI_Shape.VERTEX, [48])
+ model.testResultsVolumes(Part_4, [534313.7153742])
+
+ Part_5 = locals()["Part_5"]
+ model.testNbResults(Part_5, 1)
+ model.testNbSubResults(Part_5, [0])
+ model.testNbSubShapes(Part_5, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_5, GeomAPI_Shape.FACE, [19])
+ model.testNbSubShapes(Part_5, GeomAPI_Shape.EDGE, [96])
+ model.testNbSubShapes(Part_5, GeomAPI_Shape.VERTEX, [192])
+ model.testResultsVolumes(Part_5, [1111187.2858512])
+
+ Part_6 = locals()["Part_6"]
+ model.testNbResults(Part_6, 1)
+ model.testNbSubResults(Part_6, [0])
+ model.testNbSubShapes(Part_6, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_6, GeomAPI_Shape.FACE, [12])
+ model.testNbSubShapes(Part_6, GeomAPI_Shape.EDGE, [60])
+ model.testNbSubShapes(Part_6, GeomAPI_Shape.VERTEX, [120])
+ model.testResultsVolumes(Part_6, [124567.8141964])
+
+ Part_7 = locals()["Part_7"]
+ model.testNbResults(Part_7, 1)
+ model.testNbSubResults(Part_7, [0])
+ model.testNbSubShapes(Part_7, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_7, GeomAPI_Shape.FACE, [12])
+ model.testNbSubShapes(Part_7, GeomAPI_Shape.EDGE, [60])
+ model.testNbSubShapes(Part_7, GeomAPI_Shape.VERTEX, [120])
+ model.testResultsVolumes(Part_7, [3106355.9518294])
+
+ Part_8 = locals()["Part_8"]
+ model.testNbResults(Part_8, 1)
+ model.testNbSubResults(Part_8, [0])
+ model.testNbSubShapes(Part_8, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_8, GeomAPI_Shape.FACE, [6])
+ model.testNbSubShapes(Part_8, GeomAPI_Shape.EDGE, [24])
+ model.testNbSubShapes(Part_8, GeomAPI_Shape.VERTEX, [48])
+ model.testResultsVolumes(Part_8, [570471.5090269])
+
+ Part_9 = locals()["Part_9"]
+ model.testNbResults(Part_9, 1)
+ model.testNbSubResults(Part_9, [0])
+ model.testNbSubShapes(Part_9, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_9, GeomAPI_Shape.FACE, [7])
+ model.testNbSubShapes(Part_9, GeomAPI_Shape.EDGE, [30])
+ model.testNbSubShapes(Part_9, GeomAPI_Shape.VERTEX, [60])
+ model.testResultsVolumes(Part_9, [1688917.3777022])
+
+ Part_10 = locals()["Part_10"]
+ model.testNbResults(Part_10, 1)
+ model.testNbSubResults(Part_10, [0])
+ model.testNbSubShapes(Part_10, GeomAPI_Shape.SOLID, [1])
+ model.testNbSubShapes(Part_10, GeomAPI_Shape.FACE, [10])
+ model.testNbSubShapes(Part_10, GeomAPI_Shape.EDGE, [48])
+ model.testNbSubShapes(Part_10, GeomAPI_Shape.VERTEX, [96])
+ model.testResultsVolumes(Part_10, [6604147.6151849])
# Test reexecution after parameter change
Parameter_H.setValue(14)
model.do()
-model.testResultsVolumes(ExtrusionCut_2, [10205.255531030932615976780653000])
+model.testResultsVolumes(ExtrusionCut_2, [10205.25717])
Parameter_H.setValue(12)
model.end()
model.testNbSubResults(ExtrusionCut_2, [0])
model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.SOLID, [1])
model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.FACE, [551])
-model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.EDGE, [3473])
-model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.VERTEX, [6946])
-model.testResultsVolumes(ExtrusionCut_2, [10362.335163710422420990653336048])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.EDGE, [3481])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.VERTEX, [6962])
+model.testResultsVolumes(ExtrusionCut_2, [10362.3368])
assert(model.checkPythonDump())
SketchConstraintCoincidence_44 = Sketch_3.setCoincident(SketchLine_42.endPoint(), SketchLine_37.startPoint())
SketchProjection_5 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OX"), False)
SketchLine_43 = SketchProjection_5.createdFeature()
-SketchProjection_6 = Sketch_3.addProjection(model.selection("EDGE", "([Revolution_1_1/Generated_Face&Sketch_1/SketchLine_34][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_33])([Revolution_1_1/Generated_Face&Sketch_1/SketchLine_33][Fillet_2_1/MF:Fillet&Sketch_1/SketchLine_32])_Fillet_2_1"), False)
+SketchProjection_6 = Sketch_3.addProjection(model.selection("EDGE", "([Revolution_1_1/Generated_Face&Sketch_1/SketchLine_34][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_33])([Revolution_1_1/Generated_Face&Sketch_1/SketchLine_33][Fillet_2_1/MF:Fillet&Sketch_1/SketchLine_32])_Fillet_5_1"), False)
SketchLine_44 = SketchProjection_6.createdFeature()
SketchProjection_9 = Sketch_3.addProjection(model.selection("EDGE", "Sketch_1/SketchLine_32"), False)
SketchLine_47 = SketchProjection_9.createdFeature()
--- /dev/null
+# Copyright (C) 2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from GeomAPI import *
+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, "size_x", "150")
+ParamSize = model.addParameter(Part_1_doc, "size_y", "180")
+model.addParameter(Part_1_doc, "size_z", "5")
+model.addParameter(Part_1_doc, "chamfer", "0.8")
+model.addParameter(Part_1_doc, "thickness", "4")
+
+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, -145, 0, 30, 50, 22.70509831248424, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_1.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchAPI_Line(SketchLine_1).startPoint(), "size_y-35", True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "size_y-5")
+SketchArc_2 = Sketch_1.addArc(47.42857142857143, 14.08026468498505, 50, 22.70509831248424, 56.4024789026646, 13.39544014803082, True)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_2.results()[1], 9)
+SketchArc_3 = Sketch_1.addArc(66.37348720721259, 12.63452399585945, 56.4024789026646, 13.39544014803082, 65.54400934016748, 2.668985050670266, False)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_3.results()[1], 10)
+SketchArc_4 = Sketch_1.addArc(64.79747925982687, -6.3, 65.54400934016748, 2.668985050670266, 73.72335126899428, -5.147260273972602, True)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchArc_4.startPoint())
+SketchConstraintTangent_3 = Sketch_1.setTangent(SketchArc_3.results()[1], SketchArc_4.results()[1])
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchArc_4.results()[1], 9)
+SketchArc_5 = Sketch_1.addArc(-80, -25, 73.72335126899428, -5.147260273972602, 28.47740289468357, -135.7142857142857, True)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_4.endPoint(), SketchArc_5.startPoint())
+SketchConstraintTangent_4 = Sketch_1.setTangent(SketchArc_4.results()[1], SketchArc_5.results()[1])
+SketchConstraintRadius_5 = Sketch_1.setRadius(SketchArc_5.results()[1], "size_x+5")
+SketchArc_6 = Sketch_1.addArc(32.67652816802617, -140, 28.47740289468357, -135.7142857142857, 36.96224245374191, -135.8008747266572, False)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchArc_5.endPoint(), SketchArc_6.startPoint())
+SketchConstraintTangent_5 = Sketch_1.setTangent(SketchArc_5.results()[1], SketchArc_6.results()[1])
+SketchConstraintRadius_6 = Sketch_1.setRadius(SketchArc_6.results()[1], 6)
+SketchArc_7 = Sketch_1.addArc(38.39081388227633, -134.4011663021575, 36.96224245374191, -135.8008747266572, 39.81938531083141, -133.0014578776889, True)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchArc_6.endPoint(), SketchArc_7.startPoint())
+SketchConstraintTangent_6 = Sketch_1.setTangent(SketchArc_6.results()[1], SketchArc_7.results()[1])
+SketchConstraintRadius_7 = Sketch_1.setRadius(SketchArc_7.results()[1], "thickness/2")
+SketchArc_8 = Sketch_1.addArc(32.67652816802617, -140, 39.81938531083141, -133.0014578776889, 25.67798604578851, -132.8571428571429, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchArc_7.endPoint(), SketchArc_8.startPoint())
+SketchConstraintTangent_7 = Sketch_1.setTangent(SketchArc_7.results()[1], SketchArc_8.results()[1])
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_8.center(), SketchArc_6.center())
+SketchArc_9 = Sketch_1.addArc(-80, -25, 25.67798604578851, -132.8571428571429, 69.75629704269767, -5.659589041095889, False)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchArc_8.endPoint(), SketchArc_9.startPoint())
+SketchConstraintTangent_8 = Sketch_1.setTangent(SketchArc_8.results()[1], SketchArc_9.results()[1])
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_9.center(), SketchArc_5.center())
+SketchArc_10 = Sketch_1.addArc(64.79747925982687, -6.3, 69.75629704269767, -5.659589041095889, 65.21221819334943, -1.317230527405396, False)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_9.endPoint(), SketchArc_10.startPoint())
+SketchConstraintTangent_9 = Sketch_1.setTangent(SketchArc_9.results()[1], SketchArc_10.results()[1])
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_4.center(), SketchArc_10.center())
+SketchArc_11 = Sketch_1.addArc(66.37348720721259, 12.63452399585945, 65.21221819334943, -1.317230527405396, 52.41407558084543, 13.69980660889937, True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchArc_10.endPoint(), SketchArc_11.startPoint())
+SketchConstraintTangent_10 = Sketch_1.setTangent(SketchArc_10.results()[1], SketchArc_11.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchArc_11.center(), SketchArc_3.center())
+SketchArc_12 = Sketch_1.addArc(47.42857142857143, 14.08026468498505, 52.41407558084543, 13.69980660889937, 52.31556879671711, 15.13726833859206, False)
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchArc_11.endPoint(), SketchArc_12.startPoint())
+SketchConstraintTangent_11 = Sketch_1.setTangent(SketchArc_11.results()[1], SketchArc_12.results()[1])
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchArc_12.center(), SketchArc_2.center())
+SketchArc_13 = Sketch_1.addArc(51.92460900726545, 15.0527080463035, 52.31556879671711, 15.13726833859206, 51.52598744945789, 15.0858871609853, False)
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchArc_12.endPoint(), SketchArc_13.startPoint())
+SketchConstraintTangent_12 = Sketch_1.setTangent(SketchArc_12.results()[1], SketchArc_13.results()[1])
+SketchConstraintRadius_8 = Sketch_1.setRadius(SketchArc_13.results()[1], 0.4)
+SketchLine_2 = Sketch_1.addLine(51.52598744945789, 15.0858871609853, 50.80630122186367, 6.439410365943716)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchArc_13.endPoint(), SketchLine_2.startPoint())
+SketchConstraintTangent_13 = Sketch_1.setTangent(SketchLine_2.result(), SketchArc_13.results()[1])
+SketchArc_14 = Sketch_1.addArc(47.81663953830692, 6.68825372605725, 50.80630122186367, 6.439410365943716, 47.56779617819338, 3.698592042500495, True)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_14.startPoint())
+SketchConstraintTangent_14 = Sketch_1.setTangent(SketchLine_2.result(), SketchArc_14.results()[1])
+SketchConstraintRadius_9 = Sketch_1.setRadius(SketchArc_14.results()[1], 3)
+SketchArc_15 = Sketch_1.addArc(47.73369175160241, 5.691699831538332, 47.56779617819338, 3.698592042500495, 46.66684983267853, 4, True)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchArc_14.endPoint(), SketchArc_15.startPoint())
+SketchConstraintTangent_15 = Sketch_1.setTangent(SketchArc_14.results()[1], SketchArc_15.results()[1])
+SketchConstraintRadius_10 = Sketch_1.setRadius(SketchArc_15.results()[1], 2)
+SketchArc_16 = Sketch_1.addArc(0, -70, 46.66684983267853, 4, 0, 17.48596957973185, False)
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchArc_15.endPoint(), SketchArc_16.startPoint())
+SketchConstraintTangent_16 = Sketch_1.setTangent(SketchArc_15.results()[1], SketchArc_16.results()[1])
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchArc_16.endPoint(), SketchLine_1.result())
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchArc_16.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchArc_16.center(), SketchAPI_Line(SketchLine_1).startPoint(), "size_y/2-20", True)
+SketchLine_3 = Sketch_1.addLine(64.79747925982687, -6.3, 66.37348720721259, 12.63452399585945)
+SketchLine_3.setAuxiliary(True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchArc_4.center(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_3.endPoint())
+SketchLine_4 = Sketch_1.addLine(47.73369175160241, 5.691699831538332, 47.81663953830692, 6.68825372605725)
+SketchLine_4.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchArc_15.center(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchArc_14.center(), SketchLine_4.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_2.result(), SketchLine_3.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_2.result(), SketchLine_4.result())
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_5.center(), SketchAPI_Line(SketchLine_1).startPoint(), "size_x/2+5")
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_5.center(), SketchAPI_Line(SketchLine_1).startPoint(), 25)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchArc_11.endPoint(), SketchLine_2.result(), 1, True)
+SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchArc_8.center(), SketchAPI_Line(SketchLine_1).startPoint(), "size_y-40")
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchArc_1.endPoint(), SketchLine_1.result(), 50, True)
+SketchLine_5 = Sketch_1.addLine(28.47740289468357, -135.7142857142857, 32.67652816802617, -140)
+SketchLine_5.setAuxiliary(True)
+SketchConstraintCoincidence_30 = Sketch_1.setCoincident(SketchArc_5.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_31 = Sketch_1.setCoincident(SketchArc_6.center(), SketchLine_5.endPoint())
+SketchLine_6 = Sketch_1.addLine(32.67652816802617, -140, 36.96224245374191, -135.8008747266572)
+SketchLine_6.setAuxiliary(True)
+SketchConstraintCoincidence_32 = Sketch_1.setCoincident(SketchArc_6.center(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_33 = Sketch_1.setCoincident(SketchArc_6.endPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_5.result(), SketchLine_6.result())
+SketchConstraintDistanceVertical_3 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchArc_16.startPoint(), 4)
+SketchConstraintDistanceVertical_4 = Sketch_1.setVerticalDistance(SketchArc_4.center(), SketchAPI_Line(SketchLine_1).startPoint(), 6.3)
+SketchConstraintMirror_1_objects = [SketchArc_1.results()[1], SketchArc_2.results()[1], SketchArc_3.results()[1], SketchArc_4.results()[1], SketchArc_5.results()[1], SketchArc_6.results()[1], SketchArc_7.results()[1], SketchArc_8.results()[1], SketchArc_9.results()[1], SketchArc_10.results()[1], SketchArc_11.results()[1], SketchArc_12.results()[1], SketchArc_13.results()[1], SketchLine_2.result(), SketchArc_14.results()[1], SketchArc_15.results()[1], SketchArc_16.results()[1]]
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_1.result(), SketchConstraintMirror_1_objects)
+[SketchArc_17, SketchArc_18, SketchArc_19, SketchArc_20, SketchArc_21, SketchArc_22, SketchArc_23, SketchArc_24, SketchArc_25, SketchArc_26, SketchArc_27, SketchArc_28, SketchArc_29, SketchLine_7, SketchArc_30, SketchArc_31, SketchArc_32] = SketchConstraintMirror_1.mirrored()
+SketchLine_8 = Sketch_1.addLine(0, -145, 31.89121696112821, 27.06960882369163)
+SketchLine_8.setName("SketchLine_43")
+SketchLine_8.result().setName("SketchLine_43")
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_34 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_35 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchArc_1.results()[1])
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_8.result(), SketchLine_1.result(), 10.5, type = "Direct")
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), "size_z", 0)
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [36])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [204])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [408])
+model.testResultsVolumes(Extrusion_1, [16403.0029])
+
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_9 = SketchProjection_2.createdFeature()
+SketchLine_9.setName("SketchLine_8")
+SketchLine_9.result().setName("SketchLine_8")
+SketchArc_33 = Sketch_2.addArc(0, -145, 0, 26, 48.1858267258401, 19.0704912613701, True)
+SketchConstraintCoincidence_36 = Sketch_2.setCoincident(SketchLine_9.result(), SketchArc_33.startPoint())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchArc_1_2__cc"), False)
+SketchPoint_1 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_37 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchArc_33.center())
+SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchArc_17_2_StartVertex"), False)
+SketchPoint_2 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_33.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 4, True)
+SketchLine_10 = Sketch_2.addLine(48.1858267258401, 19.0704912613701, 49.7056919497355, 16.28668032699112)
+SketchLine_10.setName("SketchLine_9")
+SketchLine_10.result().setName("SketchLine_9")
+SketchConstraintCoincidence_38 = Sketch_2.setCoincident(SketchArc_33.endPoint(), SketchLine_10.startPoint())
+SketchArc_34 = Sketch_2.addArc(48.03804881864168, 15.3762044144511, 49.7056919497355, 16.28668032699112, 49.93150121822762, 15.21860361971252, True)
+SketchConstraintCoincidence_39 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchArc_34.startPoint())
+SketchConstraintTangent_17 = Sketch_2.setTangent(SketchLine_10.result(), SketchArc_34.results()[1])
+SketchLine_11 = Sketch_2.addLine(49.93150121822762, 15.21860361971252, 49.21181499063341, 6.57212682467093)
+SketchLine_11.setName("SketchLine_10")
+SketchLine_11.result().setName("SketchLine_10")
+SketchConstraintCoincidence_40 = Sketch_2.setCoincident(SketchArc_34.endPoint(), SketchLine_11.startPoint())
+SketchConstraintTangent_18 = Sketch_2.setTangent(SketchLine_11.result(), SketchArc_34.results()[1])
+SketchProjection_5 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/SketchLine_2"), False)
+SketchLine_12 = SketchProjection_5.createdFeature()
+SketchLine_12.setName("SketchLine_11")
+SketchLine_12.result().setName("SketchLine_11")
+SketchConstraintParallel_3 = Sketch_2.setParallel(SketchLine_12.result(), SketchLine_11.result())
+SketchConstraintDistance_6 = Sketch_2.setDistance(SketchLine_11.startPoint(), SketchLine_12.result(), 1.6, True)
+SketchArc_35 = Sketch_2.addArc(47.81663953830692, 6.68825372605725, 49.21181499063341, 6.57212682467093, 47.07590600961045, 5.500266419952984, True)
+SketchConstraintCoincidence_41 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchArc_35.startPoint())
+SketchConstraintTangent_19 = Sketch_2.setTangent(SketchLine_11.result(), SketchArc_35.results()[1])
+SketchProjection_6 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchArc_14_2__cc"), False)
+SketchPoint_3 = SketchProjection_6.createdFeature()
+SketchConstraintCoincidence_42 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchArc_35.center())
+SketchArc_36 = Sketch_2.addArc(0, -70, 47.07590600961045, 5.500266419952984, 0, 18.97432863534041, False)
+SketchConstraintCoincidence_43 = Sketch_2.setCoincident(SketchArc_35.endPoint(), SketchArc_36.startPoint())
+SketchConstraintTangent_20 = Sketch_2.setTangent(SketchArc_35.results()[1], SketchArc_36.results()[1])
+SketchConstraintCoincidence_44 = Sketch_2.setCoincident(SketchArc_36.endPoint(), SketchLine_9.result())
+SketchProjection_7 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchArc_32_2__cc"), False)
+SketchPoint_4 = SketchProjection_7.createdFeature()
+SketchConstraintCoincidence_45 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_4).coordinates(), SketchArc_36.center())
+SketchLine_13 = Sketch_2.addLine(51.52598744945789, 15.0858871609853, 49.93150121822762, 15.21860361971252)
+SketchLine_13.setName("SketchLine_12")
+SketchLine_13.result().setName("SketchLine_12")
+SketchLine_13.setAuxiliary(True)
+SketchConstraintCoincidence_46 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_12).startPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_47 = Sketch_2.setCoincident(SketchArc_34.endPoint(), SketchLine_13.endPoint())
+SketchConstraintPerpendicular_2 = Sketch_2.setPerpendicular(SketchLine_11.result(), SketchLine_13.result())
+SketchLine_14 = Sketch_2.addLine(0, 33.22217618290702, 48.1858267258401, 19.0704912613701)
+SketchLine_14.setName("SketchLine_13")
+SketchLine_14.result().setName("SketchLine_13")
+SketchLine_14.setAuxiliary(True)
+SketchConstraintCoincidence_48 = Sketch_2.setCoincident(SketchLine_14.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_49 = Sketch_2.setCoincident(SketchArc_33.endPoint(), SketchLine_14.endPoint())
+SketchConstraintTangent_21 = Sketch_2.setTangent(SketchArc_33.results()[1], SketchLine_14.result())
+SketchConstraintAngle_2 = Sketch_2.setAngle(SketchLine_14.result(), SketchLine_10.result(), 135, type = "Direct")
+SketchConstraintRadius_11 = Sketch_2.setRadius(SketchArc_34.results()[1], 1.9)
+SketchConstraintMirror_2_objects = [SketchArc_33.results()[1], SketchLine_10.result(), SketchArc_34.results()[1], SketchLine_11.result(), SketchArc_35.results()[1], SketchArc_36.results()[1]]
+SketchConstraintMirror_2 = Sketch_2.addMirror(SketchLine_9.result(), SketchConstraintMirror_2_objects)
+[SketchArc_37, SketchLine_15, SketchArc_38, SketchLine_16, SketchArc_39, SketchArc_40] = SketchConstraintMirror_2.mirrored()
+SketchLine_16.setName("SketchLine_15")
+SketchLine_16.result().setName("SketchLine_15")
+SketchLine_15.setName("SketchLine_14")
+SketchLine_15.result().setName("SketchLine_14")
+model.do()
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), model.selection("FACE", "Extrusion_1_1/To_Face"), 0, model.selection("FACE", "Extrusion_1_1/To_Face"), 4.4, [model.selection("SOLID", "Extrusion_1_1")])
+
+model.testNbResults(ExtrusionCut_1, 1)
+model.testNbSubResults(ExtrusionCut_1, [0])
+model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.FACE, [49])
+model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.EDGE, [276])
+model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.VERTEX, [552])
+model.testResultsVolumes(ExtrusionCut_1, [12313.7939])
+
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/From_Face")], True, "chamfer", "chamfer", keepSubResults = True)
+
+model.testNbResults(Chamfer_1, 1)
+model.testNbSubResults(Chamfer_1, [0])
+model.testNbSubShapes(Chamfer_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_1, GeomAPI_Shape.FACE, [83])
+model.testNbSubShapes(Chamfer_1, GeomAPI_Shape.EDGE, [412])
+model.testNbSubShapes(Chamfer_1, GeomAPI_Shape.VERTEX, [824])
+model.testResultsVolumes(Chamfer_1, [11962.2801])
+
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), "chamfer", True)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_8 = Sketch_3.addProjection(model.selection("EDGE", "Sketch_1/SketchArc_12_2"), False)
+SketchArc_41 = SketchProjection_8.createdFeature()
+SketchArc_42 = Sketch_3.addArc(47.42857142857143, 14.08026468498505, 53.87940795452356, 15.47550950774626, 42.38734178332437, 18.34007731747046, False)
+SketchConstraintCoincidence_50 = Sketch_3.setCoincident(SketchAPI_Arc(SketchArc_41).center(), SketchArc_42.center())
+SketchConstraintCoincidence_50.setName("SketchConstraintCoincidence_48")
+SketchLine_17 = Sketch_3.addLine(47.42857142857143, 14.08026468498505, 52.31556879671699, 15.13726833859203)
+SketchLine_17.setName("SketchLine_16")
+SketchLine_17.result().setName("SketchLine_16")
+SketchLine_17.setAuxiliary(True)
+SketchConstraintCoincidence_51 = Sketch_3.setCoincident(SketchAPI_Arc(SketchArc_41).center(), SketchLine_17.startPoint())
+SketchConstraintCoincidence_52 = Sketch_3.setCoincident(SketchAPI_Arc(SketchArc_41).endPoint(), SketchLine_17.endPoint())
+SketchConstraintCoincidence_53 = Sketch_3.setCoincident(SketchArc_42.startPoint(), SketchLine_17.result())
+SketchConstraintDistance_7 = Sketch_3.setDistance(SketchLine_17.endPoint(), SketchArc_42.startPoint(), "2*chamfer", True)
+SketchProjection_9 = Sketch_3.addProjection(model.selection("EDGE", "Sketch_2/SketchArc_34_2"), False)
+SketchArc_43 = SketchProjection_9.createdFeature()
+SketchArc_44 = Sketch_3.addArc(45.66073233717504, 15.57407945314024, 49.93150121822762, 15.21860361971246, 42.38734178332437, 18.34007731747046, False)
+SketchProjection_10 = Sketch_3.addProjection(model.selection("EDGE", "Sketch_2/SketchLine_12"), False)
+SketchLine_18 = SketchProjection_10.createdFeature()
+SketchLine_18.setName("SketchLine_17")
+SketchLine_18.result().setName("SketchLine_17")
+SketchConstraintCoincidence_54 = Sketch_3.setCoincident(SketchArc_44.startPoint(), SketchLine_18.result())
+SketchConstraintDistance_8 = Sketch_3.setDistance(SketchArc_44.startPoint(), SketchAPI_Line(SketchLine_18).startPoint(), "2*chamfer", True)
+SketchLine_19 = Sketch_3.addLine(47.42857142857143, 14.08026468498505, 42.38734178332437, 18.34007731747046)
+SketchLine_19.setName("SketchLine_18")
+SketchLine_19.result().setName("SketchLine_18")
+SketchLine_19.setAuxiliary(True)
+SketchConstraintCoincidence_55 = Sketch_3.setCoincident(SketchAPI_Arc(SketchArc_41).center(), SketchLine_19.startPoint())
+SketchConstraintCoincidence_56 = Sketch_3.setCoincident(SketchArc_42.endPoint(), SketchLine_19.endPoint())
+SketchConstraintPerpendicular_3 = Sketch_3.setPerpendicular(SketchArc_44.results()[1], SketchLine_18.result())
+SketchConstraintCoincidence_57 = Sketch_3.setCoincident(SketchArc_44.endPoint(), SketchLine_19.endPoint())
+SketchLine_20 = Sketch_3.addLine(49.93150121822762, 15.21860361971252, 53.87940795452356, 15.47550950774626)
+SketchLine_20.setName("SketchLine_22")
+SketchLine_20.result().setName("SketchLine_22")
+SketchConstraintCoincidence_58 = Sketch_3.setCoincident(SketchAPI_Arc(SketchArc_43).startPoint(), SketchLine_20.startPoint())
+SketchConstraintCoincidence_59 = Sketch_3.setCoincident(SketchArc_42.startPoint(), SketchLine_20.endPoint())
+SketchConstraintCoincidence_60 = Sketch_3.setCoincident(SketchArc_44.center(), SketchLine_19.result())
+model.do()
+
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), "2*chamfer", False)
+Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2"))
+SketchProjection_11 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_3/SketchArc_42_2"), False)
+SketchArc_45 = SketchProjection_11.createdFeature()
+SketchArc_46 = Sketch_4.addArc(47.42857142857143, 14.08026468498505, 51.5336492178137, 14.96814775401492, 44.22051619977783, 16.79105454202122, False)
+SketchConstraintCoincidence_61 = Sketch_4.setCoincident(SketchAPI_Arc(SketchArc_45).center(), SketchArc_46.center())
+SketchProjection_12 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_3/SketchLine_16"), False)
+SketchLine_21 = SketchProjection_12.createdFeature()
+SketchLine_21.setName("SketchLine_19")
+SketchLine_21.result().setName("SketchLine_19")
+SketchProjection_13 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_3/SketchLine_18"), False)
+SketchLine_22 = SketchProjection_13.createdFeature()
+SketchLine_22.setName("SketchLine_20")
+SketchLine_22.result().setName("SketchLine_20")
+SketchConstraintCoincidence_62 = Sketch_4.setCoincident(SketchArc_46.startPoint(), SketchLine_21.result())
+SketchConstraintCoincidence_63 = Sketch_4.setCoincident(SketchArc_46.endPoint(), SketchLine_22.result())
+SketchConstraintDistance_9 = Sketch_4.setDistance(SketchArc_46.startPoint(), SketchAPI_Arc(SketchArc_45).startPoint(), "3*chamfer", True)
+SketchProjection_14 = Sketch_4.addProjection(model.selection("EDGE", "Sketch_3/SketchArc_44_2"), False)
+SketchArc_47 = SketchProjection_14.createdFeature()
+SketchArc_48 = Sketch_4.addArc(45.66073233717504, 15.57407945314024, 52.32323056507302, 15.01952893162158, 40.55416736687089, 19.8891000929197, False)
+SketchConstraintCoincidence_64 = Sketch_4.setCoincident(SketchAPI_Arc(SketchArc_47).center(), SketchArc_48.center())
+SketchLine_23 = Sketch_4.addLine(45.66073233717504, 15.57407945314024, 49.93150121822762, 15.21860361971246)
+SketchLine_23.setName("SketchLine_21")
+SketchLine_23.result().setName("SketchLine_21")
+SketchLine_23.setAuxiliary(True)
+SketchConstraintCoincidence_65 = Sketch_4.setCoincident(SketchAPI_Arc(SketchArc_47).center(), SketchLine_23.startPoint())
+SketchConstraintCoincidence_66 = Sketch_4.setCoincident(SketchAPI_Arc(SketchArc_47).startPoint(), SketchLine_23.endPoint())
+SketchConstraintCoincidence_67 = Sketch_4.setCoincident(SketchArc_48.startPoint(), SketchLine_23.result())
+SketchConstraintCoincidence_68 = Sketch_4.setCoincident(SketchArc_48.endPoint(), SketchLine_22.result())
+SketchConstraintDistance_10 = Sketch_4.setDistance(SketchLine_23.endPoint(), SketchArc_48.startPoint(), "3*chamfer", True)
+model.do()
+
+Filling_1 = model.addFilling(Part_1_doc, [model.selection("EDGE", "Sketch_3/SketchArc_42_2"), model.selection("EDGE", "Sketch_4/SketchArc_46_2")])
+Filling_2 = model.addFilling(Part_1_doc, [model.selection("EDGE", "Sketch_3/SketchArc_44_2"), model.selection("EDGE", "Sketch_4/SketchArc_48_2")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_42_2f-SketchArc_44_2r-SketchLine_22f")])
+
+Plane_6 = model.addPlane(Part_1_doc, model.selection("EDGE", "Sketch_3/SketchLine_22"), model.selection("VERTEX", "[Filling_2_1/Edge_0_1]e[Filling_2_1/Edge_0_4]e"), False)
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_3"))
+SketchProjection_15 = Sketch_5.addProjection(model.selection("EDGE", "Sketch_3/SketchLine_22"), True)
+SketchLine_24 = SketchProjection_15.createdFeature()
+SketchLine_24.setName("SketchLine_23")
+SketchLine_24.result().setName("SketchLine_23")
+SketchProjection_16 = Sketch_5.addProjection(model.selection("EDGE", "Filling_1_1/Edge_0_1"), False)
+SketchBSpline_1 = SketchProjection_16.createdFeature()
+SketchProjection_17 = Sketch_5.addProjection(model.selection("EDGE", "Filling_2_1/Edge_0_1"), False)
+SketchBSpline_2 = SketchProjection_17.createdFeature()
+SketchLine_25 = Sketch_5.addLine(54.7440877920758, -3.054064947639794, 52.78524259618538, -1.013740096412265)
+SketchLine_25.setName("SketchLine_24")
+SketchLine_25.result().setName("SketchLine_24")
+SketchConstraintCoincidence_69 = Sketch_5.setCoincident(SketchAPI_Line(SketchLine_24).endPoint(), SketchLine_25.startPoint())
+SketchLine_26 = Sketch_5.addLine(52.78524259618538, -1.013740096412265, 50.78800926284204, -3.016502941130004)
+SketchLine_26.setName("SketchLine_25")
+SketchLine_26.result().setName("SketchLine_25")
+SketchConstraintCoincidence_70 = Sketch_5.setCoincident(SketchLine_25.endPoint(), SketchLine_26.startPoint())
+SketchConstraintCoincidence_71 = Sketch_5.setCoincident(SketchAPI_Line(SketchLine_24).startPoint(), SketchLine_26.endPoint())
+SketchConstraintCoincidence_72 = Sketch_5.setCoincident(SketchLine_26.startPoint(), SketchBSpline_1.result())
+SketchConstraintCoincidence_73 = Sketch_5.setCoincident(SketchLine_26.startPoint(), SketchBSpline_2.result())
+model.do()
+Face_2 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_5/Face-SketchProjection_15r-SketchLine_24f-SketchLine_25f")])
+
+Solid_1_objects = [model.selection("FACE", "Filling_1_1"), model.selection("FACE", "Filling_2_1"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1")]
+Solid_1 = model.addSolid(Part_1_doc, Solid_1_objects)
+
+model.testNbResults(Solid_1, 1)
+model.testNbSubResults(Solid_1, [0])
+model.testNbSubShapes(Solid_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Solid_1, GeomAPI_Shape.FACE, [4])
+model.testNbSubShapes(Solid_1, GeomAPI_Shape.EDGE, [12])
+model.testNbSubShapes(Solid_1, GeomAPI_Shape.VERTEX, [24])
+model.testResultsVolumes(Solid_1, [13.6834876])
+
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Solid_1_1/Modified_Face&Filling_1_1/Filling_1_1][Solid_1_1/Modified_Face&Filling_2_1/Filling_2_1]")], 0.4, keepSubResults = True)
+
+model.testNbResults(Fillet_1, 1)
+model.testNbSubResults(Fillet_1, [0])
+model.testNbSubShapes(Fillet_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_1, GeomAPI_Shape.FACE, [5])
+model.testNbSubShapes(Fillet_1, GeomAPI_Shape.EDGE, [18])
+model.testNbSubShapes(Fillet_1, GeomAPI_Shape.VERTEX, [36])
+model.testResultsVolumes(Fillet_1, [13.34526088678])
+
+Symmetry_1 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Fillet_1_1")], model.selection("FACE", "PartSet/YOZ"), keepOriginal = True, keepSubResults = True)
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Chamfer_1_1")], [model.selection("COMPOUND", "Symmetry_1_1")], keepSubResults = True)
+
+model.testNbResults(Cut_1, 1)
+model.testNbSubResults(Cut_1, [0])
+model.testNbSubShapes(Cut_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Cut_1, GeomAPI_Shape.FACE, [87])
+model.testNbSubShapes(Cut_1, GeomAPI_Shape.EDGE, [436])
+model.testNbSubShapes(Cut_1, GeomAPI_Shape.VERTEX, [872])
+model.testResultsVolumes(Cut_1, [11957.973])
+
+Sketch_6 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchLine_27 = Sketch_6.addLine(-32, 0, -29, 0)
+SketchLine_27.setName("SketchLine_26")
+SketchLine_27.result().setName("SketchLine_26")
+SketchLine_28 = Sketch_6.addLine(-29, 0, -28, 1)
+SketchLine_28.setName("SketchLine_27")
+SketchLine_28.result().setName("SketchLine_27")
+SketchConstraintCoincidence_74 = Sketch_6.setCoincident(SketchLine_27.endPoint(), SketchLine_28.startPoint())
+SketchLine_29 = Sketch_6.addLine(-28, 1, -28, 4)
+SketchLine_29.setName("SketchLine_28")
+SketchLine_29.result().setName("SketchLine_28")
+SketchConstraintCoincidence_75 = Sketch_6.setCoincident(SketchLine_28.endPoint(), SketchLine_29.startPoint())
+SketchConstraintVertical_1 = Sketch_6.setVertical(SketchLine_29.result())
+SketchLine_30 = Sketch_6.addLine(-28, 4, -29, 5)
+SketchLine_30.setName("SketchLine_29")
+SketchLine_30.result().setName("SketchLine_29")
+SketchConstraintCoincidence_76 = Sketch_6.setCoincident(SketchLine_29.endPoint(), SketchLine_30.startPoint())
+SketchLine_31 = Sketch_6.addLine(-29, 5, -32, 5)
+SketchLine_31.setName("SketchLine_30")
+SketchLine_31.result().setName("SketchLine_30")
+SketchConstraintCoincidence_77 = Sketch_6.setCoincident(SketchLine_30.endPoint(), SketchLine_31.startPoint())
+SketchConstraintHorizontal_1 = Sketch_6.setHorizontal(SketchLine_31.result())
+SketchLine_32 = Sketch_6.addLine(-32, 5, -33, 4)
+SketchLine_32.setName("SketchLine_31")
+SketchLine_32.result().setName("SketchLine_31")
+SketchConstraintCoincidence_78 = Sketch_6.setCoincident(SketchLine_31.endPoint(), SketchLine_32.startPoint())
+SketchLine_33 = Sketch_6.addLine(-33, 4, -33, 1)
+SketchLine_33.setName("SketchLine_32")
+SketchLine_33.result().setName("SketchLine_32")
+SketchConstraintCoincidence_79 = Sketch_6.setCoincident(SketchLine_32.endPoint(), SketchLine_33.startPoint())
+SketchConstraintVertical_2 = Sketch_6.setVertical(SketchLine_33.result())
+SketchLine_34 = Sketch_6.addLine(-33, 1, -32, 0)
+SketchLine_34.setName("SketchLine_33")
+SketchLine_34.result().setName("SketchLine_33")
+SketchConstraintCoincidence_80 = Sketch_6.setCoincident(SketchLine_33.endPoint(), SketchLine_34.startPoint())
+SketchConstraintCoincidence_81 = Sketch_6.setCoincident(SketchLine_27.startPoint(), SketchLine_34.endPoint())
+SketchProjection_18 = Sketch_6.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_35 = SketchProjection_18.createdFeature()
+SketchLine_35.setName("SketchLine_34")
+SketchLine_35.result().setName("SketchLine_34")
+SketchConstraintCollinear_1 = Sketch_6.setCollinear(SketchLine_35.result(), SketchLine_27.result())
+SketchConstraintLength_1 = Sketch_6.setLength(SketchLine_27.result(), "size_z-2")
+SketchConstraintEqual_1 = Sketch_6.setEqual(SketchLine_27.result(), SketchLine_29.result())
+SketchConstraintEqual_2 = Sketch_6.setEqual(SketchLine_29.result(), SketchLine_31.result())
+SketchConstraintEqual_3 = Sketch_6.setEqual(SketchLine_31.result(), SketchLine_33.result())
+SketchConstraintEqual_4 = Sketch_6.setEqual(SketchLine_28.result(), SketchLine_30.result())
+SketchConstraintEqual_5 = Sketch_6.setEqual(SketchLine_30.result(), SketchLine_32.result())
+SketchConstraintEqual_6 = Sketch_6.setEqual(SketchLine_32.result(), SketchLine_34.result())
+SketchConstraintDistanceHorizontal_2 = Sketch_6.setHorizontalDistance(SketchLine_27.endPoint(), SketchLine_28.endPoint(), 1)
+SketchConstraintDistanceHorizontal_3 = Sketch_6.setHorizontalDistance(SketchLine_31.startPoint(), SketchLine_29.endPoint(), 1)
+SketchConstraintDistanceVertical_5 = Sketch_6.setVerticalDistance(SketchLine_27.endPoint(), SketchLine_28.endPoint(), 1)
+SketchConstraintDistance_11 = Sketch_6.setDistance(SketchAPI_Line(SketchLine_35).startPoint(), SketchLine_29.result(), 28, True)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), 79, -76.5)
+
+Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_6/Face-SketchLine_26r-SketchLine_27f-SketchLine_28f-SketchLine_29f-SketchLine_30f-SketchLine_31f-SketchLine_32f-SketchLine_33f"))
+SketchProjection_19 = Sketch_7.addProjection(model.selection("EDGE", "Sketch_6/SketchLine_27"), True)
+SketchLine_36 = SketchProjection_19.createdFeature()
+SketchLine_36.setName("SketchLine_35")
+SketchLine_36.result().setName("SketchLine_35")
+SketchProjection_20 = Sketch_7.addProjection(model.selection("EDGE", "Sketch_6/SketchLine_28"), True)
+SketchLine_37 = SketchProjection_20.createdFeature()
+SketchLine_37.setName("SketchLine_36")
+SketchLine_37.result().setName("SketchLine_36")
+SketchProjection_21 = Sketch_7.addProjection(model.selection("EDGE", "Sketch_6/SketchLine_29"), True)
+SketchLine_38 = SketchProjection_21.createdFeature()
+SketchLine_38.setName("SketchLine_37")
+SketchLine_38.result().setName("SketchLine_37")
+SketchLine_39 = Sketch_7.addLine(-29, 5, -31, 5)
+SketchLine_39.setName("SketchLine_38")
+SketchLine_39.result().setName("SketchLine_38")
+SketchConstraintCoincidence_82 = Sketch_7.setCoincident(SketchAPI_Line(SketchLine_38).endPoint(), SketchLine_39.startPoint())
+SketchLine_40 = Sketch_7.addLine(-31, 5, -32, 4)
+SketchLine_40.setName("SketchLine_39")
+SketchLine_40.result().setName("SketchLine_39")
+SketchConstraintCoincidence_83 = Sketch_7.setCoincident(SketchLine_39.endPoint(), SketchLine_40.startPoint())
+SketchLine_41 = Sketch_7.addLine(-32, 4, -32, 1)
+SketchLine_41.setName("SketchLine_40")
+SketchLine_41.result().setName("SketchLine_40")
+SketchConstraintCoincidence_84 = Sketch_7.setCoincident(SketchLine_40.endPoint(), SketchLine_41.startPoint())
+SketchConstraintVertical_3 = Sketch_7.setVertical(SketchLine_41.result())
+SketchLine_42 = Sketch_7.addLine(-32, 1, -31, 0)
+SketchLine_42.setName("SketchLine_41")
+SketchLine_42.result().setName("SketchLine_41")
+SketchConstraintCoincidence_85 = Sketch_7.setCoincident(SketchLine_41.endPoint(), SketchLine_42.startPoint())
+SketchLine_43 = Sketch_7.addLine(-31, 0, -29, 0)
+SketchLine_43.setName("SketchLine_42")
+SketchLine_43.result().setName("SketchLine_42")
+SketchConstraintCoincidence_86 = Sketch_7.setCoincident(SketchLine_42.endPoint(), SketchLine_43.startPoint())
+SketchConstraintCoincidence_87 = Sketch_7.setCoincident(SketchAPI_Line(SketchLine_36).startPoint(), SketchLine_43.endPoint())
+SketchConstraintHorizontal_2 = Sketch_7.setHorizontal(SketchLine_43.result())
+SketchConstraintHorizontal_3 = Sketch_7.setHorizontal(SketchLine_39.result())
+SketchConstraintEqual_7 = Sketch_7.setEqual(SketchLine_40.result(), SketchLine_42.result())
+SketchConstraintEqual_8 = Sketch_7.setEqual(SketchLine_42.result(), SketchLine_36.result())
+SketchConstraintEqual_9 = Sketch_7.setEqual(SketchLine_37.result(), SketchLine_41.result())
+SketchConstraintEqual_10 = Sketch_7.setEqual(SketchLine_39.result(), SketchLine_43.result())
+SketchConstraintLength_2 = Sketch_7.setLength(SketchLine_39.result(), 2)
+model.do()
+ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), model.selection("FACE", "Extrusion_2_1/From_Face"), 0, model.selection("FACE", "Extrusion_2_1/From_Face"), "1.6+2*chamfer", [model.selection("SOLID", "Extrusion_2_1")])
+
+model.testNbResults(ExtrusionFuse_1, 1)
+model.testNbSubResults(ExtrusionFuse_1, [0])
+model.testNbSubShapes(ExtrusionFuse_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ExtrusionFuse_1, GeomAPI_Shape.FACE, [19])
+model.testNbSubShapes(ExtrusionFuse_1, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(ExtrusionFuse_1, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(ExtrusionFuse_1, [115.1])
+
+Plane_7 = model.addPlane(Part_1_doc, model.selection("EDGE", "Sketch_1/SketchLine_43"), model.selection("VERTEX", "Sketch_1/SketchArc_1"), True)
+Sketch_8 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_4"))
+SketchLine_44 = Sketch_8.addLine(30.42415119636338, 0, 27.42415119636338, 0)
+SketchConstraintHorizontal_4 = Sketch_8.setHorizontal(SketchLine_44.result())
+SketchLine_45 = Sketch_8.addLine(27.42415119636338, 0, 26.42415119636338, -1)
+SketchConstraintCoincidence_88 = Sketch_8.setCoincident(SketchLine_44.endPoint(), SketchLine_45.startPoint())
+SketchLine_46 = Sketch_8.addLine(26.42415119636338, -1, 26.42415119636338, -4)
+SketchConstraintCoincidence_89 = Sketch_8.setCoincident(SketchLine_45.endPoint(), SketchLine_46.startPoint())
+SketchConstraintVertical_4 = Sketch_8.setVertical(SketchLine_46.result())
+SketchLine_47 = Sketch_8.addLine(26.42415119636338, -4, 27.42415119636338, -5)
+SketchConstraintCoincidence_90 = Sketch_8.setCoincident(SketchLine_46.endPoint(), SketchLine_47.startPoint())
+SketchLine_48 = Sketch_8.addLine(27.42415119636338, -5, 30.42415119636338, -5)
+SketchConstraintCoincidence_91 = Sketch_8.setCoincident(SketchLine_47.endPoint(), SketchLine_48.startPoint())
+SketchConstraintHorizontal_5 = Sketch_8.setHorizontal(SketchLine_48.result())
+SketchLine_49 = Sketch_8.addLine(30.42415119636338, -5, 31.4241511964612, -4)
+SketchConstraintCoincidence_92 = Sketch_8.setCoincident(SketchLine_48.endPoint(), SketchLine_49.startPoint())
+SketchLine_50 = Sketch_8.addLine(31.4241511964612, -4, 31.4241511964612, -1)
+SketchConstraintCoincidence_93 = Sketch_8.setCoincident(SketchLine_49.endPoint(), SketchLine_50.startPoint())
+SketchConstraintVertical_5 = Sketch_8.setVertical(SketchLine_50.result())
+SketchLine_51 = Sketch_8.addLine(31.4241511964612, -1, 30.42415119636338, 0)
+SketchConstraintCoincidence_94 = Sketch_8.setCoincident(SketchLine_50.endPoint(), SketchLine_51.startPoint())
+SketchConstraintCoincidence_95 = Sketch_8.setCoincident(SketchLine_44.startPoint(), SketchLine_51.endPoint())
+SketchProjection_22 = Sketch_8.addProjection(model.selection("VERTEX", "Sketch_1/SketchArc_1"), False)
+SketchPoint_5 = SketchProjection_22.createdFeature()
+SketchConstraintLength_3 = Sketch_8.setLength(SketchLine_44.result(), "size_z-2")
+SketchConstraintEqual_11 = Sketch_8.setEqual(SketchLine_44.result(), SketchLine_46.result())
+SketchConstraintEqual_12 = Sketch_8.setEqual(SketchLine_46.result(), SketchLine_48.result())
+SketchConstraintEqual_13 = Sketch_8.setEqual(SketchLine_48.result(), SketchLine_50.result())
+SketchConstraintEqual_14 = Sketch_8.setEqual(SketchLine_45.result(), SketchLine_47.result())
+SketchConstraintEqual_15 = Sketch_8.setEqual(SketchLine_47.result(), SketchLine_49.result())
+SketchConstraintEqual_16 = Sketch_8.setEqual(SketchLine_49.result(), SketchLine_51.result())
+SketchConstraintDistanceHorizontal_4 = Sketch_8.setHorizontalDistance(SketchLine_45.startPoint(), SketchLine_45.endPoint(), 1)
+SketchConstraintDistanceHorizontal_5 = Sketch_8.setHorizontalDistance(SketchLine_47.endPoint(), SketchLine_46.endPoint(), 1)
+SketchConstraintDistanceVertical_6 = Sketch_8.setVerticalDistance(SketchLine_44.endPoint(), SketchLine_46.startPoint(), 1)
+SketchConstraintCoincidence_96 = Sketch_8.setCoincident(SketchAPI_Point(SketchPoint_5).coordinates(), SketchLine_44.result())
+SketchConstraintCoincidence_97 = Sketch_8.setCoincident(SketchAPI_Point(SketchPoint_5).coordinates(), SketchLine_46.result())
+model.do()
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_44r-SketchLine_45f-SketchLine_46f-SketchLine_47f-SketchLine_48f-SketchLine_49f-SketchLine_50f-SketchLine_51f")], model.selection(), "size_y-5+3.8", "-size_y+5+2*chamfer")
+
+model.testNbResults(Extrusion_3, 1)
+model.testNbSubResults(Extrusion_3, [0])
+model.testNbSubShapes(Extrusion_3, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_3, GeomAPI_Shape.FACE, [10])
+model.testNbSubShapes(Extrusion_3, GeomAPI_Shape.EDGE, [48])
+model.testNbSubShapes(Extrusion_3, GeomAPI_Shape.VERTEX, [96])
+model.testResultsVolumes(Extrusion_3, [124.2])
+
+Symmetry_2 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "ExtrusionFuse_1_1"), model.selection("SOLID", "Extrusion_3_1")], model.selection("FACE", "PartSet/YOZ"), keepOriginal = True, keepSubResults = True)
+Fuse_1_objects_1 = [model.selection("SOLID", "Cut_1_1"), model.selection("COMPOUND", "Symmetry_2_1"), model.selection("COMPOUND", "Symmetry_2_2")]
+Fuse_1 = model.addFuse(Part_1_doc, Fuse_1_objects_1, removeEdges = True, keepSubResults = True)
+Fuse_1.result().setName("Visor")
+
+model.testNbResults(Fuse_1, 1)
+model.testNbSubResults(Fuse_1, [0])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.FACE, [125])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [668])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [1336])
+model.testResultsVolumes(Fuse_1, [12309.7614])
+
+model.testHaveNamingSubshapes(Fuse_1, model, Part_1_doc)
+
+model.end()
+
+model.begin()
+ParamSize.setValue(160)
+model.end()
+
+model.testNbResults(Fuse_1, 1)
+model.testNbSubResults(Fuse_1, [0])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.FACE, [125])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [668])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [1336])
+model.testResultsVolumes(Fuse_1, [10224.4774])
+
+model.undo()
+
+model.testNbResults(Fuse_1, 1)
+model.testNbSubResults(Fuse_1, [0])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.FACE, [125])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [668])
+model.testNbSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [1336])
+model.testResultsVolumes(Fuse_1, [12309.7614])