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::wstring>& 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::wstring& 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::wstring>& 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::wstring shortName(
125 std::shared_ptr<ModelAPI_ResultConstruction>& theConstr)
127 std::wstring 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::wstring aSyms(L"sefr");
135 std::wstring::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::wstring 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::wstring aVertexName = aMyName + L"_" +
300 (anIndex == 1 ? L"StartVertex" : L"EndVertex");
301 TDataStd_Name::Set(aSubLab, aVertexName.c_str());
302 aMyDoc->addNamingName(aSubLab, aVertexName);
304 TDataStd_Name::Set(aShapeLab, aMyName.c_str());
305 aMyDoc->addNamingName(aShapeLab, aMyName);
306 } else { // this is probably sketch, so, work with it as with composite
307 std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr =
308 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(theShape);
310 return; // unknown case
311 ResultPtr aThisPtr = std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner());
312 FeaturePtr aThisFeature = aMyDoc->feature(aThisPtr);
313 CompositeFeaturePtr aComposite =
314 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aThisFeature);
315 if (!aComposite || aComposite->numberOfSubs() == 0)
316 return; // unknown case
317 // collect indices of curves of current composite
318 NCollection_DataMap<Handle(Geom_Curve), int> aCurvesIndices;
319 NCollection_DataMap<int, TopoDS_Edge> anEdgeIndices;
320 std::map<int, std::wstring> aComponentsNames; // names of components that lay on index
321 indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames);
323 GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(),
324 aWirePtr->norm(), aWirePtr);
325 const ListOfShape& aFaces = aSketchBuilder.faces();
326 // order is important to store faces in the same order if sketch is created from scratch
327 MapFaceToEdgeIndices aNewIndices; // edges indices
328 faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices);
330 NCollection_DataMap<int, TopoDS_Face> aFacesOrder; // faces -> tag where they must be set
331 NCollection_List<TopoDS_Face> anUnorderedFaces; // faces that may be located at any index
332 // searching for the best new candidate to old location
333 MapFaceToEdgeIndices::Iterator aNewIter(aNewIndices);
334 for (; aNewIter.More(); aNewIter.Next()) {
335 double aBestFound = 0, aBestNotFound = 1.e+100;
337 const TColStd_ListOfInteger& aNewInd = aNewIter.Value();
338 // old faces indices where they where located
339 TDF_ChildIDIterator anOldIter(aShapeLab, TDataStd_IntPackedMap::GetID());
340 for (; anOldIter.More(); anOldIter.Next()) {
341 int aTag = anOldIter.Value()->Label().Tag();
342 if (aFacesOrder.IsBound(aTag))
343 continue; // already found a best candidate
344 Handle(TDataStd_IntPackedMap) anOldIndices =
345 Handle(TDataStd_IntPackedMap)::DownCast(anOldIter.Value());
346 double aFound = 0, aNotFound = 0;
347 TColStd_ListOfInteger::Iterator aNewIndIter(aNewInd);
348 for (; aNewIndIter.More(); aNewIndIter.Next()) {
349 if (anOldIndices->Contains(aNewIndIter.Value())) {
352 else if (anOldIndices->Contains(-aNewIndIter.Value())) { // different orientation
359 if (aNotFound <= aBestNotFound) { // less and equal to find better "found": #2859
360 if (aFound > aBestFound) {
361 aBestNotFound = aNotFound;
367 if (aBestTag != 0) { // found an appropriate face
368 aFacesOrder.Bind(aBestTag, aNewIter.Key());
370 anUnorderedFaces.Append(aNewIter.Key());
373 storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces,
374 aNewIndices, anEdgeIndices, aComponentsNames);
379 void Model_ResultConstruction::setFacesOrder(const std::list<GeomFacePtr>& theFaces)
381 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
382 if (aData && aData->isValid()) {
383 std::wstring aMyName = data()->name();
384 TDF_Label aShapeLab = aData->shapeLab();
385 GeomShapePtr aResShape = shape();
386 if (!aResShape.get() || aResShape->isNull()) {
390 std::shared_ptr<Model_Document> aMyDoc =
391 std::dynamic_pointer_cast<Model_Document>(document());
392 const TopoDS_Shape& aShape = aResShape->impl<TopoDS_Shape>();
393 if (aShape.ShapeType() != TopAbs_VERTEX &&
394 aShape.ShapeType() != TopAbs_EDGE) {
395 ResultPtr aThisPtr = std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner());
396 FeaturePtr aThisFeature = aMyDoc->feature(aThisPtr);
397 CompositeFeaturePtr aComposite =
398 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aThisFeature);
399 if (!aComposite || aComposite->numberOfSubs() == 0)
400 return; // unknown case
401 // collect indices of curves of current composite
402 NCollection_DataMap<Handle(Geom_Curve), int> aCurvesIndices;
403 NCollection_DataMap<int, TopoDS_Edge> anEdgeIndices;
404 std::map<int, std::wstring> aComponentsNames; // names of components that lay on index
405 indexingSketchEdges(aComposite, aCurvesIndices, anEdgeIndices, aComponentsNames);
408 NCollection_DataMap<int, TopoDS_Face> aFacesOrder; // faces -> tag where they must be set
409 NCollection_List<TopoDS_Face> anUnorderedFaces; // unordered faces are empty in this case
411 for (std::list<GeomFacePtr>::const_iterator aFIt = theFaces.begin();
412 aFIt != theFaces.end(); ++aFIt) {
413 aFaces.push_back(*aFIt);
414 aFacesOrder.Bind(++aTagId, (*aFIt)->impl<TopoDS_Face>());
417 MapFaceToEdgeIndices aNewIndices; // edges indices
418 faceToEdgeIndices(aFaces, aCurvesIndices, aNewIndices);
420 storeFacesOnLabel(aMyDoc, aShapeLab, aMyName, aShape, aFacesOrder, anUnorderedFaces,
421 aNewIndices, anEdgeIndices, aComponentsNames);
426 // ========================== Auxiliary functions =========================================
428 void storeFacesOnLabel(std::shared_ptr<Model_Document>& theDocument,
429 TDF_Label& theShapeLabel,
430 const std::wstring& theName,
431 const TopoDS_Shape& theShape,
432 NCollection_DataMap<int, TopoDS_Face>& theFacesOrder,
433 NCollection_List<TopoDS_Face>& theUnorderedFaces,
434 const MapFaceToEdgeIndices& theFaceEdges,
435 const NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
436 const std::map<int, std::wstring>& theEdgesNames)
438 theShapeLabel.ForgetAllAttributes(); // clear all previously stored
439 TDataStd_Name::Set(theShapeLabel, theName.c_str()); // restore name forgotten
440 TNaming_Builder aBuilder(theShapeLabel); // store the compound to get it ready on open of document
441 aBuilder.Generated(theShape);
442 theDocument->addNamingName(theShapeLabel, theName);
443 // set new faces to the labels
445 NCollection_List<TopoDS_Face>::Iterator anUnordered(theUnorderedFaces);
446 for (int aCurrentTag = 1; !theFacesOrder.IsEmpty() || anUnordered.More(); aCurrentTag++) {
447 TopoDS_Face aFaceToPut;
448 if (theFacesOrder.IsBound(aCurrentTag)) {
449 aFaceToPut = theFacesOrder.Find(aCurrentTag);
450 theFacesOrder.UnBind(aCurrentTag);
452 else if (anUnordered.More()) {
453 aFaceToPut = anUnordered.Value();
457 if (aFaceToPut.IsNull())
460 TopTools_MapOfShape aFaceEdges;
461 for (TopExp_Explorer anEdges(aFaceToPut, TopAbs_EDGE); anEdges.More(); anEdges.Next())
462 aFaceEdges.Add(anEdges.Current());
464 TDF_Label aLab = theShapeLabel.FindChild(aCurrentTag);
465 TNaming_Builder aFaceBuilder(aLab);
466 aFaceBuilder.Generated(aFaceToPut);
467 // store also indices of the new face edges
468 Handle(TDataStd_IntPackedMap) aNewMap = TDataStd_IntPackedMap::Set(aLab);
469 const TColStd_ListOfInteger& aNewInd = theFaceEdges.FindFromKey(aFaceToPut);
470 std::wstringstream aName;
472 TopExp_Explorer aPutEdges(aFaceToPut, TopAbs_EDGE);
473 TNaming_Builder *anEdgesBuilder = 0, *aVerticesBuilder = 0;
474 for(TColStd_ListOfInteger::Iterator anIter(aNewInd); anIter.More(); anIter.Next()) {
475 int anIndex = anIter.Value();
476 int aModIndex = anIndex > 0 ? anIndex : -anIndex;
477 aNewMap->Add(anIndex);
478 aName<<"-"<<theEdgesNames.find(aModIndex)->second;
479 if (anIter.Value() > 0)
483 // collect all edges of the face which are modified in sub-label of the face
484 if (theEdgesIndices.IsBound(aModIndex) &&
485 !aFaceEdges.Contains(theEdgesIndices.Find(aModIndex))) {
486 if (!anEdgesBuilder) {
487 TDF_Label anEdgesLabel = aLab.FindChild(1);
488 anEdgesBuilder = new TNaming_Builder(anEdgesLabel);
489 std::ostringstream aSubName;
490 // tag is needed for Test1922 to distinguish sub-edges of different faces
491 aSubName<<"SubEdge_"<<aCurrentTag;
492 TDataStd_Name::Set(anEdgesLabel, aSubName.str().c_str());
494 anEdgesBuilder->Modify(theEdgesIndices.Find(aModIndex), aPutEdges.Current());
496 // put also modified vertices, otherwise vertex of original edge has no history
497 if (theEdgesIndices.IsBound(aModIndex)) {
498 TopExp_Explorer aVExpOld(theEdgesIndices.Find(aModIndex), TopAbs_VERTEX);
499 TopExp_Explorer aVExpNew(aPutEdges.Current(), TopAbs_VERTEX);
500 for(; aVExpNew.More() && aVExpOld.More(); aVExpNew.Next(), aVExpOld.Next()) {
501 if (!aVExpOld.Current().IsSame(aVExpNew.Current())) {
502 if (!aVerticesBuilder) {
503 TDF_Label aVertLabel = aLab.FindChild(2);
504 aVerticesBuilder = new TNaming_Builder(aVertLabel);
505 std::ostringstream aSubName;
506 // tag is needed for Test1922 to distinguish sub-edges of different faces
507 aSubName<<"SubVertex_"<<aCurrentTag;
508 TDataStd_Name::Set(aVertLabel, aSubName.str().c_str());
510 aVerticesBuilder->Modify(aVExpOld.Current(), aVExpNew.Current());
518 delete anEdgesBuilder;
519 if (aVerticesBuilder)
520 delete aVerticesBuilder;
521 TDataStd_Name::Set(aLab, TCollection_ExtendedString(aName.str().c_str()));
522 theDocument->addNamingName(aLab, aName.str());
523 // put also wires to sub-labels to correctly select them instead of collection by edges
524 int aWireTag = 3; // first tag is for SubEdge-s, second - for vertices
525 for(TopExp_Explorer aWires(aFaceToPut, TopAbs_WIRE); aWires.More(); aWires.Next()) {
526 TDF_Label aWireLab = aLab.FindChild(aWireTag);
527 TNaming_Builder aWireBuilder(aWireLab);
528 aWireBuilder.Generated(aWires.Current());
529 std::wostringstream aWireName;
530 aWireName<<aName.str()<<L"_wire";
532 aWireName<<"_"<<aWireTag - 2;
533 TDataStd_Name::Set(aWireLab, aWireName.str().c_str());
534 theDocument->addNamingName(aWireLab, aWireName.str());
540 void indexingSketchEdges(const CompositeFeaturePtr& theComposite,
541 NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
542 NCollection_DataMap<int, TopoDS_Edge>& theEdgesIndices,
543 std::map<int, std::wstring>& theEdgesNames)
545 const int aSubNum = theComposite->numberOfSubs();
546 for (int a = 0; a < aSubNum; a++) {
547 FeaturePtr aSub = theComposite->subFeature(a);
548 const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
549 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
550 for (; aRes != aResults.cend(); aRes++) {
551 ResultConstructionPtr aConstr =
552 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
553 if (aConstr->shape() && aConstr->shape()->isEdge()) {
554 TopoDS_Edge anEdge = TopoDS::Edge(aConstr->shape()->impl<TopoDS_Shape>());
555 Standard_Real aFirst, aLast;
556 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
557 theCurvesIndices.Bind(aCurve, a);
558 theEdgesIndices.Bind(a, anEdge);
559 theEdgesNames[a] = shortName(aConstr);
565 void faceToEdgeIndices(const ListOfShape& theFaces,
566 const NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
567 MapFaceToEdgeIndices& theFaceEdges)
569 std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFIter = theFaces.begin();
570 for (; aFIter != theFaces.end(); aFIter++) {
571 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
572 // put them to a label, trying to keep the same faces on the same labels
573 if (aFace.get() && !aFace->isNull()) {
574 TopoDS_Face aTopoFace = TopoDS::Face(aFace->impl<TopoDS_Shape>());
575 theFaceEdges.Add(aTopoFace, TColStd_ListOfInteger());
576 // keep new indices of sub-elements used in this face
577 for (TopExp_Explorer anEdges(aTopoFace, TopAbs_EDGE); anEdges.More(); anEdges.Next()) {
578 TopoDS_Edge anEdge = TopoDS::Edge(anEdges.Current());
579 Standard_Real aFirst, aLast;
580 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
581 if (theCurvesIndices.IsBound(aCurve)) {
582 int anIndex = theCurvesIndices.Find(aCurve);
583 if ((aFirst > aLast) != (anEdge.Orientation() == TopAbs_REVERSED))
585 theFaceEdges.ChangeFromKey(aTopoFace).Append(anIndex);