]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_CompleteCalcCase.cxx
Salome HOME
lot 15 :: updated gui
[modules/hydro.git] / src / HYDROData / HYDROData_CompleteCalcCase.cxx
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.
6 //
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.
11 //
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
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 // File:     HYDROData_CompleteCalcCase.cxx
20 // Author:   Ilya SHCHEKIN
21
22 #include <HYDROData_CompleteCalcCase.h>
23
24 #include <gp_Pnt.hxx>
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>
32 #include <TopoDS.hxx>
33 #include <HYDROData_Region.h>
34 #include <TopTools_IndexedMapOfShape.hxx>
35 #include <TopExp.hxx>
36 #include <HYDROData_Document.h>
37 #include <HYDROData_Tool.h>
38
39 static void GetModifToOrigHistory(BOPAlgo_Builder& theAlgo, TopTools_IndexedDataMapOfShapeListOfShape& theModifToOrigMap)
40 {
41   const TopTools_ListOfShape& args = theAlgo.Arguments();
42   TopTools_IndexedMapOfShape argsAllSh;
43   TopTools_ListOfShape::Iterator it(args);
44   for (;it.More();it.Next())
45     TopExp::MapShapes(it.Value(), argsAllSh);
46   for (int i=1;i<=argsAllSh.Extent();i++)
47   {
48     const TopoDS_Shape& arg_sh = argsAllSh(i);
49     const TopTools_ListOfShape& modif_ls = theAlgo.Modified(arg_sh);
50     for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
51     {
52       const TopoDS_Shape& val = itLS.Value();
53       TopTools_ListOfShape* LS = theModifToOrigMap.ChangeSeek(val);
54       if (LS)
55         LS->Append(arg_sh);
56       else
57       {
58         TopTools_ListOfShape newLS;
59         newLS.Append(arg_sh);
60         theModifToOrigMap.Add(val, newLS);
61       }
62     }
63   }
64 }
65
66
67 static bool CheckIntersection(BOPAlgo_Builder& theAlgo, const std::vector<TopoDS_Shape>& SHM,
68   const TopTools_MapOfShape& ShapesToAvoid)
69 {
70   TopTools_MapOfShape gmodif_m;
71   int calc_ext = 0;
72   for (int i=0; i<SHM.size();i++)
73   {
74     TopTools_MapOfShape modif_m;
75     const TopTools_ListOfShape& modif_ls = theAlgo.Modified(SHM[i]);
76     for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
77     {
78       const TopoDS_Shape& val = itLS.Value();
79       if (!ShapesToAvoid.Contains(val))
80         modif_m.Add(val);
81     }
82     calc_ext+=modif_m.Extent();
83     gmodif_m.Unite(modif_m);
84     if (gmodif_m.Extent() < calc_ext)
85       return true; //there is an intersection
86   }
87   return false;
88 }
89
90 bool HYDROData_CompleteCalcCase::AddObjects( const Handle(HYDROData_Document)& doc,
91                                              Handle(HYDROData_CalculationCase)& theCalcCase, 
92                                              NCollection_Sequence<Handle(HYDROData_Entity)> theNewObjects,
93                                              bool IsUseOrigNamingOfNewRegions,
94                                              bool& IsIntersectionOfNewObj,
95                                              NCollection_Sequence<Handle(HYDROData_Region)>& theNewRegions)
96 {
97   Handle(HYDROData_PolylineXY) aBndPolyline = theCalcCase->GetBoundaryPolyline();        
98   TopoDS_Wire aBndWire;
99   TopoDS_Face aLimFace;
100   bool UseBndPolyline = false;
101   QString CaseName = theCalcCase->GetName();
102   if (!aBndPolyline.IsNull())
103   {
104     Handle(TopTools_HSequenceOfShape) aConnectedWires = new TopTools_HSequenceOfShape;
105     int nbWires = aBndPolyline->GetNbConnectedWires(aConnectedWires);
106     if (nbWires > 0)
107     {
108       aBndWire = TopoDS::Wire(aConnectedWires->Value(1));
109       if(!aBndWire.IsNull()) 
110       {      
111         if(HYDROData_SplitToZonesTool::buildLimFace(aBndWire, aLimFace)) 
112         {
113           theNewObjects.Append(theCalcCase->GetBoundaryPolyline());
114           UseBndPolyline = true;
115         }
116       }
117     }
118   }
119
120   BOPAlgo_Builder anAlgo;
121   std::vector<TopoDS_Shape> newShapes;
122   std::vector<Handle(HYDROData_ShapesGroup)> newshapesGroups;
123   NCollection_DataMap<TopoDS_Shape, QStringList, TopTools_ShapeMapHasher> aShToRefObjects;
124   for (int i=1; i<= theNewObjects.Size();i++)
125   {
126     Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theNewObjects(i) );
127     if (!aPolyXY.IsNull())
128     {
129       TopoDS_Shape aSh = aPolyXY->GetShape();
130       newShapes.push_back(aSh);
131       anAlgo.AddArgument(aSh);
132       QStringList aLS(aPolyXY->GetName());
133       aShToRefObjects.Bind(aSh, aLS);
134     }
135     else 
136     {
137       Handle(HYDROData_Object ) anObj = Handle(HYDROData_Object)::DownCast( theNewObjects(i) );
138       if (!anObj.IsNull())
139       {
140         TopoDS_Shape aSh = anObj->GetTopShape();
141         //
142         HYDROData_SequenceOfObjects groups = anObj->GetGroups();
143         for ( int k=1; k<=groups.Size(); k++ )
144         {
145           Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(groups(k));
146           if ( aGroup.IsNull() )
147             continue;
148           newshapesGroups.push_back(aGroup);
149         }
150         //
151         newShapes.push_back(aSh);
152         anAlgo.AddArgument(aSh);
153         QStringList aLS(anObj->GetName());
154         aShToRefObjects.Bind(aSh, aLS);
155       }
156     }
157   }
158
159   HYDROData_SequenceOfObjects aRegions = theCalcCase->GetRegions();
160   for ( int i = 1; i <= aRegions.Size(); i++ )
161   {
162     Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
163     if ( !aRegion.IsNull() )
164     {
165       HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
166       for ( int j = 1; j <= aZones.Size(); j++ )
167       {
168         Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZones(j) );
169         TopoDS_Shape aSh = aZone->GetShape();
170         anAlgo.AddArgument(aSh);
171         HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
172         QStringList aRefObjList;
173         for (int k=1;k<=aRefObjects.Size();k++)
174           aRefObjList << aRefObjects(k)->GetName();
175         aShToRefObjects.Bind(aSh, aRefObjList);
176       }
177     }
178   }
179
180   anAlgo.Perform(); 
181 #if OCC_VERSION_LARGE > 0x07020000
182   if (anAlgo.HasErrors())
183     return false;
184 #endif
185   TopoDS_Shape aRes = anAlgo.Shape();        
186   TopTools_MapOfShape UsedFaces;
187   ///
188   TopTools_IndexedDataMapOfShapeListOfShape theModifToOrigMap;
189   GetModifToOrigHistory(anAlgo, theModifToOrigMap);
190
191   //
192   if (UseBndPolyline)
193   {
194     TopTools_IndexedMapOfShape aResFaces;
195     TopExp::MapShapes(aRes, TopAbs_FACE, aResFaces);
196     Handle(IntTools_Context) aContext = new IntTools_Context();
197     for (int i=1; i<= aResFaces.Extent();i++)
198     {
199       gp_Pnt aP3D;
200       gp_Pnt2d aP2D;
201       TopoDS_Face aF = TopoDS::Face(aResFaces(i));
202       int err = BOPTools_AlgoTools3D::PointInFace(aF, aP3D, aP2D, aContext);
203       if (err)
204         continue;
205
206       TopAbs_State aState = HYDROData_Tool::ComputePointState(gp_XY(aP3D.X(), aP3D.Y()), aLimFace);
207       if (aState == TopAbs_OUT)
208       {
209         UsedFaces.Add(aF); //filter out the faces which is out of boundary polyline
210       }
211     }
212   }
213
214   ///
215   //check intersection between new objects => if it's present, the combining of zones into region will be depend on ordering
216   IsIntersectionOfNewObj = CheckIntersection(anAlgo, newShapes, UsedFaces);
217   //
218   std::vector<std::vector<TopoDS_Shape>> NREGV; //new regions vector (each vector is a region, subvector == zones) 
219   for (int i=0;i<newShapes.size();i++)
220   {
221     TopoDS_Shape aSh = newShapes[i];
222     if (aSh.ShapeType() != TopAbs_FACE)
223       continue;
224     TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
225     if (newShL.IsEmpty()) //non-modified
226     {
227       if (!UsedFaces.Contains(aSh))
228       {
229         std::vector<TopoDS_Shape> vect;
230         vect.push_back(aSh);
231         NREGV.push_back(vect);
232         UsedFaces.Add(aSh);
233       }
234     }
235     else //was modified
236     {
237       std::vector<TopoDS_Shape> vect;
238       for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
239       {
240         TopoDS_Face nF = TopoDS::Face(it.Value());
241         if (!nF.IsNull() && !UsedFaces.Contains(nF))
242         {                                         
243           vect.push_back(nF);
244           UsedFaces.Add(nF);
245         }
246       }    
247       NREGV.push_back(vect);
248     }
249   }
250   
251   //iter through already existing zone
252   //substract new zones (NREGV) from old zones
253   for ( int i = 1; i <= aRegions.Size(); i++ )
254   {
255     Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
256     if ( !aRegion.IsNull() )
257     {
258       HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
259       for ( int j = 1; j <= aZones.Size(); j++ )
260       {
261         Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast(aZones(j));
262         TopoDS_Shape aSh = aZone->GetShape();
263         TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
264         if (newShL.IsEmpty() )
265           newShL.Append(aSh);
266         TopTools_MapOfShape newShM;
267         for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
268           newShM.Add(it.Value());
269         //
270         newShM.Subtract(UsedFaces); ///substract UsedFaces from newShM (since they have been taken by regions/object with higher priority)
271         //
272
273         if (newShM.Size() == 0)
274         {
275           //remove zone
276           aRegion->RemoveZone(aZone, true);
277         }
278         else if (newShM.Size() == 1)
279         {
280           TopoDS_Shape newS = *newShM.cbegin();
281           if (!newS.IsEqual(aSh))
282             aZone->SetShape(newS);
283         }
284         else ///newShM > 1
285         {
286           QString anOldZoneName = aZone->GetName();                
287           HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
288           aRegion->RemoveZone(aZone, false);
289           QStringList aRefObjList;
290           for (int k=1;k<=aRefObjects.Size();k++)
291             aRefObjList << aRefObjects(k)->GetName();
292           for (TopTools_MapIteratorOfMapOfShape it(newShM); it.More(); it.Next())
293           {
294             if (it.Value().ShapeType() == TopAbs_FACE)
295             {
296               TopoDS_Face F = TopoDS::Face(it.Value());
297               aRegion->addNewZone( doc, anOldZoneName, F, aRefObjList );
298             }
299           }
300         }
301       }
302     }
303   }
304
305   //create new regions/zones based on NREGV
306   QString aRegsPref = CaseName + "_Reg_";
307   QString aZonesPref = CaseName + "_Zone";
308   for ( int k=0;k<NREGV.size();k++ )
309   {
310     const std::vector<TopoDS_Shape>& sh_vec = NREGV[k];
311     Handle(HYDROData_Region) aRegion = theCalcCase->addNewRegion( doc, aRegsPref );
312     theNewRegions.Append(aRegion);
313     QString OrigNameOfRegion = "";
314     for (int i=0;i<sh_vec.size();i++)
315     {
316       TopoDS_Face nF = TopoDS::Face(sh_vec[i]);
317       //QString zoneName = aZonesPref;
318       QStringList refObjList;
319       //
320       const TopTools_ListOfShape* origLS = theModifToOrigMap.Seek(nF);
321       if (origLS)
322       {
323         for (TopTools_ListIteratorOfListOfShape itLS1(*origLS); itLS1.More(); itLS1.Next())
324         {
325           const TopoDS_Shape& OrSh = itLS1.Value();
326           const QStringList* names = aShToRefObjects.Seek(OrSh);
327           if (names)
328             refObjList.append(*names);
329         }
330       }
331       //
332       Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( doc, aZonesPref, nF, refObjList);
333
334       //try to get an origial name region (obtained from origin object)
335       if (IsUseOrigNamingOfNewRegions && !refObjList.empty() && OrigNameOfRegion == "") 
336         OrigNameOfRegion = refObjList.first();
337     }
338     if (OrigNameOfRegion != "")
339       aRegion->SetName(OrigNameOfRegion + "_reg");
340   }
341
342   //GROUPS
343   HYDROData_SequenceOfObjects aSplitGroups = theCalcCase->GetSplitGroups();
344
345   ///process boundary polyline group (if present)
346   Handle(HYDROData_ShapesGroup) aBndWireGroup;
347   QString BndWireGroupName;
348   TopTools_ListOfShape aNewGroupForBndWireLS;
349   if (UseBndPolyline)
350   {
351     TopTools_IndexedMapOfShape aBndWireEdges;
352     TopTools_IndexedDataMapOfShapeListOfShape aResEdgesToFaces;
353     TopExp::MapShapes(aBndWire, TopAbs_EDGE, aBndWireEdges);
354     TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aResEdgesToFaces);
355     TopTools_IndexedMapOfShape aNewGroupForBndWire;
356     for (int i=1;i<=aBndWireEdges.Extent();i++)
357     {
358       TopoDS_Shape E = aBndWireEdges(i);
359       TopTools_ListOfShape aMLS = anAlgo.Modified(E);
360       if (aMLS.IsEmpty())
361         aMLS.Append(E);
362       TopTools_ListIteratorOfListOfShape itLS(aMLS);
363       for (;itLS.More();itLS.Next())
364       {
365         TopoDS_Edge E1 = TopoDS::Edge(itLS.Value());
366         if (E1.IsNull())
367           continue;
368         if (!aResEdgesToFaces.Contains(E1)) //should contains E since it's a part of aRes
369           continue;
370         //skip free edges
371         if (aResEdgesToFaces.FindFromKey(E1).Extent() > 0) 
372           aNewGroupForBndWire.Add(E1);
373       }
374     }
375     //
376     BndWireGroupName = CaseName + "_" + aBndPolyline->GetName();
377     for (int i=1;i<=aNewGroupForBndWire.Extent();i++)
378       aNewGroupForBndWireLS.Append(aNewGroupForBndWire(i));
379   }
380
381   // UPDATE SPLIT GROUPS       
382   for ( int k=1; k<=aSplitGroups.Size(); k++ )
383   {
384     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(aSplitGroups(k));
385     if ( aGroup.IsNull() )
386       continue;
387
388     TopTools_SequenceOfShape GDefSeq, ModifedGDefSeq;
389
390     if (UseBndPolyline && aGroup->GetName() == BndWireGroupName)
391     {
392       aBndWireGroup = aGroup;
393       continue;
394     }
395
396     aGroup->GetShapes( GDefSeq );
397     for (int i=1;i<=GDefSeq.Length();i++)
398     {
399       const TopoDS_Shape& CSH = GDefSeq(i); 
400       TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
401       if (aMLS.IsEmpty())
402         aMLS.Append(CSH);
403       TopTools_ListIteratorOfListOfShape itLS(aMLS);
404       for (;itLS.More();itLS.Next())
405         ModifedGDefSeq.Append(itLS.Value());                     
406     }
407     aGroup->SetShapes(ModifedGDefSeq);
408   }
409
410   if (UseBndPolyline)
411   {
412     if (!aBndWireGroup.IsNull()) //modify group
413     {
414       aBndWireGroup->SetShapes(aNewGroupForBndWireLS);
415     }
416     else //add new group
417     {
418       Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( BndWireGroupName );
419       aSplitGroup->SetShapes(aNewGroupForBndWireLS);
420     }
421   }
422
423   ///Add new groups from newly added objects
424   for ( int k=0; k<newshapesGroups.size(); k++ )
425   {
426     Handle(HYDROData_ShapesGroup) aGroup = newshapesGroups[k];
427     QString aName = aGroup->GetName();
428     TopTools_SequenceOfShape aSeqSh, ModifedGDefSeq;
429     aGroup->GetShapes(aSeqSh);
430     Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( aName );
431     theCalcCase->AddGeometryGroup( aSplitGroup );
432
433     for (int i=1;i<=aSeqSh.Length();i++)
434     {
435       const TopoDS_Shape& CSH = aSeqSh(i); 
436       TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
437       if (aMLS.IsEmpty())
438         aMLS.Append(CSH);
439       TopTools_ListIteratorOfListOfShape itLS(aMLS);
440       for (;itLS.More();itLS.Next())
441         ModifedGDefSeq.Append(itLS.Value());                     
442     }
443     aSplitGroup->SetShapes(ModifedGDefSeq);
444   }
445
446   return true;
447 }