-/// registers the name of the shape in the label (theID == 0) of sub label (theID is a tag)
-/// if theID is zero,
-/// theOrientation is additional information about the positioning of edge relatively to face
-/// it is stored in the integer attribute of the edge sub-label:
-/// -1 is out, 1 is in, 0 is not needed
-static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
- const int theID, const FeaturePtr& theContextFeature, std::shared_ptr<Model_Document> theDoc,
- std::map<int, int>& theOrientations,
- // name of sub-elements by ID to be exported instead of indexes
- std::map<int, std::string>& theSubNames,
- Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(),
- const int theOrientation = 0)
-{
- TDF_Label aLab = theID == 0 ? theMainLabel : theMainLabel.FindChild(theID);
- if (theOrientation != 0) { // store the orientation of edge relatively to face if needed
- TDataStd_Integer::Set(aLab, theOrientation);
- }
- TNaming_Builder aBuilder(aLab);
- aBuilder.Generated(theShape);
- std::stringstream aName;
- // #1839 : do not store name of the feature in the tree, since this name could be changed
- //aName<<theContextFeature->name();
- if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction
- //aName<<"/";
- if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
- else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
- else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
- else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex";
-
- if (theRefs.IsNull()) {
- aName<<theID;
- if (theOrientation == 1)
- aName<<"f";
- else if (theOrientation == -1)
- aName<<"r";
- } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
- TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
- for(; aRef.More(); aRef.Next()) {
- aName<<"-"<<theSubNames[aRef.Key()];
- if (theOrientations.find(aRef.Key()) != theOrientations.end()) {
- if (theOrientations[aRef.Key()] == 1)
- aName<<"f";
- else if (theOrientations[aRef.Key()] == -1)
- aName<<"r";
- }
- }
- }
- }
-
- theDoc->addNamingName(aLab, aName.str());
- TDataStd_Name::Set(aLab, aName.str().c_str());
-}
-
-void Model_AttributeSelection::selectConstruction(
- const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape)
-{
- std::shared_ptr<Model_Document> aMyDoc =
- std::dynamic_pointer_cast<Model_Document>(owner()->document());
- FeaturePtr aContextFeature = theContext->document()->feature(theContext);
- CompositeFeaturePtr aComposite =
- std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aContextFeature);
- const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
- if (!aComposite || aComposite->numberOfSubs() == 0) {
- // saving of context is enough: result construction contains exactly the needed shape
- TNaming_Builder aBuilder(selectionLabel());
- aBuilder.Generated(aSubShape);
- //std::string aName = contextName(theContext);
- //aMyDoc->addNamingName(selectionLabel(), aName);
- //TDataStd_Name::Set(selectionLabel(), aName.c_str());
- return;
- }
- std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(owner()->data());
- TDF_Label aLab = myRef.myRef->Label();
- // identify the results of sub-object of the composite by edges
- // save type of the selected shape in integer attribute
- TopAbs_ShapeEnum aShapeType = aSubShape.ShapeType();
- TDataStd_Integer::Set(aLab, (int)aShapeType);
- gp_Pnt aVertexPos;
- TColStd_MapOfTransient allCurves;
- if (aShapeType == TopAbs_VERTEX) { // compare positions
- aVertexPos = BRep_Tool::Pnt(TopoDS::Vertex(aSubShape));
- } else {
- for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) {
- TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current());
- Standard_Real aFirst, aLast;
- Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
- allCurves.Add(aCurve);
- }
- }
- // iterate and store the result ids of sub-elements and sub-elements to sub-labels
- Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
- std::map<int, int> anOrientations; //map from edges IDs to orientations of these edges in face
- std::map<int, std::string> aSubNames; //map from edges IDs to names of edges
- aRefs->Clear();
- const int aSubNum = aComposite->numberOfSubs();
- for(int a = 0; a < aSubNum; a++) {
- FeaturePtr aSub = aComposite->subFeature(a);
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
- // there may be many shapes (circle and center): register if at least one is in selection
- for(; aRes != aResults.cend(); aRes++) {
- ResultConstructionPtr aConstr =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
- if (!aConstr->shape()) {
- continue;
- }
- if (aShapeType == TopAbs_VERTEX) {
- if (aConstr->shape()->isVertex()) { // compare vertices positions
- const TopoDS_Shape& aVertex = aConstr->shape()->impl<TopoDS_Shape>();
- gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex));
- if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
- aRefs->Add(aComposite->subFeatureId(a));
- aSubNames[aComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr);
- }
- } else { // get first or last vertex of the edge: last is stored with additional delta
- const TopoDS_Shape& anEdge = aConstr->shape()->impl<TopoDS_Shape>();
- int aDelta = kSTART_VERTEX_DELTA;
- for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) {
- gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current()));
- if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) {
- aRefs->Add(aDelta + aComposite->subFeatureId(a));
- aSubNames[aDelta + aComposite->subFeatureId(a)] =
- Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA);
- break;
- }
- aDelta += kSTART_VERTEX_DELTA;
- }
- }
- } else {
- if (aConstr->shape()->isEdge()) {
- const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
- TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
- if (!anEdge.IsNull()) {
- Standard_Real aFirst, aLast;
- Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
- if (allCurves.Contains(aCurve)) {
- int anID = aComposite->subFeatureId(a);
- aRefs->Add(anID);
- aSubNames[anID] = Model_SelectionNaming::shortName(aConstr);
- if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels
- // add edges to sub-label to support naming for edges selection
- TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE);
- for(; anEdgeExp.More(); anEdgeExp.Next()) {
- TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current());
- Standard_Real aFirst, aLast;
- Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
- if (aFaceCurve == aCurve) {
- int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
- anOrientations[anID] = anOrient;
-
- TDF_Label aLab = selectionLabel().FindChild(anID);
- std::string aName = "Edge-" + Model_SelectionNaming::shortName(aConstr, 0);
- TNaming_Builder aBuilder(aLab);
- aBuilder.Generated(anEdge);
- aMyDoc->addNamingName(aLab, aName.c_str());
- TDataStd_Name::Set(aLab, aName.c_str());
-
- if (anOrient != 0) {
- // store the orientation of edge relatively to face if needed
- TDataStd_Integer::Set(aLab, anOrient);
- }
- }
- }
- } else { // put vertices of the selected edge to sub-labels
- // add edges to sub-label to support naming for edges selection
- int aDelta = kSTART_VERTEX_DELTA;
- int aTagIndex = anID + kSTART_VERTEX_DELTA;
- for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX);
- anEdgeExp.More();
- anEdgeExp.Next(),
- aTagIndex += kSTART_VERTEX_DELTA,
- aDelta += kSTART_VERTEX_DELTA) {
- TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current());
-
- TDF_Label aLab = selectionLabel().FindChild(aTagIndex);
- std::string aName = "Vertex-"
- + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA);
- TNaming_Builder aBuilder(aLab);
- aBuilder.Generated(aV);
- aMyDoc->addNamingName(aLab, aName.c_str());
- TDataStd_Name::Set(aLab, aName.c_str());
- }
- }
- }
- }
- }
- }
- }
- }
- // store the selected as primitive
- registerSubShape(
- selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, anOrientations, aSubNames, aRefs);
-}
-