1 // Copyright (C) 2014-2018 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File: HYDROData_CompleteCalcCase.cxx
20 // Author: Ilya SHCHEKIN
22 #include <HYDROData_CompleteCalcCase.h>
25 #include <HYDROData_SplitToZonesTool.h>
26 #include <HYDROData_SplitShapesGroup.h>
27 #include <BOPTools_AlgoTools3D.hxx>
28 #include <IntTools_Context.hxx>
29 #include <BRepBuilderAPI_MakeFace.hxx>
30 #include <TopTools_HSequenceOfShape.hxx>
31 #include <HYDROData_PolylineXY.h>
33 #include <HYDROData_Region.h>
34 #include <TopTools_IndexedMapOfShape.hxx>
36 #include <HYDROData_Document.h>
37 #include <HYDROData_Tool.h>
39 static void GetModifToOrigHistory(BOPAlgo_Builder& theAlgo, TopTools_IndexedDataMapOfShapeListOfShape& theModifToOrigMap)
41 const TopTools_ListOfShape& args = theAlgo.Arguments();
42 TopTools_IndexedMapOfShape argsAllSh;
43 TopTools_ListOfShape::Iterator it(args);
44 for (;it.More();it.Next())
46 const TopoDS_Shape& aSh = it.Value();
49 TopExp::MapShapes(it.Value(), argsAllSh);
51 for (int i=1;i<=argsAllSh.Extent();i++)
53 const TopoDS_Shape& arg_sh = argsAllSh(i);
54 const TopTools_ListOfShape& modif_ls = theAlgo.Modified(arg_sh);
55 for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
57 const TopoDS_Shape& val = itLS.Value();
58 TopTools_ListOfShape* LS = theModifToOrigMap.ChangeSeek(val);
63 TopTools_ListOfShape newLS;
65 theModifToOrigMap.Add(val, newLS);
72 static bool CheckIntersection(BOPAlgo_Builder& theAlgo, const std::vector<TopoDS_Shape>& SHM,
73 const TopTools_MapOfShape& ShapesToAvoid)
75 TopTools_MapOfShape gmodif_m;
77 for (int i=0; i<SHM.size();i++)
79 TopTools_MapOfShape modif_m;
80 const TopTools_ListOfShape& modif_ls = theAlgo.Modified(SHM[i]);
81 for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
83 const TopoDS_Shape& val = itLS.Value();
84 if (!ShapesToAvoid.Contains(val))
87 calc_ext+=modif_m.Extent();
88 gmodif_m.Unite(modif_m);
89 if (gmodif_m.Extent() < calc_ext)
90 return true; //there is an intersection
95 bool HYDROData_CompleteCalcCase::AddObjects( const Handle(HYDROData_Document)& doc,
96 Handle(HYDROData_CalculationCase)& theCalcCase,
97 NCollection_Sequence<Handle(HYDROData_Entity)> theNewObjects,
98 bool IsUseOrigNamingOfNewRegions,
99 bool& IsIntersectionOfNewObj,
100 NCollection_Sequence<Handle(HYDROData_Region)>& theNewRegions)
102 Handle(HYDROData_PolylineXY) aBndPolyline = theCalcCase->GetBoundaryPolyline();
103 TopoDS_Wire aBndWire;
104 TopoDS_Face aLimFace;
105 bool UseBndPolyline = false;
106 QString CaseName = theCalcCase->GetName();
107 if (!aBndPolyline.IsNull())
109 Handle(TopTools_HSequenceOfShape) aConnectedWires = new TopTools_HSequenceOfShape;
110 int nbWires = aBndPolyline->GetNbConnectedWires(aConnectedWires);
113 aBndWire = TopoDS::Wire(aConnectedWires->Value(1));
114 if(!aBndWire.IsNull())
116 if(HYDROData_SplitToZonesTool::buildLimFace(aBndWire, aLimFace))
118 theNewObjects.Append(theCalcCase->GetBoundaryPolyline());
119 UseBndPolyline = true;
125 BOPAlgo_Builder anAlgo;
126 std::vector<TopoDS_Shape> newShapes;
127 std::vector<Handle(HYDROData_ShapesGroup)> newshapesGroups;
128 NCollection_DataMap<TopoDS_Shape, QStringList, TopTools_ShapeMapHasher> aShToRefObjects;
129 for (int i=1; i<= theNewObjects.Size();i++)
131 Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theNewObjects(i) );
132 if (!aPolyXY.IsNull())
134 TopoDS_Shape aSh = aPolyXY->GetShape();
137 newShapes.push_back(aSh);
138 anAlgo.AddArgument(aSh);
139 QStringList aLS(aPolyXY->GetName());
140 aShToRefObjects.Bind(aSh, aLS);
145 Handle(HYDROData_Object ) anObj = Handle(HYDROData_Object)::DownCast( theNewObjects(i) );
148 TopoDS_Shape aSh = anObj->GetTopShape();
150 HYDROData_SequenceOfObjects groups = anObj->GetGroups();
151 for ( int k=1; k<=groups.Size(); k++ )
153 Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(groups(k));
154 if ( aGroup.IsNull() )
156 newshapesGroups.push_back(aGroup);
161 newShapes.push_back(aSh);
162 anAlgo.AddArgument(aSh);
163 QStringList aLS(anObj->GetName());
164 aShToRefObjects.Bind(aSh, aLS);
170 HYDROData_SequenceOfObjects aRegions = theCalcCase->GetRegions();
171 for ( int i = 1; i <= aRegions.Size(); i++ )
173 Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
174 if ( !aRegion.IsNull() )
176 HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
177 for ( int j = 1; j <= aZones.Size(); j++ )
179 Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZones(j) );
180 TopoDS_Shape aSh = aZone->GetShape();
181 anAlgo.AddArgument(aSh);
182 HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
183 QStringList aRefObjList;
184 for (int k=1;k<=aRefObjects.Size();k++)
185 aRefObjList << aRefObjects(k)->GetName();
186 aShToRefObjects.Bind(aSh, aRefObjList);
192 #if OCC_VERSION_LARGE > 0x07020000
193 if (anAlgo.HasErrors())
196 TopoDS_Shape aRes = anAlgo.Shape();
197 TopTools_MapOfShape UsedFaces;
199 TopTools_IndexedDataMapOfShapeListOfShape theModifToOrigMap;
200 GetModifToOrigHistory(anAlgo, theModifToOrigMap);
205 TopTools_IndexedMapOfShape aResFaces;
206 TopExp::MapShapes(aRes, TopAbs_FACE, aResFaces);
207 Handle(IntTools_Context) aContext = new IntTools_Context();
208 for (int i=1; i<= aResFaces.Extent();i++)
212 TopoDS_Face aF = TopoDS::Face(aResFaces(i));
213 int err = BOPTools_AlgoTools3D::PointInFace(aF, aP3D, aP2D, aContext);
217 TopAbs_State aState = HYDROData_Tool::ComputePointState(gp_XY(aP3D.X(), aP3D.Y()), aLimFace);
218 if (aState == TopAbs_OUT)
220 UsedFaces.Add(aF); //filter out the faces which is out of boundary polyline
226 //check intersection between new objects => if it's present, the combining of zones into region will be depend on ordering
227 IsIntersectionOfNewObj = CheckIntersection(anAlgo, newShapes, UsedFaces);
229 std::vector<std::vector<TopoDS_Shape>> NREGV; //new regions vector (each vector is a region, subvector == zones)
230 for (int i=0;i<newShapes.size();i++)
232 TopoDS_Shape aSh = newShapes[i];
233 if (aSh.ShapeType() != TopAbs_FACE)
235 TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
236 if (newShL.IsEmpty()) //non-modified
238 if (!UsedFaces.Contains(aSh))
240 std::vector<TopoDS_Shape> vect;
242 NREGV.push_back(vect);
248 std::vector<TopoDS_Shape> vect;
249 for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
251 TopoDS_Face nF = TopoDS::Face(it.Value());
252 if (!nF.IsNull() && !UsedFaces.Contains(nF))
258 NREGV.push_back(vect);
262 //iter through already existing zone
263 //substract new zones (NREGV) from old zones
264 for ( int i = 1; i <= aRegions.Size(); i++ )
266 Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
267 if ( !aRegion.IsNull() )
269 HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
270 for ( int j = 1; j <= aZones.Size(); j++ )
272 Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast(aZones(j));
273 TopoDS_Shape aSh = aZone->GetShape();
274 TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
275 if (newShL.IsEmpty() )
277 TopTools_MapOfShape newShM;
278 for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
279 newShM.Add(it.Value());
281 newShM.Subtract(UsedFaces); ///substract UsedFaces from newShM (since they have been taken by regions/object with higher priority)
284 if (newShM.Size() == 0)
287 aRegion->RemoveZone(aZone, true);
289 else if (newShM.Size() == 1)
291 TopoDS_Shape newS = *newShM.cbegin();
292 if (!newS.IsEqual(aSh))
293 aZone->SetShape(newS);
297 QString anOldZoneName = aZone->GetName();
298 HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
299 aRegion->RemoveZone(aZone, false);
300 QStringList aRefObjList;
301 for (int k=1;k<=aRefObjects.Size();k++)
302 aRefObjList << aRefObjects(k)->GetName();
303 for (TopTools_MapIteratorOfMapOfShape it(newShM); it.More(); it.Next())
305 if (it.Value().ShapeType() == TopAbs_FACE)
307 TopoDS_Face F = TopoDS::Face(it.Value());
308 aRegion->addNewZone( doc, anOldZoneName, F, aRefObjList );
316 //create new regions/zones based on NREGV
317 QString aRegsPref = CaseName + "_Reg_";
318 QString aZonesPref = CaseName + "_Zone";
319 for ( int k=0;k<NREGV.size();k++ )
321 const std::vector<TopoDS_Shape>& sh_vec = NREGV[k];
322 Handle(HYDROData_Region) aRegion = theCalcCase->addNewRegion( doc, aRegsPref );
323 theNewRegions.Append(aRegion);
324 QString OrigNameOfRegion = "";
325 for (int i=0;i<sh_vec.size();i++)
327 TopoDS_Face nF = TopoDS::Face(sh_vec[i]);
328 //QString zoneName = aZonesPref;
329 QStringList refObjList;
331 const TopTools_ListOfShape* origLS = theModifToOrigMap.Seek(nF);
334 for (TopTools_ListIteratorOfListOfShape itLS1(*origLS); itLS1.More(); itLS1.Next())
336 const TopoDS_Shape& OrSh = itLS1.Value();
337 const QStringList* names = aShToRefObjects.Seek(OrSh);
339 refObjList.append(*names);
343 Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( doc, aZonesPref, nF, refObjList);
345 //try to get an origial name region (obtained from origin object)
346 if (IsUseOrigNamingOfNewRegions && !refObjList.empty() && OrigNameOfRegion == "")
347 OrigNameOfRegion = refObjList.first();
349 if (OrigNameOfRegion != "")
350 aRegion->SetName(OrigNameOfRegion + "_reg");
354 HYDROData_SequenceOfObjects aSplitGroups = theCalcCase->GetSplitGroups();
356 ///process boundary polyline group (if present)
357 Handle(HYDROData_ShapesGroup) aBndWireGroup;
358 QString BndWireGroupName;
359 TopTools_ListOfShape aNewGroupForBndWireLS;
362 TopTools_IndexedMapOfShape aBndWireEdges;
363 TopTools_IndexedDataMapOfShapeListOfShape aResEdgesToFaces;
364 TopExp::MapShapes(aBndWire, TopAbs_EDGE, aBndWireEdges);
365 TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aResEdgesToFaces);
366 TopTools_IndexedMapOfShape aNewGroupForBndWire;
367 for (int i=1;i<=aBndWireEdges.Extent();i++)
369 TopoDS_Shape E = aBndWireEdges(i);
370 TopTools_ListOfShape aMLS = anAlgo.Modified(E);
373 TopTools_ListIteratorOfListOfShape itLS(aMLS);
374 for (;itLS.More();itLS.Next())
376 TopoDS_Edge E1 = TopoDS::Edge(itLS.Value());
379 if (!aResEdgesToFaces.Contains(E1)) //should contains E since it's a part of aRes
382 if (aResEdgesToFaces.FindFromKey(E1).Extent() > 0)
383 aNewGroupForBndWire.Add(E1);
387 BndWireGroupName = CaseName + "_" + aBndPolyline->GetName();
388 for (int i=1;i<=aNewGroupForBndWire.Extent();i++)
389 aNewGroupForBndWireLS.Append(aNewGroupForBndWire(i));
392 // UPDATE SPLIT GROUPS
393 for ( int k=1; k<=aSplitGroups.Size(); k++ )
395 Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(aSplitGroups(k));
396 if ( aGroup.IsNull() )
399 TopTools_SequenceOfShape GDefSeq, ModifedGDefSeq;
401 if (UseBndPolyline && aGroup->GetName() == BndWireGroupName)
403 aBndWireGroup = aGroup;
407 aGroup->GetShapes( GDefSeq );
408 for (int i=1;i<=GDefSeq.Length();i++)
410 const TopoDS_Shape& CSH = GDefSeq(i);
411 TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
414 TopTools_ListIteratorOfListOfShape itLS(aMLS);
415 for (;itLS.More();itLS.Next())
416 ModifedGDefSeq.Append(itLS.Value());
418 aGroup->SetShapes(ModifedGDefSeq);
423 if (!aBndWireGroup.IsNull()) //modify group
425 aBndWireGroup->SetShapes(aNewGroupForBndWireLS);
429 Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( BndWireGroupName );
430 aSplitGroup->SetShapes(aNewGroupForBndWireLS);
434 ///Add new groups from newly added objects
435 for ( int k=0; k<newshapesGroups.size(); k++ )
437 Handle(HYDROData_ShapesGroup) aGroup = newshapesGroups[k];
438 QString aName = aGroup->GetName();
439 TopTools_SequenceOfShape aSeqSh, ModifedGDefSeq;
440 aGroup->GetShapes(aSeqSh);
441 Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( aName );
442 theCalcCase->AddGeometryGroup( aSplitGroup );
444 for (int i=1;i<=aSeqSh.Length();i++)
446 const TopoDS_Shape& CSH = aSeqSh(i);
447 TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
450 TopTools_ListIteratorOfListOfShape itLS(aMLS);
451 for (;itLS.More();itLS.Next())
452 ModifedGDefSeq.Append(itLS.Value());
454 aSplitGroup->SetShapes(ModifedGDefSeq);