1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: Model_ResultBody.cpp
4 // Created: 08 Jul 2014
5 // Author: Mikhail PONIKAROV
7 #include <Model_ResultBody.h>
8 #include <Model_Data.h>
9 #include <TNaming_Builder.hxx>
10 #include <TNaming_NamedShape.hxx>
12 #include <TopoDS_Shape.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TDF_ChildIterator.hxx>
15 #include <TopTools_MapOfShape.hxx>
16 #include <TopExp_Explorer.hxx>
17 #include <TopTools_ListOfShape.hxx>
18 #include <TopTools_ListIteratorOfListOfShape.hxx>
19 #include <TopTools_DataMapOfShapeListOfShape.hxx>
20 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
21 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
22 #include <TopTools_MapIteratorOfMapOfShape.hxx>
23 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
24 #include <TopTools_IndexedMapOfShape.hxx>
25 #include <TopTools_DataMapOfShapeShape.hxx>
27 #include <BRepTools.hxx>
28 #include <GeomAPI_Shape.h>
29 #include <GeomAlgoAPI_MakeShape.h>
31 //#include <TCollection_AsciiString.hxx>
32 //#include <TDF_Tool.hxx>
33 Model_ResultBody::Model_ResultBody()
35 setIsConcealed(false);
38 void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
40 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
42 TDF_Label& aShapeLab = aData->shapeLab();
45 // store the new shape as primitive
46 TNaming_Builder aBuilder(aShapeLab);
49 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
51 return; // null shape inside
53 aBuilder.Generated(aShape);
57 void Model_ResultBody::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theFromShape,
58 const std::shared_ptr<GeomAPI_Shape>& theToShape)
60 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
62 TDF_Label& aShapeLab = aData->shapeLab();
65 // store the new shape as primitive
66 TNaming_Builder aBuilder(aShapeLab);
67 if (!theFromShape || !theToShape)
69 TopoDS_Shape aShapeBasis = theFromShape->impl<TopoDS_Shape>();
70 if (aShapeBasis.IsNull())
71 return; // null shape inside
72 TopoDS_Shape aShapeNew = theToShape->impl<TopoDS_Shape>();
73 if (aShapeNew.IsNull())
74 return; // null shape inside
75 aBuilder.Generated(aShapeBasis, aShapeNew);
79 void Model_ResultBody::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
80 const std::shared_ptr<GeomAPI_Shape>& theNewShape)
82 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
84 TDF_Label& aShapeLab = aData->shapeLab();
87 // store the new shape as primitive
88 TNaming_Builder aBuilder(aShapeLab);
89 if (!theOldShape || !theNewShape)
91 TopoDS_Shape aShapeOld = theOldShape->impl<TopoDS_Shape>();
92 if (aShapeOld.IsNull())
93 return; // null shape inside
94 TopoDS_Shape aShapeNew = theNewShape->impl<TopoDS_Shape>();
95 if (aShapeNew.IsNull())
96 return; // null shape inside
97 aBuilder.Modify(aShapeOld, aShapeNew);
101 std::shared_ptr<GeomAPI_Shape> Model_ResultBody::shape()
103 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
105 TDF_Label& aShapeLab = aData->shapeLab();
106 Handle(TNaming_NamedShape) aName;
107 if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) {
108 TopoDS_Shape aShape = aName->Get();
109 if (!aShape.IsNull()) {
110 std::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
111 aRes->setImpl(new TopoDS_Shape(aShape));
116 return std::shared_ptr<GeomAPI_Shape>();
119 void Model_ResultBody::clean()
121 std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
122 for(; aBuilder != myBuilders.end(); aBuilder++)
127 Model_ResultBody::~Model_ResultBody()
132 TNaming_Builder* Model_ResultBody::builder(const int theTag)
134 if (myBuilders.size() <= (unsigned int)theTag) {
135 myBuilders.insert(myBuilders.end(), theTag - myBuilders.size() + 1, NULL);
137 if (!myBuilders[theTag]) {
138 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
139 myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag));
140 //TCollection_AsciiString entry;//
141 //TDF_Tool::Entry(aData->shapeLab().FindChild(theTag), entry);
142 //cout << "Label = " <<entry.ToCString() <<endl;
144 return myBuilders[theTag];
147 void Model_ResultBody::generated(
148 const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theTag)
150 TopoDS_Shape aShape = theNewShape->impl<TopoDS_Shape>();
151 builder(theTag)->Generated(aShape);
154 void Model_ResultBody::generated(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
155 const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theTag)
157 TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
158 TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
159 builder(theTag)->Generated(anOldShape, aNewShape);
163 void Model_ResultBody::modified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
164 const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theTag)
166 TopoDS_Shape anOldShape = theOldShape->impl<TopoDS_Shape>();
167 TopoDS_Shape aNewShape = theNewShape->impl<TopoDS_Shape>();
168 builder(theTag)->Modify(anOldShape, aNewShape);
171 void Model_ResultBody::deleted(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
174 TopoDS_Shape aShape = theOldShape->impl<TopoDS_Shape>();
175 builder(theTag)->Delete(aShape);
178 void Model_ResultBody::loadDeletedShapes (GeomAlgoAPI_MakeShape* theMS,
179 std::shared_ptr<GeomAPI_Shape> theShapeIn,
180 const int theKindOfShape,
183 TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
184 TopTools_MapOfShape aView;
185 TopExp_Explorer ShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
186 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
187 const TopoDS_Shape& aRoot = ShapeExplorer.Current ();
188 if (!aView.Add(aRoot)) continue;
189 std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
190 aRShape->setImpl((new TopoDS_Shape(aRoot)));
191 if (theMS->isDeleted (aRShape)) {
192 builder(theTag)->Delete(aRoot);
197 void Model_ResultBody::loadAndOrientModifiedShapes (
198 GeomAlgoAPI_MakeShape* theMS,
199 std::shared_ptr<GeomAPI_Shape> theShapeIn,
200 const int theKindOfShape,
202 GeomAPI_DataMapOfShapeShape& theSubShapes)
204 TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
205 TopTools_MapOfShape aView;
206 TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
207 for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
208 const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
209 if (!aView.Add(aRoot)) continue;
211 std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
212 aRShape->setImpl((new TopoDS_Shape(aRoot)));
213 theMS->modified(aRShape, aList);
214 std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
215 for (; anIt != aLast; anIt++) {
216 TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();
217 if (theSubShapes.isBound(*anIt)) {
218 std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
219 aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
221 if (!aRoot.IsSame (aNewShape))
222 builder(theTag)->Modify(aRoot,aNewShape);
227 void Model_ResultBody::loadAndOrientGeneratedShapes (
228 GeomAlgoAPI_MakeShape* theMS,
229 std::shared_ptr<GeomAPI_Shape> theShapeIn,
230 const int theKindOfShape,
232 GeomAPI_DataMapOfShapeShape& theSubShapes)
234 TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
235 TopTools_MapOfShape aView;
236 TopExp_Explorer aShapeExplorer (aShapeIn, (TopAbs_ShapeEnum)theKindOfShape);
237 for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
238 const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
239 if (!aView.Add(aRoot)) continue;
241 std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
242 aRShape->setImpl((new TopoDS_Shape(aRoot)));
243 theMS->generated(aRShape, aList);
244 std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aList.begin(), aLast = aList.end();
245 for (; anIt != aLast; anIt++) {
246 TopoDS_Shape aNewShape = (*anIt)->impl<TopoDS_Shape>();
247 if (theSubShapes.isBound(*anIt)) {
248 std::shared_ptr<GeomAPI_Shape> aMapShape(theSubShapes.find(*anIt));
249 aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
251 if (!aRoot.IsSame (aNewShape))
252 builder(theTag)->Generated(aRoot,aNewShape);
257 //=======================================================================
258 int getDangleShapes(const TopoDS_Shape& theShapeIn,
259 const TopAbs_ShapeEnum theGeneratedFrom,
260 TopTools_DataMapOfShapeShape& theDangles)
263 TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
264 TopAbs_ShapeEnum GeneratedTo;
265 if (theGeneratedFrom == TopAbs_FACE) GeneratedTo = TopAbs_EDGE;
266 else if (theGeneratedFrom == TopAbs_EDGE) GeneratedTo = TopAbs_VERTEX;
267 else return Standard_False;
268 TopExp::MapShapesAndAncestors(theShapeIn, GeneratedTo, theGeneratedFrom, subShapeAndAncestors);
269 for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
270 const TopoDS_Shape& mayBeDangle = subShapeAndAncestors.FindKey(i);
271 const TopTools_ListOfShape& ancestors = subShapeAndAncestors.FindFromIndex(i);
272 if (ancestors.Extent() == 1) theDangles.Bind(ancestors.First(), mayBeDangle);
274 return theDangles.Extent();
277 //=======================================================================
278 void loadGeneratedDangleShapes(
279 const TopoDS_Shape& theShapeIn,
280 const TopAbs_ShapeEnum theGeneratedFrom,
281 TNaming_Builder * theBuilder)
283 TopTools_DataMapOfShapeShape dangles;
284 if (!getDangleShapes(theShapeIn, theGeneratedFrom, dangles)) return;
285 TopTools_DataMapIteratorOfDataMapOfShapeShape itr(dangles);
286 for (; itr.More(); itr.Next())
287 theBuilder->Generated(itr.Key(), itr.Value());
290 //=======================================================================
291 void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape,
294 if(theShape->isNull()) return;
295 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
296 if (aShape.ShapeType() == TopAbs_SOLID) {
297 TopExp_Explorer expl(aShape, TopAbs_FACE);
298 for (; expl.More(); expl.Next())
299 builder(++theTag)->Generated(expl.Current());
301 else if (aShape.ShapeType() == TopAbs_SHELL || aShape.ShapeType() == TopAbs_FACE) {
302 // load faces and all the free edges
303 TopTools_IndexedMapOfShape Faces;
304 TopExp::MapShapes(aShape, TopAbs_FACE, Faces);
305 if (Faces.Extent() > 1 || (aShape.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
306 TopExp_Explorer expl(aShape, TopAbs_FACE);
307 for (; expl.More(); expl.Next())
308 builder(++theTag)->Generated(expl.Current());
310 TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
311 TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
312 for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++)
314 const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
315 if (aLL.Extent() < 2) {
316 builder(++theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
318 TopTools_ListIteratorOfListOfShape anIter(aLL);
319 const TopoDS_Face& aFace = TopoDS::Face(anIter.Value());
321 if(aFace.IsEqual(anIter.Value())) {
322 builder(++theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
326 } else if (aShape.ShapeType() == TopAbs_WIRE) {
327 TopTools_IndexedMapOfShape Edges;
328 BRepTools::Map3DEdges(aShape, Edges);
329 if (Edges.Extent() == 1) {
330 builder(++theTag)->Generated(Edges.FindKey(1));
331 TopExp_Explorer expl(aShape, TopAbs_VERTEX);
332 for (; expl.More(); expl.Next()) {
333 builder(++theTag)->Generated(expl.Current());
336 TopExp_Explorer expl(aShape, TopAbs_EDGE);
337 for (; expl.More(); expl.Next()) {
338 builder(++theTag)->Generated(expl.Current());
340 // and load generated vertices.
341 TopTools_DataMapOfShapeShape generated;
342 if (getDangleShapes(aShape, TopAbs_EDGE, generated))
344 TNaming_Builder* pBuilder = builder(++theTag);
345 loadGeneratedDangleShapes(aShape, TopAbs_EDGE, pBuilder);
348 } else if (aShape.ShapeType() == TopAbs_EDGE) {
349 TopExp_Explorer expl(aShape, TopAbs_VERTEX);
350 for (; expl.More(); expl.Next()) {
351 builder(++theTag)->Generated(expl.Current());
355 //=======================================================================
356 void Model_ResultBody::loadFirstLevel(
357 std::shared_ptr<GeomAPI_Shape> theShape, int& theTag)
359 if(theShape->isNull()) return;
360 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
361 if (aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID) {
362 TopoDS_Iterator itr(aShape);
363 for (; itr.More(); itr.Next()) {
364 builder(++theTag)->Generated(itr.Value());
365 if (itr.Value().ShapeType() == TopAbs_COMPOUND ||
366 itr.Value().ShapeType() == TopAbs_COMPSOLID)
368 std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
369 itrShape->setImpl(new TopoDS_Shape(itr.Value()));
370 loadFirstLevel(itrShape, theTag);
372 std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
373 itrShape->setImpl(new TopoDS_Shape(itr.Value()));
374 loadNextLevels(itrShape, theTag);
378 std::shared_ptr<GeomAPI_Shape> itrShape(new GeomAPI_Shape());
379 itrShape->setImpl(new TopoDS_Shape(aShape));
380 loadNextLevels(itrShape, theTag);
384 //=======================================================================
385 void Model_ResultBody::loadDisconnectedEdges(
386 std::shared_ptr<GeomAPI_Shape> theShape, int& theTag)
388 if(theShape->isNull()) return;
389 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
390 TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
391 TopTools_ListOfShape empty;
392 TopExp_Explorer explF(aShape, TopAbs_FACE);
393 for (; explF.More(); explF.Next()) {
394 const TopoDS_Shape& aFace = explF.Current();
395 TopExp_Explorer explV(aFace, TopAbs_EDGE);
396 for (; explV.More(); explV.Next()) {
397 const TopoDS_Shape& anEdge = explV.Current();
398 if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
399 Standard_Boolean faceIsNew = Standard_True;
400 TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
401 for (; itrF.More(); itrF.Next()) {
402 if (itrF.Value().IsSame(aFace)) {
403 faceIsNew = Standard_False;
408 edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
412 TopTools_MapOfShape anEdgesToDelete;
413 TopExp_Explorer anEx(aShape,TopAbs_EDGE);
414 for(;anEx.More();anEx.Next()) {
415 Standard_Boolean aC0 = Standard_False;
416 TopoDS_Shape anEdge1 = anEx.Current();
417 if (edgeNaborFaces.IsBound(anEdge1)) {
418 const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
419 if (aList1.Extent()<2) continue;
420 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
421 for (; itr.More(); itr.Next()) {
422 TopoDS_Shape anEdge2 = itr.Key();
423 if(anEdgesToDelete.Contains(anEdge2)) continue;
424 if (anEdge1.IsSame(anEdge2)) continue;
425 const TopTools_ListOfShape& aList2 = itr.Value();
426 // compare lists of the neighbour faces of edge1 and edge2
427 if (aList1.Extent() == aList2.Extent()) {
428 Standard_Integer aMatches = 0;
429 for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
430 for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
431 if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
432 if (aMatches == aList1.Extent()) {
434 builder(++theTag)->Generated(anEdge2);
435 anEdgesToDelete.Add(anEdge2);
439 TopTools_MapIteratorOfMapOfShape itDelete(anEdgesToDelete);
440 for(;itDelete.More();itDelete.Next())
441 edgeNaborFaces.UnBind(itDelete.Key());
442 edgeNaborFaces.UnBind(anEdge1);
445 builder(++theTag)->Generated(anEdge1);
449 void Model_ResultBody::loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, int& theTag)
451 if(theShape->isNull()) return;
452 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
453 TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
454 TopTools_ListOfShape empty;
455 TopExp_Explorer explF(aShape, TopAbs_FACE);
456 for (; explF.More(); explF.Next()) {
457 const TopoDS_Shape& aFace = explF.Current();
458 TopExp_Explorer explV(aFace, TopAbs_VERTEX);
459 for (; explV.More(); explV.Next()) {
460 const TopoDS_Shape& aVertex = explV.Current();
461 if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
462 Standard_Boolean faceIsNew = Standard_True;
463 TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
464 for (; itrF.More(); itrF.Next()) {
465 if (itrF.Value().IsSame(aFace)) {
466 faceIsNew = Standard_False;
471 vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
476 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
477 for (; itr.More(); itr.Next()) {
478 const TopTools_ListOfShape& naborFaces = itr.Value();
479 if (naborFaces.Extent() < 3)
480 builder(++theTag)->Generated(itr.Key());