1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <Model_ResultConstruction.h>
22 #include <Model_Data.h>
23 #include <ModelAPI_CompositeFeature.h>
24 #include <GeomAlgoAPI_SketchBuilder.h>
25 #include <GeomAPI_Tools.h>
26 #include <ModelAPI_Events.h>
27 #include <Model_Document.h>
28 #include <GeomAPI_PlanarEdges.h>
29 #include <GeomAPI_Shape.h>
30 #include <Events_Loop.h>
31 #include <GeomDataAPI_Point.h>
32 #include <GeomDataAPI_Dir.h>
34 #include <TDF_ChildIDIterator.hxx>
35 #include <TNaming_NamedShape.hxx>
36 #include <TNaming_Builder.hxx>
37 #include <TDataStd_IntPackedMap.hxx>
38 #include <TDataStd_Name.hxx>
39 #include <TDataStd_UAttribute.hxx>
40 #include <BRep_Builder.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopoDS_ListOfShape.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <NCollection_IndexedDataMap.hxx>
51 typedef NCollection_IndexedDataMap<TopoDS_Face, TColStd_ListOfInteger> MapFaceToEdgeIndices;
53 /// Convert each edge of sketch to corresponding integer value
54 /// \param[in] theComposite sketch feature
55 /// \param[out] theCurvesIndices map curve to its index
56 /// \param[out] theEdgesIndices indexed edge
57 /// \param[out] theEdgesNames indexed name for edge
58 static void indexingSketchEdges(
59 const CompositeFeaturePtr& theComposite,
60 NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
61 NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
62 std::map<int, std::string>& theEdgesNames);
64 /// Convert each face to the list of indices of its edges
65 /// \param[in] theFaces list of faces to proceed
66 /// \param[in] theCurvesIndices index of each curve
67 /// \param[out] theFaceEdges map face to indices of its edges
68 static void faceToEdgeIndices(
69 const ListOfShape& theFaces,
70 const NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
71 MapFaceToEdgeIndices& theFaceEdges);
73 /// Assign faces to tags for the specified label
74 /// \param theDocument current document
75 /// \param theShapeLabel label to store shapes
76 /// \param theName name of the object
77 /// \param theShape shape to be stored to the label
78 /// \param theFacesOrder faces to be assigned to specified tag
79 /// \param theUnorderedFaces faces which may be stored to any tag
80 /// \param theFaceEdges indices of edges for each face
81 /// \param theEdgesIndices indices of edges
82 /// \param theEdgesNames named of edges
83 static void storeFacesOnLabel(std::shared_ptr<Model_Document>& theDocument,
84 TDF_Label& theShapeLabel,
85 const std::string& theName,
86 const TopoDS_Shape& theShape,
87 NCollection_DataMap<int, TopoDS_Face>& theFacesOrder,
88 NCollection_List<TopoDS_Face>& theUnorderedFaces,
89 const MapFaceToEdgeIndices& theFaceEdges,
90 const NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
91 const std::map<int, std::string>& theEdgesNames);
94 // identifier of the infinite result
95 Standard_GUID kIS_INFINITE("dea8cc5a-53f2-49c1-94e8-a947bed20a9f");
96 // identifier of the result not in history
97 Standard_GUID kIS_IN_HISTORY("a9aec01c-805e-44d1-b5d2-a63f06522f8a");
99 void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::string& theName,
100 std::string& theDefault)
102 theSection = "Visualization";
103 theName = "result_construction_color";
104 theDefault = DEFAULT_COLOR();
107 void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
109 if (myShape != theShape) {
110 storeShape(theShape);
111 if (!theShape.get() || !theShape->isEqual(myShape)) {
112 static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
113 ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent);
119 std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
124 static std::string shortName(
125 std::shared_ptr<ModelAPI_ResultConstruction>& theConstr)
127 std::string aName = theConstr->data()->name();
128 // remove "-", "/" and "&" command-symbols
129 aName.erase(std::remove(aName.begin(), aName.end(), '-'), aName.end());
130 aName.erase(std::remove(aName.begin(), aName.end(), '/'), aName.end());
131 aName.erase(std::remove(aName.begin(), aName.end(), '&'), aName.end());
132 // remove the last 's', 'e', 'f' and 'r' symbols:
133 // they are used as markers of start/end/forward/reversed indicators
134 static const std::string aSyms("sefr");
135 std::string::iterator aSuffix = aName.end() - 1;
136 while(aSyms.find(*aSuffix) != std::string::npos) {
139 aName.erase(aSuffix + 1, aName.end());
143 bool Model_ResultConstruction::updateShape()
145 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
146 if (aData && aData->isValid()) {
147 TDF_Label aShapeLab = aData->shapeLab();
148 Handle(TNaming_NamedShape) aNS;
149 if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
150 TopoDS_Shape aShape = aNS->Get();
151 if (!aShape.IsNull()) {
152 if (aShape.ShapeType() == TopAbs_COMPOUND) {
153 // restore the sketch planar edges object
154 std::shared_ptr<GeomAPI_PlanarEdges> aBigWire(new GeomAPI_PlanarEdges);
155 aBigWire->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
157 document()->feature(std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner()));
158 std::shared_ptr<GeomDataAPI_Point> anOrigin =
159 std::dynamic_pointer_cast<GeomDataAPI_Point>(aSketch->data()->attribute("Origin"));
160 std::shared_ptr<GeomDataAPI_Dir> aDirX =
161 std::dynamic_pointer_cast<GeomDataAPI_Dir>(aSketch->data()->attribute("DirX"));
162 std::shared_ptr<GeomDataAPI_Dir> aNorm =
163 std::dynamic_pointer_cast<GeomDataAPI_Dir>(aSketch->data()->attribute("Norm"));
164 if (anOrigin.get() && aDirX.get() && aNorm.get()) {
165 aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aNorm->dir());
170 // just restore shape
171 GeomShapePtr aGShape(new GeomAPI_Shape);
172 aGShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
173 myShape = GeomAPI_Tools::getTypedShape(aGShape); // restore the sketch sub-components
181 Model_ResultConstruction::Model_ResultConstruction()
185 bool Model_ResultConstruction::isInHistory()
187 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
188 if (aData.get() && aData->isValid()) {
189 return !aData->label().IsAttribute(kIS_IN_HISTORY); // by default no attribute, but in history
191 return true; // unknown case
194 void Model_ResultConstruction::setIsInHistory(const bool isInHistory)
196 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
197 if (aData.get() && aData->isValid()) {
199 TDataStd_UAttribute::Set(aData->label(), kIS_IN_HISTORY);
201 aData->label().ForgetAttribute(kIS_IN_HISTORY);
205 bool Model_ResultConstruction::isInfinite()
207 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
208 if (aData.get() && aData->isValid()) {
209 return aData->label().IsAttribute(kIS_INFINITE);
211 return false; // unknown case
214 void Model_ResultConstruction::setInfinite(const bool theInfinite)
216 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
217 if (aData.get() && aData->isValid()) {
219 TDataStd_UAttribute::Set(aData->label(), kIS_INFINITE);
221 aData->label().ForgetAttribute(kIS_INFINITE);
225 int Model_ResultConstruction::facesNum(const bool theUpdateNaming)
228 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
229 if (aData.get() && aData->isValid()) {
230 TDF_Label aShapeLab = aData->shapeLab();
231 TDF_ChildIDIterator anOldIter(aShapeLab, TDataStd_IntPackedMap::GetID());
232 for (; anOldIter.More(); anOldIter.Next()) {
239 std::shared_ptr<GeomAPI_Face> Model_ResultConstruction::face(const int theIndex)
241 std::shared_ptr<GeomAPI_Face> aResult;
243 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
244 if (aData.get() && aData->isValid()) {
245 TDF_Label aShapeLab = aData->shapeLab();
246 TDF_ChildIDIterator anOldIter(aShapeLab, TDataStd_IntPackedMap::GetID());
247 for (; anOldIter.More(); anOldIter.Next()) {
248 if (anIndex == theIndex) {
249 Handle(TNaming_NamedShape) aNS;
250 anOldIter.Value()->Label().FindAttribute(TNaming_NamedShape::GetID(), aNS);
251 aResult.reset(new GeomAPI_Face);
252 aResult->setImpl(new TopoDS_Shape(aNS->Get()));
261 void Model_ResultConstruction::setIsConcealed(const bool theValue, const bool theForced)
263 // the construction element may be concealed only by "delete" feature
264 if (!theValue || theForced) {
265 ModelAPI_ResultConstruction::setIsConcealed(theValue, theForced);
269 void Model_ResultConstruction::storeShape(std::shared_ptr<GeomAPI_Shape> theShape)
271 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
272 if (aData && aData->isValid()) {
273 std::string aMyName = data()->name();
274 TDF_Label aShapeLab = aData->shapeLab();
275 if (!theShape.get() || theShape->isNull()) {
276 aShapeLab.ForgetAllAttributes();
277 TDataStd_Name::Set(aShapeLab, aMyName.c_str()); // restore name forgotten
280 std::shared_ptr<Model_Document> aMyDoc =
281 std::dynamic_pointer_cast<Model_Document>(document());
282 const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
283 if (isInfinite() || aShape.ShapeType() == TopAbs_VERTEX) {
284 aShapeLab.ForgetAllAttributes(); // clear all previously stored
285 TNaming_Builder aBuilder(aShapeLab);
286 aBuilder.Generated(aShape);
287 TDataStd_Name::Set(aShapeLab, aMyName.c_str());
288 aMyDoc->addNamingName(aShapeLab, aMyName);
289 } else if (aShape.ShapeType() == TopAbs_EDGE) { // store sub-vertices on sub-labels
290 aShapeLab.ForgetAllAttributes(); // clear all previously stored
291 TNaming_Builder aBuilder(aShapeLab);
292 aBuilder.Generated(aShape);
294 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
295 for(int anIndex = 1; anExp.More(); anExp.Next(), anIndex++) {
296 TDF_Label aSubLab = aShapeLab.FindChild(anIndex);
297 TNaming_Builder aBuilder(aSubLab);
298 aBuilder.Generated(anExp.Current());
299 std::string aVertexName = aMyName + "_" + (anIndex == 1 ? "StartVertex" : "EndVertex");
300 TDataStd_Name::Set(aSubLab, aVertexName.c_str());
301 aMyDoc->addNamingName(aSubLab, aVertexName);
303 TDataStd_Name::Set(aShapeLab, aMyName.c_str());
304 aMyDoc->addNamingName(aShapeLab, aMyName);
305 } else { // this is probably sketch, so, work with it as with composite
306 std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr =
307 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(theShape);
309 return; // unknown case
310 ResultPtr aThisPtr = std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner());
311 FeaturePtr aThisFeature = aMyDoc->feature(aThisPtr);
312 CompositeFeaturePtr aComposite =
313 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aThisFeature);
314 if (!aComposite || aComposite->numberOfSubs() == 0)
315 return; // unknown case
316 // collect indices of curves of current composite
317 NCollection_DataMap<Handle(Geom_Curve), int> aCurvesIndices;
318 NCollection_DataMap<int, TopoDS_Edge> anEdgeIndices;
319 std::map<int, std::string> aComponentsNames; // names of components that lay on index
320 indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames);
322 GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(),
323 aWirePtr->norm(), aWirePtr);
324 const ListOfShape& aFaces = aSketchBuilder.faces();
325 // order is important to store faces in the same order if sketch is created from scratch
326 MapFaceToEdgeIndices aNewIndices; // edges indices
327 faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices);
329 NCollection_DataMap<int, TopoDS_Face> aFacesOrder; // faces -> tag where they must be set
330 NCollection_List<TopoDS_Face> anUnorderedFaces; // faces that may be located at any index
331 // searching for the best new candidate to old location
332 MapFaceToEdgeIndices::Iterator aNewIter(aNewIndices);
333 for (; aNewIter.More(); aNewIter.Next()) {
334 double aBestFound = 0, aBestNotFound = 1.e+100;
336 const TColStd_ListOfInteger& aNewInd = aNewIter.Value();
337 // old faces indices where they where located
338 TDF_ChildIDIterator anOldIter(aShapeLab, TDataStd_IntPackedMap::GetID());
339 for (; anOldIter.More(); anOldIter.Next()) {
340 int aTag = anOldIter.Value()->Label().Tag();
341 if (aFacesOrder.IsBound(aTag))
342 continue; // already found a best candidate
343 Handle(TDataStd_IntPackedMap) anOldIndices =
344 Handle(TDataStd_IntPackedMap)::DownCast(anOldIter.Value());
345 double aFound = 0, aNotFound = 0;
346 TColStd_ListOfInteger::Iterator aNewIndIter(aNewInd);
347 for (; aNewIndIter.More(); aNewIndIter.Next()) {
348 if (anOldIndices->Contains(aNewIndIter.Value())) {
351 else if (anOldIndices->Contains(-aNewIndIter.Value())) { // different orientation
358 if (aNotFound <= aBestNotFound) { // less and equal to find better "found": #2859
359 if (aFound > aBestFound) {
360 aBestNotFound = aNotFound;
366 if (aBestTag != 0) { // found an appropriate face
367 aFacesOrder.Bind(aBestTag, aNewIter.Key());
369 anUnorderedFaces.Append(aNewIter.Key());
372 storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces,
373 aNewIndices, anEdgeIndices, aComponentsNames);
378 void Model_ResultConstruction::setFacesOrder(const std::list<GeomFacePtr>& theFaces)
380 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
381 if (aData && aData->isValid()) {
382 std::string aMyName = data()->name();
383 TDF_Label aShapeLab = aData->shapeLab();
384 GeomShapePtr aResShape = shape();
385 if (!aResShape.get() || aResShape->isNull()) {
389 std::shared_ptr<Model_Document> aMyDoc =
390 std::dynamic_pointer_cast<Model_Document>(document());
391 const TopoDS_Shape& aShape = aResShape->impl<TopoDS_Shape>();
392 if (aShape.ShapeType() != TopAbs_VERTEX &&
393 aShape.ShapeType() != TopAbs_EDGE) {
394 ResultPtr aThisPtr = std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner());
395 FeaturePtr aThisFeature = aMyDoc->feature(aThisPtr);
396 CompositeFeaturePtr aComposite =
397 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aThisFeature);
398 if (!aComposite || aComposite->numberOfSubs() == 0)
399 return; // unknown case
400 // collect indices of curves of current composite
401 NCollection_DataMap<Handle(Geom_Curve), int> aCurvesIndices;
402 NCollection_DataMap<int, TopoDS_Edge> anEdgeIndices;
403 std::map<int, std::string> aComponentsNames; // names of components that lay on index
404 indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames);
407 NCollection_DataMap<int, TopoDS_Face> aFacesOrder; // faces -> tag where they must be set
408 NCollection_List<TopoDS_Face> anUnorderedFaces; // unordered faces are empty in this case
410 for (std::list<GeomFacePtr>::const_iterator aFIt = theFaces.begin();
411 aFIt != theFaces.end(); ++aFIt) {
412 aFaces.push_back(*aFIt);
413 aFacesOrder.Bind(++aTagId, (*aFIt)->impl<TopoDS_Face>());
416 MapFaceToEdgeIndices aNewIndices; // edges indices
417 faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices);
419 storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces,
420 aNewIndices, anEdgeIndices, aComponentsNames);
425 // ========================== Auxiliary functions =========================================
427 void storeFacesOnLabel(std::shared_ptr<Model_Document>& theDocument,
428 TDF_Label& theShapeLabel,
429 const std::string& theName,
430 const TopoDS_Shape& theShape,
431 NCollection_DataMap<int, TopoDS_Face>& theFacesOrder,
432 NCollection_List<TopoDS_Face>& theUnorderedFaces,
433 const MapFaceToEdgeIndices& theFaceEdges,
434 const NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
435 const std::map<int, std::string>& theEdgesNames)
437 theShapeLabel.ForgetAllAttributes(); // clear all previously stored
438 TDataStd_Name::Set(theShapeLabel, theName.c_str()); // restore name forgotten
439 TNaming_Builder aBuilder(theShapeLabel); // store the compound to get it ready on open of document
440 aBuilder.Generated(theShape);
441 theDocument->addNamingName(theShapeLabel, theName);
442 // set new faces to the labels
444 NCollection_List<TopoDS_Face>::Iterator anUnordered(theUnorderedFaces);
445 for (int aCurrentTag = 1; !theFacesOrder.IsEmpty() || anUnordered.More(); aCurrentTag++) {
446 TopoDS_Face aFaceToPut;
447 if (theFacesOrder.IsBound(aCurrentTag)) {
448 aFaceToPut = theFacesOrder.Find(aCurrentTag);
449 theFacesOrder.UnBind(aCurrentTag);
451 else if (anUnordered.More()) {
452 aFaceToPut = anUnordered.Value();
456 if (aFaceToPut.IsNull())
459 TopTools_MapOfShape aFaceEdges;
460 for (TopExp_Explorer anEdges(aFaceToPut, TopAbs_EDGE); anEdges.More(); anEdges.Next())
461 aFaceEdges.Add(anEdges.Current());
463 TDF_Label aLab = theShapeLabel.FindChild(aCurrentTag);
464 TNaming_Builder aFaceBuilder(aLab);
465 aFaceBuilder.Generated(aFaceToPut);
466 // store also indices of the new face edges
467 Handle(TDataStd_IntPackedMap) aNewMap = TDataStd_IntPackedMap::Set(aLab);
468 const TColStd_ListOfInteger& aNewInd = theFaceEdges.FindFromKey(aFaceToPut);
469 std::stringstream aName;
471 TopExp_Explorer aPutEdges(aFaceToPut, TopAbs_EDGE);
472 TNaming_Builder *anEdgesBuilder = 0, *aVerticesBuilder = 0;
473 for(TColStd_ListOfInteger::Iterator anIter(aNewInd); anIter.More(); anIter.Next()) {
474 int anIndex = anIter.Value();
475 int aModIndex = anIndex > 0 ? anIndex : -anIndex;
476 aNewMap->Add(anIndex);
477 aName<<"-"<<theEdgesNames.find(aModIndex)->second;
478 if (anIter.Value() > 0)
482 // collect all edges of the face which are modified in sub-label of the face
483 if (theEdgesIndices.IsBound(aModIndex) &&
484 !aFaceEdges.Contains(theEdgesIndices.Find(aModIndex))) {
485 if (!anEdgesBuilder) {
486 TDF_Label anEdgesLabel = aLab.FindChild(1);
487 anEdgesBuilder = new TNaming_Builder(anEdgesLabel);
488 std::ostringstream aSubName;
489 // tag is needed for Test1922 to distinguish sub-edges of different faces
490 aSubName<<"SubEdge_"<<aCurrentTag;
491 TDataStd_Name::Set(anEdgesLabel, aSubName.str().c_str());
493 anEdgesBuilder->Modify(theEdgesIndices.Find(aModIndex), aPutEdges.Current());
495 // put also modified vertices, otherwise vertex of original edge has no history
496 if (theEdgesIndices.IsBound(aModIndex)) {
497 TopExp_Explorer aVExpOld(theEdgesIndices.Find(aModIndex), TopAbs_VERTEX);
498 TopExp_Explorer aVExpNew(aPutEdges.Current(), TopAbs_VERTEX);
499 for(; aVExpNew.More() && aVExpOld.More(); aVExpNew.Next(), aVExpOld.Next()) {
500 if (!aVExpOld.Current().IsSame(aVExpNew.Current())) {
501 if (!aVerticesBuilder) {
502 TDF_Label aVertLabel = aLab.FindChild(2);
503 aVerticesBuilder = new TNaming_Builder(aVertLabel);
504 std::ostringstream aSubName;
505 // tag is needed for Test1922 to distinguish sub-edges of different faces
506 aSubName<<"SubVertex_"<<aCurrentTag;
507 TDataStd_Name::Set(aVertLabel, aSubName.str().c_str());
509 aVerticesBuilder->Modify(aVExpOld.Current(), aVExpNew.Current());
517 delete anEdgesBuilder;
518 if (aVerticesBuilder)
519 delete aVerticesBuilder;
520 TDataStd_Name::Set(aLab, TCollection_ExtendedString(aName.str().c_str()));
521 theDocument->addNamingName(aLab, aName.str());
522 // put also wires to sub-labels to correctly select them instead of collection by edges
523 int aWireTag = 3; // first tag is for SubEdge-s, second - for vertices
524 for(TopExp_Explorer aWires(aFaceToPut, TopAbs_WIRE); aWires.More(); aWires.Next()) {
525 TDF_Label aWireLab = aLab.FindChild(aWireTag);
526 TNaming_Builder aWireBuilder(aWireLab);
527 aWireBuilder.Generated(aWires.Current());
528 std::ostringstream aWireName;
529 aWireName<<aName.str()<<"_wire";
531 aWireName<<"_"<<aWireTag - 2;
532 TDataStd_Name::Set(aWireLab, aWireName.str().c_str());
533 theDocument->addNamingName(aWireLab, aWireName.str());
539 void indexingSketchEdges(const CompositeFeaturePtr& theComposite,
540 NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
541 NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
542 std::map<int, std::string>& theEdgesNames)
544 const int aSubNum = theComposite->numberOfSubs();
545 for (int a = 0; a < aSubNum; a++) {
546 FeaturePtr aSub = theComposite->subFeature(a);
547 const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
548 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
549 for (; aRes != aResults.cend(); aRes++) {
550 ResultConstructionPtr aConstr =
551 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
552 if (aConstr->shape() && aConstr->shape()->isEdge()) {
553 TopoDS_Edge anEdge = TopoDS::Edge(aConstr->shape()->impl<TopoDS_Shape>());
554 Standard_Real aFirst, aLast;
555 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
556 theCurvesIndices.Bind(aCurve, a);
557 theEdgesIndices.Bind(a, anEdge);
558 theEdgesNames[a] = shortName(aConstr);
564 void faceToEdgeIndices(const ListOfShape& theFaces,
565 const NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
566 MapFaceToEdgeIndices& theFaceEdges)
568 std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFIter = theFaces.begin();
569 for (; aFIter != theFaces.end(); aFIter++) {
570 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
571 // put them to a label, trying to keep the same faces on the same labels
572 if (aFace.get() && !aFace->isNull()) {
573 TopoDS_Face aTopoFace = TopoDS::Face(aFace->impl<TopoDS_Shape>());
574 theFaceEdges.Add(aTopoFace, TColStd_ListOfInteger());
575 // keep new indices of sub-elements used in this face
576 for (TopExp_Explorer anEdges(aTopoFace, TopAbs_EDGE); anEdges.More(); anEdges.Next()) {
577 TopoDS_Edge anEdge = TopoDS::Edge(anEdges.Current());
578 Standard_Real aFirst, aLast;
579 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
580 if (theCurvesIndices.IsBound(aCurve)) {
581 int anIndex = theCurvesIndices.Find(aCurve);
582 if ((aFirst > aLast) != (anEdge.Orientation() == TopAbs_REVERSED))
584 theFaceEdges.ChangeFromKey(aTopoFace).Append(anIndex);