--- /dev/null
+// Copyright (C) 2014-2018 EDF-R&D
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File: HYDROData_CompleteCalcCase.cxx
+// Author: Ilya SHCHEKIN
+
+#include <HYDROData_CompleteCalcCase.h>
+
+#include <gp_Pnt.hxx>
+#include <HYDROData_SplitToZonesTool.h>
+#include <HYDROData_SplitShapesGroup.h>
+#include <BOPTools_AlgoTools3D.hxx>
+#include <IntTools_Context.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <TopTools_HSequenceOfShape.hxx>
+#include <HYDROData_PolylineXY.h>
+#include <TopoDS.hxx>
+#include <HYDROData_Region.h>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopExp.hxx>
+#include <HYDROData_Document.h>
+#include <HYDROData_Tool.h>
+
+static void GetModifToOrigHistory(BOPAlgo_Builder& theAlgo, TopTools_IndexedDataMapOfShapeListOfShape& theModifToOrigMap)
+{
+ const TopTools_ListOfShape& args = theAlgo.Arguments();
+ TopTools_IndexedMapOfShape argsAllSh;
+ TopTools_ListOfShape::Iterator it(args);
+ for (;it.More();it.Next())
+ TopExp::MapShapes(it.Value(), argsAllSh);
+ for (int i=1;i<=argsAllSh.Extent();i++)
+ {
+ const TopoDS_Shape& arg_sh = argsAllSh(i);
+ const TopTools_ListOfShape& modif_ls = theAlgo.Modified(arg_sh);
+ for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
+ {
+ const TopoDS_Shape& val = itLS.Value();
+ TopTools_ListOfShape* LS = theModifToOrigMap.ChangeSeek(val);
+ if (LS)
+ LS->Append(arg_sh);
+ else
+ {
+ TopTools_ListOfShape newLS;
+ newLS.Append(arg_sh);
+ theModifToOrigMap.Add(val, newLS);
+ }
+ }
+ }
+}
+
+
+static bool CheckIntersection(BOPAlgo_Builder& theAlgo, const std::vector<TopoDS_Shape>& SHM,
+ const TopTools_MapOfShape& ShapesToAvoid)
+{
+ TopTools_MapOfShape gmodif_m;
+ int calc_ext = 0;
+ for (int i=0; i<SHM.size();i++)
+ {
+ TopTools_MapOfShape modif_m;
+ const TopTools_ListOfShape& modif_ls = theAlgo.Modified(SHM[i]);
+ for (TopTools_ListIteratorOfListOfShape itLS(modif_ls); itLS.More(); itLS.Next())
+ {
+ const TopoDS_Shape& val = itLS.Value();
+ if (!ShapesToAvoid.Contains(val))
+ modif_m.Add(val);
+ }
+ calc_ext+=modif_m.Extent();
+ gmodif_m.Unite(modif_m);
+ if (gmodif_m.Extent() < calc_ext)
+ return true; //there is an intersection
+ }
+ return false;
+}
+
+bool HYDROData_CompleteCalcCase::AddObjects( const Handle(HYDROData_Document)& doc,
+ Handle(HYDROData_CalculationCase)& theCalcCase,
+ NCollection_Sequence<Handle(HYDROData_Entity)> theNewObjects,
+ bool& IsIntersectionOfNewObj)
+{
+ Handle(HYDROData_PolylineXY) aBndPolyline = theCalcCase->GetBoundaryPolyline();
+ TopoDS_Wire aBndWire;
+ TopoDS_Face aLimFace;
+ bool UseBndPolyline = false;
+ QString CaseName = theCalcCase->GetName();
+ if (!aBndPolyline.IsNull())
+ {
+ Handle(TopTools_HSequenceOfShape) aConnectedWires = new TopTools_HSequenceOfShape;
+ int nbWires = aBndPolyline->GetNbConnectedWires(aConnectedWires);
+ if (nbWires > 0)
+ {
+ aBndWire = TopoDS::Wire(aConnectedWires->Value(1));
+ if(!aBndWire.IsNull())
+ {
+ if(HYDROData_SplitToZonesTool::buildLimFace(aBndWire, aLimFace))
+ {
+ theNewObjects.Append(theCalcCase->GetBoundaryPolyline());
+ UseBndPolyline = true;
+ }
+ }
+ }
+ }
+
+ BOPAlgo_Builder anAlgo;
+ std::vector<TopoDS_Shape> newShapes;
+ std::vector<Handle(HYDROData_ShapesGroup)> newshapesGroups;
+ NCollection_DataMap<TopoDS_Shape, QStringList, TopTools_ShapeMapHasher> aShToRefObjects;
+ for (int i=1; i<= theNewObjects.Size();i++)
+ {
+ Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theNewObjects(i) );
+ if (!aPolyXY.IsNull())
+ {
+ TopoDS_Shape aSh = aPolyXY->GetShape();
+ newShapes.push_back(aSh);
+ anAlgo.AddArgument(aSh);
+ QStringList aLS(aPolyXY->GetName());
+ aShToRefObjects.Bind(aSh, aLS);
+ }
+ else
+ {
+ Handle(HYDROData_Object ) anObj = Handle(HYDROData_Object)::DownCast( theNewObjects(i) );
+ if (!anObj.IsNull())
+ {
+ TopoDS_Shape aSh = anObj->GetTopShape();
+ //
+ HYDROData_SequenceOfObjects groups = anObj->GetGroups();
+ for ( int k=1; k<=groups.Size(); k++ )
+ {
+ Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(groups(k));
+ if ( aGroup.IsNull() )
+ continue;
+ newshapesGroups.push_back(aGroup);
+ }
+ //
+ newShapes.push_back(aSh);
+ anAlgo.AddArgument(aSh);
+ QStringList aLS(anObj->GetName());
+ aShToRefObjects.Bind(aSh, aLS);
+ }
+ }
+ }
+
+ HYDROData_SequenceOfObjects aRegions = theCalcCase->GetRegions();
+ for ( int i = 1; i <= aRegions.Size(); i++ )
+ {
+ Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
+ if ( !aRegion.IsNull() )
+ {
+ HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
+ for ( int j = 1; j <= aZones.Size(); j++ )
+ {
+ Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZones(j) );
+ TopoDS_Shape aSh = aZone->GetShape();
+ anAlgo.AddArgument(aSh);
+ HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
+ QStringList aRefObjList;
+ for (int k=1;k<=aRefObjects.Size();k++)
+ aRefObjList << aRefObjects(k)->GetName();
+ aShToRefObjects.Bind(aSh, aRefObjList);
+ }
+ }
+ }
+
+ anAlgo.Perform();
+#if OCC_VERSION_LARGE > 0x07020000
+ if (anAlgo.HasErrors())
+ return false;
+#endif
+ TopoDS_Shape aRes = anAlgo.Shape();
+ TopTools_MapOfShape UsedFaces;
+ ///
+ TopTools_IndexedDataMapOfShapeListOfShape theModifToOrigMap;
+ GetModifToOrigHistory(anAlgo, theModifToOrigMap);
+
+ //
+ if (UseBndPolyline)
+ {
+ TopTools_IndexedMapOfShape aResFaces;
+ TopExp::MapShapes(aRes, TopAbs_FACE, aResFaces);
+ Handle(IntTools_Context) aContext = new IntTools_Context();
+ for (int i=1; i<= aResFaces.Extent();i++)
+ {
+ gp_Pnt aP3D;
+ gp_Pnt2d aP2D;
+ TopoDS_Face aF = TopoDS::Face(aResFaces(i));
+ int err = BOPTools_AlgoTools3D::PointInFace(aF, aP3D, aP2D, aContext);
+ if (err)
+ continue;
+
+ TopAbs_State aState = HYDROData_Tool::ComputePointState(gp_XY(aP3D.X(), aP3D.Y()), aLimFace);
+ if (aState == TopAbs_OUT)
+ {
+ UsedFaces.Add(aF); //filter out the faces which is out of boundary polyline
+ }
+ }
+ }
+
+ ///
+ //check intersection between new objects => if it's present, the combining of zones into region will be depend on ordering
+ IsIntersectionOfNewObj = CheckIntersection(anAlgo, newShapes, UsedFaces);
+ //
+ std::vector<std::vector<TopoDS_Shape>> NREGV; //new regions vector (each vector is a region, subvector == zones)
+ for (int i=0;i<newShapes.size();i++)
+ {
+ TopoDS_Shape aSh = newShapes[i];
+ if (aSh.ShapeType() != TopAbs_FACE)
+ continue;
+ TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
+ if (newShL.IsEmpty()) //non-modified
+ {
+ if (!UsedFaces.Contains(aSh))
+ {
+ std::vector<TopoDS_Shape> vect;
+ vect.push_back(aSh);
+ NREGV.push_back(vect);
+ UsedFaces.Add(aSh);
+ }
+ }
+ else //was modified
+ {
+ std::vector<TopoDS_Shape> vect;
+ for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
+ {
+ TopoDS_Face nF = TopoDS::Face(it.Value());
+ if (!nF.IsNull() && !UsedFaces.Contains(nF))
+ {
+ vect.push_back(nF);
+ UsedFaces.Add(nF);
+ }
+ }
+ NREGV.push_back(vect);
+ }
+ }
+
+ //iter through already existing zone
+ //substract new zones (NREGV) from old zones
+ for ( int i = 1; i <= aRegions.Size(); i++ )
+ {
+ Handle(HYDROData_Region) aRegion = Handle(HYDROData_Region)::DownCast( aRegions(i) );
+ if ( !aRegion.IsNull() )
+ {
+ HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
+ for ( int j = 1; j <= aZones.Size(); j++ )
+ {
+ Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast(aZones(j));
+ TopoDS_Shape aSh = aZone->GetShape();
+ TopTools_ListOfShape newShL = anAlgo.Modified(aSh);
+ if (newShL.IsEmpty() )
+ newShL.Append(aSh);
+ TopTools_MapOfShape newShM;
+ for (TopTools_ListIteratorOfListOfShape it(newShL); it.More(); it.Next())
+ newShM.Add(it.Value());
+ //
+ newShM.Subtract(UsedFaces); ///substract UsedFaces from newShM (since they have been taken by regions/object with higher priority)
+ //
+
+ if (newShM.Size() == 0)
+ {
+ //remove zone
+ aRegion->RemoveZone(aZone, true);
+ }
+ else if (newShM.Size() == 1)
+ {
+ TopoDS_Shape newS = *newShM.cbegin();
+ if (!newS.IsEqual(aSh))
+ aZone->SetShape(newS);
+ }
+ else ///newShM > 1
+ {
+ QString anOldZoneName = aZone->GetName();
+ HYDROData_SequenceOfObjects aRefObjects = aZone->GetObjects();
+ aRegion->RemoveZone(aZone, false);
+ QStringList aRefObjList;
+ for (int k=1;k<=aRefObjects.Size();k++)
+ aRefObjList << aRefObjects(k)->GetName();
+ for (TopTools_MapIteratorOfMapOfShape it(newShM); it.More(); it.Next())
+ {
+ if (it.Value().ShapeType() == TopAbs_FACE)
+ {
+ TopoDS_Face F = TopoDS::Face(it.Value());
+ aRegion->addNewZone( doc, anOldZoneName, F, aRefObjList );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //create new regions/zones based on NREGV
+ QString aRegsPref = CaseName + "_Reg_";
+ QString aZonesPref = CaseName + "_Zone";
+ for ( int k=0;k<NREGV.size();k++ )
+ {
+ const std::vector<TopoDS_Shape>& sh_vec = NREGV[k];
+ Handle(HYDROData_Region) aRegion = theCalcCase->addNewRegion( doc, aRegsPref );
+ for (int i=0;i<sh_vec.size();i++)
+ {
+ TopoDS_Face nF = TopoDS::Face(sh_vec[i]);
+ QString zoneName = aZonesPref;
+ QStringList refObjList;
+ //
+ const TopTools_ListOfShape* origLS = theModifToOrigMap.Seek(nF);
+ if (origLS)
+ {
+ for (TopTools_ListIteratorOfListOfShape itLS1(*origLS); itLS1.More(); itLS1.Next())
+ {
+ const TopoDS_Shape& OrSh = itLS1.Value();
+ const QStringList* names = aShToRefObjects.Seek(OrSh);
+ if (names)
+ refObjList.append(*names);
+ }
+ }
+ //
+ Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( doc, aZonesPref, nF, refObjList);
+ }
+ }
+
+ //GROUPS
+ HYDROData_SequenceOfObjects aSplitGroups = theCalcCase->GetSplitGroups();
+
+ ///process boundary polyline group (if present)
+ Handle(HYDROData_ShapesGroup) aBndWireGroup;
+ QString BndWireGroupName;
+ TopTools_ListOfShape aNewGroupForBndWireLS;
+ if (UseBndPolyline)
+ {
+ TopTools_IndexedMapOfShape aBndWireEdges;
+ TopTools_IndexedDataMapOfShapeListOfShape aResEdgesToFaces;
+ TopExp::MapShapes(aBndWire, TopAbs_EDGE, aBndWireEdges);
+ TopExp::MapShapesAndAncestors(aRes, TopAbs_EDGE, TopAbs_FACE, aResEdgesToFaces);
+ TopTools_IndexedMapOfShape aNewGroupForBndWire;
+ for (int i=1;i<=aBndWireEdges.Extent();i++)
+ {
+ TopoDS_Shape E = aBndWireEdges(i);
+ TopTools_ListOfShape aMLS = anAlgo.Modified(E);
+ if (aMLS.IsEmpty())
+ aMLS.Append(E);
+ TopTools_ListIteratorOfListOfShape itLS(aMLS);
+ for (;itLS.More();itLS.Next())
+ {
+ TopoDS_Edge E1 = TopoDS::Edge(itLS.Value());
+ if (E1.IsNull())
+ continue;
+ if (!aResEdgesToFaces.Contains(E1)) //should contains E since it's a part of aRes
+ continue;
+ //skip free edges
+ if (aResEdgesToFaces.FindFromKey(E1).Extent() > 0)
+ aNewGroupForBndWire.Add(E1);
+ }
+ }
+ //
+ BndWireGroupName = CaseName + "_" + aBndPolyline->GetName();
+ for (int i=1;i<=aNewGroupForBndWire.Extent();i++)
+ aNewGroupForBndWireLS.Append(aNewGroupForBndWire(i));
+ }
+
+ // UPDATE SPLIT GROUPS
+ for ( int k=1; k<=aSplitGroups.Size(); k++ )
+ {
+ Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast(aSplitGroups(k));
+ if ( aGroup.IsNull() )
+ continue;
+
+ TopTools_SequenceOfShape GDefSeq, ModifedGDefSeq;
+
+ if (UseBndPolyline && aGroup->GetName() == BndWireGroupName)
+ {
+ aBndWireGroup = aGroup;
+ continue;
+ }
+
+ aGroup->GetShapes( GDefSeq );
+ for (int i=1;i<=GDefSeq.Length();i++)
+ {
+ const TopoDS_Shape& CSH = GDefSeq(i);
+ TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
+ if (aMLS.IsEmpty())
+ aMLS.Append(CSH);
+ TopTools_ListIteratorOfListOfShape itLS(aMLS);
+ for (;itLS.More();itLS.Next())
+ ModifedGDefSeq.Append(itLS.Value());
+ }
+ aGroup->SetShapes(ModifedGDefSeq);
+ }
+
+ if (UseBndPolyline)
+ {
+ if (!aBndWireGroup.IsNull()) //modify group
+ {
+ aBndWireGroup->SetShapes(aNewGroupForBndWireLS);
+ }
+ else //add new group
+ {
+ Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( BndWireGroupName );
+ aSplitGroup->SetShapes(aNewGroupForBndWireLS);
+ }
+ }
+
+ ///Add new groups from newly added objects
+ for ( int k=0; k<newshapesGroups.size(); k++ )
+ {
+ Handle(HYDROData_ShapesGroup) aGroup = newshapesGroups[k];
+ QString aName = aGroup->GetName();
+ TopTools_SequenceOfShape aSeqSh, ModifedGDefSeq;
+ aGroup->GetShapes(aSeqSh);
+ Handle(HYDROData_SplitShapesGroup) aSplitGroup = theCalcCase->addNewSplitGroup( aName );
+
+ for (int i=1;i<=aSeqSh.Length();i++)
+ {
+ const TopoDS_Shape& CSH = aSeqSh(i);
+ TopTools_ListOfShape aMLS = anAlgo.Modified(CSH);
+ if (aMLS.IsEmpty())
+ aMLS.Append(CSH);
+ TopTools_ListIteratorOfListOfShape itLS(aMLS);
+ for (;itLS.More();itLS.Next())
+ ModifedGDefSeq.Append(itLS.Value());
+ }
+ aSplitGroup->SetShapes(ModifedGDefSeq);
+ }
+ return true;
+}
#include <QApplication>
#include <QKeySequence>
#include <QShortcut>
+#include <BRep_Builder.hxx>
+#include <TopoDS.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopExp.hxx>
+#include <TopoDS.hxx>
-HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
+HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit, bool IsComplete )
: HYDROGUI_Operation( theModule ),
myIsEdit( theIsEdit ),
myActiveViewManager( NULL ),
myPreviewViewManager( NULL ),
myShowGeomObjects( true ),
myShowLandCoverMap( false ),
- myShowZones( false )
+ myShowZones( false ),
+ myDenyIncExcl (IsComplete)
{
setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
}
aPanel->setObjectName( anObjectName );
aPanel->setEditedObject( myEditedObject );
+ myIncObjAtStart.clear();
+ myIncObjAtStart = aPanel->getGeometryObjects(false);
+
setGeomObjectsVisible( true );
createPreview( false );
return;
QStringList aSelectedList = aPanel->getSelectedGeomObjects();
+
+ if (myDenyIncExcl)
+ {
+ QSet<QString> selMap = aSelectedList.toSet();
+ myIncObjAtStart.toVector();
+ for (int i=0;i<myIncObjAtStart.size();i++)
+ {
+ QString str = myIncObjAtStart[i]->GetName();
+ if (selMap.contains(str))
+ return;
+ }
+ }
+
+
if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
return;
bool HYDROGUI_CalculationOp::confirmRegionsChange() const
{
+
// Check if the case is already modified or not
bool isConfirmed = myEditedObject->IsMustBeUpdated( HYDROData_Entity::Geom_2d );
+
if ( !isConfirmed )
{
+
+ if (myDenyIncExcl)
+ {
+ SUIT_MessageBox::information(module()->getApp()->desktop(),
+ tr( "REGIONS_CHANGED" ),
+ tr( "COMPLETE_OP_WILL_BE_PERFORMED" ));
+ return true;
+ }
+
// If not modified check if the case has already defined regions with zones
HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
if ( aSeq.Length() > 0 )
aMsg );
}
}
-
+#include <HYDROData_CompleteCalcCase.h>
void HYDROGUI_CalculationOp::onNext( const int theIndex )
{
if( theIndex==1 )
if ( myEditedObject->IsMustBeUpdated( HYDROData_Entity::Geom_All ) )
{
myShowZones = true;
- myEditedObject->Update();
+
+ if (myDenyIncExcl)
+ {
+ QList<Handle(HYDROData_Entity)> ibcludedGeomObj = aPanel->getGeometryObjects(false);
+ //QSet<Handle(HYDROData_Entity)> includedObjAtStartSet = myIncObjAtStart.toSet();
+ NCollection_Sequence<Handle(HYDROData_Entity)> theNewObjects;
+ foreach (Handle(HYDROData_Entity) obj, ibcludedGeomObj)
+ {
+ if (!myIncObjAtStart.contains(obj))
+ theNewObjects.Append(obj);
+ }
+
+ bool is_int = false;
+ HYDROData_CompleteCalcCase::AddObjects(doc(), myEditedObject, theNewObjects, is_int);
+ if (is_int)
+ SUIT_MessageBox::information(module()->getApp()->desktop(),
+ tr( "COMPLETE_CASE" ),
+ tr( "There is an intersection(s) between new objects. result will be depend on order" ));
+
+ myEditedObject->ClearChanged();
+ }
+ else
+ myEditedObject->Update();
AssignDefaultZonesColors();