#include <GeomAPI_Pln.h>
#include <GeomAPI_ShapeIterator.h>
#include <GeomAPI_Vertex.h>
+#include <GeomAPI_XYZ.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAlgoAPI_PointBuilder.h>
anEdge = aLineShape->edge();
}
else if (aLineShape->isCompound()) {
- GeomAPI_ShapeIterator anIt(aLineShape);
- anEdge = anIt.current()->edge();
+ // create an edge which covers all edges from compounds (they are on the same line)
+ GeomPointPtr aFirst, aLast;
+ GeomXYZPtr aLineVec;
+ for(GeomAPI_ShapeIterator anIt(aLineShape); anIt.more(); anIt.next()) {
+ GeomEdgePtr aSub = anIt.current()->edge();
+ if (aSub.get() && aSub->isLine()) {
+ if (!aLineVec.get()) {
+ aFirst = aSub->firstPoint();
+ aLast = aSub->lastPoint();
+ } else { // set aFirst and aLast by extreme points
+ GeomXYZPtr aFirstVec = aSub->firstPoint()->xyz()->decreased(aFirst->xyz());
+ bool aSameDirection =
+ aSub->lastPoint()->xyz()->decreased(aSub->firstPoint()->xyz())->dot(aLineVec) > 0;
+ if (aLineVec->dot(aFirstVec) < -1.e-7) { // first point is changed
+ aFirst = aSameDirection ? aSub->firstPoint() : aSub->lastPoint();
+ } else { // last point is changed
+ aLast = aSameDirection ? aSub->lastPoint() : aSub->firstPoint();
+ }
+ }
+ aLineVec = aLast->xyz()->decreased(aFirst->xyz());
+ }
+ }
+ if (aLineVec.get())
+ anEdge = GeomAlgoAPI_EdgeBuilder::line(aFirst, aLast);
}
ResultConstructionPtr aConstr = document()->createConstruction(data());
virtual std::shared_ptr<GeomAPI_Pnt> middlePoint() const;
};
-//! Pointer on attribute object
+//! Pointer on object
typedef std::shared_ptr<GeomAPI_Edge> GeomEdgePtr;
#endif
GEOMAPI_EXPORT double squareModulus() const;
};
+//! Pointer on object
+typedef std::shared_ptr<GeomAPI_XYZ> GeomXYZPtr;
+
#endif
ModelAPI_AttributeSelection::setID(theID);
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
if (myParent) {
- myIsGeometricalSelection = myParent->isGeometricalSelection();
+ myIsGeometricalSelection = true;//myParent->isGeometricalSelection();
} else {
myIsGeometricalSelection =
ModelAPI_Session::get()->validators()->isGeometricalSelection(aFeature->getKind(), id());
if (anOldShape.IsNull() || aNewShape.IsNull() || !anOldShape.IsEqual(aNewShape)) {
// shape type should not be changed: if shape becomes compound of such shapes, then split
- if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
+ if (!myIsGeometricalSelection && myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
anOldShape.ShapeType() != aNewShape.ShapeType() &&
(aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID))
{
TestGeomNamingRevolution.py
TestGeomNamingEdgeByFilter.py
TestGeomNamingSketchPlane.py
+ TestGeomNamingBoxWithFillet.py
TestContainerSelector.py
)
# on increase of parameter selected part of extrusion is increased and selected face is removed (U becomes L)
# so, check that selection is still correct and cut from not existing part produces correct shape anyway
lenParam.setValue(100)
-model.end()
+model.do()
# check the result validity
from ModelAPI import *
aFactory = ModelAPI_Session.get().validators()
assert(aFactory.validate(ExtrusionCut_2.feature()))
+# set the value back to avoid changed the name text in selection of "to_object" in check python dump
+lenParam.setValue(45)
+
+model.end()
+
assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# -*- coding: utf-8 -*-
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+param_p = model.addParameter(Part_1_doc, "p", "5")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 0, 0, 30.0000000000845)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchPoint_1.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(0, 30.0000000000845, 30.00000000002328, 30.00000000002326)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(30.00000000002328, 30.00000000002326, 29.99999999996195, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchProjection_3 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_5 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.result())
+SketchLine_6 = Sketch_1.addLine(29.99999999996195, 0, 0, 0)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_6.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_4.result(), 30)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_3.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_1.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_4r-SketchLine_3r-SketchLine_1r")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_4r-SketchLine_3r-SketchLine_1r"))
+SketchLine_7 = Sketch_2.addLine(20, 7, 10, 7)
+SketchLine_8 = Sketch_2.addLine(10, 7, 10, 0)
+SketchLine_9 = Sketch_2.addLine(10, 0, 20, 0)
+SketchLine_10 = Sketch_2.addLine(20, 0, 20, 7)
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_2 = Sketch_2.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_2 = Sketch_2.setVertical(SketchLine_10.result())
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/SketchLine_6"), False)
+SketchLine_11 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_11.result())
+SketchConstraintDistance_1 = Sketch_2.setDistance(SketchAPI_Line(SketchLine_11).endPoint(), SketchLine_8.endPoint(), 10, True)
+SketchConstraintLength_3 = Sketch_2.setLength(SketchLine_9.result(), 10)
+SketchConstraintLength_4 = Sketch_2.setLength(SketchLine_8.result(), 7)
+model.do()
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchLine_7r-SketchLine_8f-SketchLine_9f-SketchLine_10f_wire")], model.selection(), "p", 0, [model.selection("SOLID", "Extrusion_1_1")])
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]")], 3)
+model.do()
+# increase the extrusion-cut heigh to make face of a box divided into two
+param_p.setValue(30);
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Fillet_1.feature()))
+model.do()
+# set the value back and check again
+param_p.setValue(5);
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Fillet_1.feature()))
+model.end()
+
+assert(model.checkPythonDump())
isDumpByGeom = aSelectedFeature && aSelectedFeature->isInHistory();
}
- if (theAttrSelect->isGeometricalSelection() && aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+ if (theAttrSelect->isGeometricalSelection() && aShape->shapeType() == GeomAPI_Shape::COMPOUND
+ && theAttrSelect->context().get() && !aShape->isEqual(theAttrSelect->context()->shape())
+ && theAttrSelect->context()->groupName() != ModelAPI_ResultPart::group()) {
GeomAPI_ShapeIterator anIt(aShape);
aShape = anIt.current();
}
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <Geom_Surface.hxx>
#include <BRep_Tool.hxx>
#include <TNaming_Builder.hxx>
#include <TNaming_Tool.hxx>
#include <TNaming_SameShapeIterator.hxx>
#include <TNaming_Iterator.hxx>
+#include <TNaming_NewShapeIterator.hxx>
#include <TDataStd_ReferenceArray.hxx>
#include <TDataStd_ExtStringList.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_UAttribute.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRep_Builder.hxx>
/// type of the selection, integer keeps the Selector_Type value
}
Selector_Algo* Selector_Algo::restoreByName(TDF_Label theLab, TDF_Label theBaseDocLab,
- std::string theName, const TopAbs_ShapeEnum theShapeType,
+ std::string theName, const TopAbs_ShapeEnum theShapeType, const bool theGeomNaming,
Selector_NameGenerator* theNameGenerator, TDF_Label& theContextLab)
{
Selector_Algo* aResult = NULL;
if (aResult) {
aResult->myLab = theLab;
aResult->myBaseDocumentLab = theBaseDocLab;
+ aResult->myGeometricalNaming = theGeomNaming;
theContextLab = aResult->restoreByName(theName, theShapeType, theNameGenerator);
if (theContextLab.IsNull()) {
delete aResult;
if (myGeometricalNaming)
TDataStd_UAttribute::Set(myLab, kGEOMETRICAL_NAMING);
}
+
+/// Returns true if theSub is in theContext shape
+static bool isInContext(const TopoDS_Shape& theContext, const TopoDS_Shape& theSub) {
+ for(TopExp_Explorer anExp(theContext, theSub.ShapeType()); anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsSame(theSub))
+ return true;
+ }
+ return false;
+}
+
+bool Selector_Algo::findNewVersion(const TopoDS_Shape& theContext, TopoDS_Shape& theResult) const
+{
+ if (theResult.IsNull())
+ return false;
+ if (!TNaming_Tool::HasLabel(myLab, theResult)) {
+ if (theResult.ShapeType() == TopAbs_COMPOUND) { // do it for all elements of compound
+ BRep_Builder aBuilder;
+ TopoDS_Compound aResultingCompound;
+ aBuilder.MakeCompound(aResultingCompound);
+ bool aWasChanged = false;
+ for (TopoDS_Iterator anIter(theResult); anIter.More(); anIter.Next()) {
+ TopoDS_Shape aSub = anIter.Value();
+ if (findNewVersion(theContext, aSub))
+ aWasChanged = true;
+ aBuilder.Add(aResultingCompound, aSub);
+ }
+ if (aWasChanged)
+ theResult = aResultingCompound;
+ return aWasChanged;
+ }
+ } else {
+ // check theResult is in theContext
+ if (isInContext(theContext, theResult))
+ return false;
+ // searching the next modifications of the result shape in document
+ TopTools_MapOfShape aResultShapes;
+ for(TNaming_NewShapeIterator aBaseIter(theResult, myLab); aBaseIter.More(); aBaseIter.Next())
+ {
+ TNaming_Evolution anEvolution = aBaseIter.NamedShape()->Evolution();
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ TopoDS_Shape aNextModification = aBaseIter.Shape();
+ if (aNextModification.IsNull())
+ continue;
+ if (isInContext(theContext, aNextModification))
+ aResultShapes.Add(aNextModification);
+ else if (findNewVersion(theContext, aNextModification))
+ aResultShapes.Add(aNextModification);
+ }
+ }
+ if (aResultShapes.IsEmpty())
+ return false;
+ if (aResultShapes.Size() == 1) {
+ theResult = TopTools_MapIteratorOfMapOfShape(aResultShapes).Value();
+ } else { // make a compound of all results
+ BRep_Builder aBuilder;
+ TopoDS_Compound aResultingCompound;
+ aBuilder.MakeCompound(aResultingCompound);
+ for(TopTools_MapIteratorOfMapOfShape anIter(aResultShapes); anIter.More(); anIter.Next())
+ aBuilder.Add(aResultingCompound, anIter.Value());
+ theResult = aResultingCompound;
+ }
+ return true;
+ }
+ return false;
+}
/// Returns not empty label of the context.
SELECTOR_EXPORT static Selector_Algo* restoreByName(
TDF_Label theLab, TDF_Label theBaseDocLab, std::string theName,
- const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator,
- TDF_Label& theContextLab);
+ const TopAbs_ShapeEnum theShapeType, const bool theGeomNaming,
+ Selector_NameGenerator* theNameGenerator, TDF_Label& theContextLab);
/// Returns true if the given shapes are based on the same geometry
static bool sameGeometry(const TopoDS_Shape theShape1, const TopoDS_Shape theShape2);
}
/// Stores the type of an algorithm in the data tree (in myLab)
void storeType(const Selector_Type theType);
+
+ /// Searches the newer version of the shape in the document if the base shape does not
+ /// belong to context. Returns it in theResult (if any). Returns true is theResult is changed.
+ bool findNewVersion(const TopoDS_Shape& theContext, TopoDS_Shape& theResult) const;
};
#endif
}
TDF_Label aSubContext;
Selector_Algo* aSubSel =
- Selector_Algo::restoreByName(
- newSubLabel(), baseDocument(), aSubStr, aSubShapeType, theNameGenerator, aSubContext);
+ Selector_Algo::restoreByName(newSubLabel(), baseDocument(), aSubStr, aSubShapeType,
+ geometricalNaming(), theNameGenerator, aSubContext);
if (!append(aSubSel))
return TDF_Label();
std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
TDF_Label aSubContext;
Selector_Algo* aSubSel =
- Selector_Algo::restoreByName(
- newSubLabel(), baseDocument(), aSubStr, myShapeType, theNameGenerator, aSubContext);
+ Selector_Algo::restoreByName(newSubLabel(), baseDocument(), aSubStr, myShapeType,
+ geometricalNaming(), theNameGenerator, aSubContext);
if (!append(aSubSel))
return TDF_Label();
char aShapeChar = theName[anEndPos + 1];
if (theName[anEndPos + 1] != '[') {
switch(aShapeChar) {
- case 'c': aSubShapeType = TopAbs_COMPOUND; break;
- case 'o': aSubShapeType = TopAbs_COMPSOLID; break;
- case 's': aSubShapeType = TopAbs_SOLID; break;
- case 'h': aSubShapeType = TopAbs_SHELL; break;
- case 'w': aSubShapeType = TopAbs_WIRE; break;
case 'e': aSubShapeType = TopAbs_EDGE; break;
case 'v': aSubShapeType = TopAbs_VERTEX; break;
default:;
}
TDF_Label aSubContext;
Selector_Algo* aSubSel =
- Selector_Algo::restoreByName(
- newSubLabel(), baseDocument(), aSubStr, aSubShapeType, theNameGenerator, aSubContext);
+ Selector_Algo::restoreByName(newSubLabel(), baseDocument(), aSubStr, aSubShapeType,
+ geometricalNaming(), theNameGenerator, aSubContext);
if (!append(aSubSel))
return TDF_Label();
TopAbs_ShapeEnum aSubType = aSubVal.ShapeType();
if (aSubType != TopAbs_FACE) { // in case the sub shape type must be stored
switch(aSubType) {
- case TopAbs_COMPOUND: aResult += "c"; break;
- case TopAbs_COMPSOLID: aResult += "o"; break;
- case TopAbs_SOLID: aResult += "s"; break;
- case TopAbs_SHELL: aResult += "h"; break;
- case TopAbs_WIRE: aResult += "w"; break;
case TopAbs_EDGE: aResult += "e"; break;
case TopAbs_VERTEX: aResult += "v"; break;
default:;
findModificationResult(aFinalsCommon);
if (aFinalsCommon.Extent() == 1) { // result is valid: found only one shape
aResult = aFinalsCommon.First();
+ findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && myWeakIndex > 0) {
Selector_NExplode aNExp(aFinalsCommon);
aResult = aNExp.shape(myWeakIndex);
+ findNewVersion(theContext, aResult);
} else if (aFinalsCommon.Extent() > 1 && geometricalNaming()) {// if same geometry - compound
TopoDS_ListOfShape::Iterator aCommonIter(aFinalsCommon);
TopoDS_Shape aFirst = aCommonIter.Value();
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
for(aCommonIter.Initialize(aFinalsCommon); aCommonIter.More(); aCommonIter.Next()) {
- aBuilder.Add(aCompound, aCommonIter.Value());
+ TopoDS_Shape aSub = aCommonIter.Value();
+ findNewVersion(theContext, aSub);
+ aBuilder.Add(aCompound, aSub);
}
aResult = aCompound;
}
{
Handle(TNaming_NamedShape) aNS;
if (myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- Selector_Algo::store(aNS->Get());
+ TopoDS_Shape aResult = aNS->Get();
+ // if shape was modified and not exists in the context anymore, check evolution of this shape
+ // issue 2254 and similar (document CEA parametric first issue description)
+ findNewVersion(theContext, aResult);
+ Selector_Algo::store(aResult);
return true;
}
return false;
Selector_NameGenerator* theNameGenerator, const bool theGeometricalNaming)
{
TDF_Label aResult;
- myAlgo = Selector_Algo::restoreByName(
- myLab, myBaseDocumentLab, theName, theShapeType, theNameGenerator, aResult);
+ myAlgo = Selector_Algo::restoreByName(myLab, myBaseDocumentLab, theName, theShapeType,
+ theGeometricalNaming, theNameGenerator, aResult);
if (myAlgo) {
- if (theGeometricalNaming)
- myAlgo->setGeometricalNaming();
return aResult;
}
return TDF_Label();