X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_PolylineOperator.cxx;h=07387a6e9d0cf085fba22e6aca6e2ee26cee61fc;hb=0f4c16e80e5c9160fb6e240e3f09b151701a1e5b;hp=61c835f6123d389986b42d23e185f3cc4ea43910;hpb=18bf2fdae8933e8a31ca58f36b6dceb7a4a8cf42;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_PolylineOperator.cxx b/src/HYDROData/HYDROData_PolylineOperator.cxx index 61c835f6..07387a6e 100644 --- a/src/HYDROData/HYDROData_PolylineOperator.cxx +++ b/src/HYDROData/HYDROData_PolylineOperator.cxx @@ -17,8 +17,46 @@ // #include +#include +#include +#include + +#ifndef LIGHT_MODE +#include +#endif + +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _DEVDEBUG_ +#include "HYDRO_trace.hxx" +#include +#include template void append( std::vector& theList, const std::vector& theList2 ) { @@ -33,105 +71,456 @@ template void append( std::vector& theList, const std::vector& th theList[i] = theList2[j]; } - -bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_PolylineXY )& thePolyline, - const gp_Pnt2d& thePoint ) const +bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, + const Handle( HYDROData_PolylineXY )& thePolyline, + const gp_Pnt2d& thePoint, + double theTolerance ) const { + if (thePolyline.IsNull()) + { + return false; + } + std::vector aPointsList( 1 ); aPointsList[0] = thePoint; - std::vector aCurves = GetCurves( thePolyline ); + std::vector aCurves; + GetWires(thePolyline, aCurves); bool isOK = true; for( int i=0, n=aCurves.size(); i aCurvesList = Split( aCurves[i], aPointsList ); - bool isLocalOK = CreatePolylines( aCurvesList ); + std::vector aCurvesList; + Split( aCurves[i], thePoint, theTolerance, aCurvesList ); + bool isLocalOK = CreatePolylines( theDoc, thePolyline, aCurvesList, true ); isOK = isOK && isLocalOK; } return isOK; } -bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_PolylineXY )& thePolyline, - const Handle( HYDROData_PolylineXY )& theTool ) const +bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, + const Handle( HYDROData_PolylineXY )& thePolyline, + const Handle( HYDROData_PolylineXY )& theTool, + double theTolerance, + bool& theIsIntersected) const { - std::vector aCurves = GetCurves( thePolyline ); - std::vector aToolCurves = GetCurves( theTool ); - bool isOK = true; - for( int i=0, n=aCurves.size(); i aPointsList = Intersection( aCurves[i], aToolCurves[j] ); - std::vector aCurvesList = Split( aCurves[i], aPointsList ); - bool isLocalOK = CreatePolylines( aCurvesList ); - isOK = isOK && isLocalOK; - } - return isOK; + if (thePolyline.IsNull() || theTool.IsNull()) + { + return false; + } + + HYDROData_SequenceOfObjects aSeq; + aSeq.Append( theTool ); + return split( theDoc, thePolyline, aSeq, theTolerance, -1, theIsIntersected); } -bool HYDROData_PolylineOperator::Split( const HYDROData_SequenceOfObjects& thePolylines ) +bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, + const HYDROData_SequenceOfObjects& thePolylines, + double theTolerance ) { int f = thePolylines.Lower(), l = thePolylines.Upper(); - bool isOK = true; - std::vector anAllCurves; for( int i=f; i<=l; i++ ) { Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) ); - std::vector aCurves = GetCurves( aPolyline ); - append( anAllCurves, aCurves ); + bool isIntersected; + if( !split( theDoc, aPolyline, thePolylines, theTolerance, i, isIntersected) ) + return false; } + return true; +} + +bool HYDROData_PolylineOperator::Merge( const Handle( HYDROData_Document )& theDoc, + const QString& theName, + const HYDROData_SequenceOfObjects& thePolylines, + bool isConnectByNewSegment, + double theTolerance ) +{ + Handle( HYDROData_PolylineXY ) aNewPolyline = + Handle( HYDROData_PolylineXY )::DownCast( theDoc->CreateObject( KIND_POLYLINEXY ) ); + int ins =0; - for( int i=0, n=anAllCurves.size(); i aCompletePointsList; - for( int j=0; j aSectNames; + NCollection_Sequence aSectTypes; + NCollection_Sequence aSectClosures; + aPolyline->GetSections( aSectNames, aSectTypes, aSectClosures ); + + for ( int i = 1, n = aSectNames.Size(); i <= n; ++i ) { - if( i==j ) - continue; - std::vector aPointsList = Intersection( anAllCurves[i], anAllCurves[j] ); - append( aCompletePointsList, aPointsList ); + const TCollection_AsciiString& aSectName = aSectNames.Value( i ) + "_" + ip; + const HYDROData_PolylineXY::SectionType& aSectType = aSectTypes.Value( i ); + bool aSectClosure = aSectClosures.Value( i ); + aNewPolyline->AddSection(aSectName, aSectType, aSectClosure); + HYDROData_PolylineXY::PointsList aPointsList = aPolyline->GetPoints(i-1, false); + aNewPolyline->SetPoints(ins++, aPointsList); } - std::vector aCurvesList = Split( anAllCurves[i], aCompletePointsList ); - bool isLocalOK = CreatePolylines( aCurvesList ); - isOK = isOK && isLocalOK; } - return isOK; + QString aName = theName; + if( aName.isEmpty() ) + { + aName = "merged"; + int anIndex = 1; + QString aNewName = aName + "_" + QString::number(anIndex); + while (!theDoc->FindObjectByName(aNewName).IsNull()) // the object with such a name is not found + { + anIndex++; + aNewName = aName + "_" + QString::number(anIndex); + } + aName = aNewName; + } + + aNewPolyline->SetName(aName); + aNewPolyline->Update(); + return true; } -bool HYDROData_PolylineOperator::Merge( const HYDROData_SequenceOfObjects& thePolylines ) +bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theDoc, + const Handle( HYDROData_PolylineXY )& thePolyline, + const HYDROData_SequenceOfObjects& theTools, + double theTolerance, + int theIgnoreIndex, + bool& theIsIntersected) const { - //TODO + theIsIntersected = false; + + if (thePolyline.IsNull()) + { + return false; + } + + std::vector aCurves; + GetWires(thePolyline, aCurves); + std::vector aToolCurves; + for( int i=theTools.Lower(), n=theTools.Upper(); i<=n; i++ ) + if( i!=theIgnoreIndex ) + { + Handle( HYDROData_PolylineXY ) aToolPolyline = + Handle( HYDROData_PolylineXY )::DownCast( theTools.Value( i ) ); + if (!aToolPolyline.IsNull()) + { + std::vector aTCurves; + GetWires(aToolPolyline, aTCurves); + append( aToolCurves, aTCurves); + } + } + + if (aToolCurves.empty()) + { + return false; + } + + const int aPSCount = aCurves.size(); + const int aTSCount = aToolCurves.size(); + std::vector aResult; + for (int aPSI = 0; aPSI < aPSCount; ++aPSI) + { + HYDROData_TopoCurve aCurve; + //DEBTRACE("Initialize curve " << aPSI); + if (!aCurve.Initialize(aCurves[aPSI])) + { + continue; + } + + std::deque > aParams; + for (int aTSI = 0; aTSI < aTSCount; ++aTSI) + { + aCurve.Intersect(aToolCurves[aTSI], aParams); + } + + std::deque aSplitCurves; + theIsIntersected |= aCurve.Cut(aParams, aSplitCurves); + std::deque::const_iterator aCIt = + aSplitCurves.begin(); + std::deque::const_iterator aLastCIt = + aSplitCurves.end(); + for (int iw=0; aCIt != aLastCIt; ++aCIt, iw++) + { + /*std::stringstream brepName; + brepName << "theSplitWire_"; + brepName << iw; + brepName << ".brep"; + BRepTools::Write(aCIt->Wire() , brepName.str().c_str() );*/ + aResult.push_back(aCIt->Wire()); + } + } + + CreatePolylines( theDoc, thePolyline, aResult, true ); return true; } -std::vector HYDROData_PolylineOperator::GetCurves( const Handle( HYDROData_PolylineXY )& thePolyline ) +void HYDROData_PolylineOperator::GetWires( + const Handle( HYDROData_PolylineXY )& thePolyline, + std::vector& theWires) { - std::vector aResult; - //TODO - return aResult; + TopoDS_Shape aShape = thePolyline->GetShape(); + if( aShape.ShapeType()==TopAbs_WIRE ) + { + theWires.push_back( TopoDS::Wire( aShape ) ); + } + else + { + TopExp_Explorer anExp( aShape, TopAbs_WIRE ); + for( ; anExp.More(); anExp.Next() ) + { + theWires.push_back( TopoDS::Wire( anExp.Current() ) ); + } + } } -std::vector HYDROData_PolylineOperator::Intersection( const Handle( Geom2d_Curve )& theCurve, - const Handle( Geom2d_Curve )& theTool ) +void HYDROData_PolylineOperator::Split( + const TopoDS_Wire& theWire, + const gp_Pnt2d& thePoint, + double theTolerance, + std::vector& theWires) { - std::vector aResult; - //TODO - return aResult; + HYDROData_TopoCurve aCurve; + if (!aCurve.Initialize(theWire)) + { + theWires.push_back(theWire); + return; + } + + const gp_XYZ aP(thePoint.X(), thePoint.Y(), 0); + std::list::const_iterator aEPos; + double aParam; + aCurve.Project(aP, aEPos, aParam); + HYDROData_TopoCurve aCurve1, aCurve2; + aCurve.Cut(aEPos, aParam, aCurve1, aCurve2); + theWires.push_back(aCurve1.Wire()); + if (!aCurve2.IsEmpty()) + { + theWires.push_back(aCurve2.Wire()); + } } -std::vector HYDROData_PolylineOperator::Split( const Handle( Geom2d_Curve )& theCurve, - const std::vector& thePoints ) +bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc, + const Handle( HYDROData_PolylineXY )& theOldPolyline, + const std::vector& theShapes, + bool isUseIndices ) { - std::vector aResult; - //TODO - return aResult; + if( theDoc.IsNull() ) + return false; + + if ( theOldPolyline.IsNull() ) + return false; + const QString& theNamePrefix = theOldPolyline->GetName(); + const QColor& theColor = theOldPolyline->GetWireColor(); + + int n = theShapes.size(); + //DEBTRACE("theShapes.size() "<< n); + int anIndex = 1; + for( int i=0; iCreateObject( KIND_POLYLINEXY ) ); + if( aPolyline.IsNull() ) + return false; + + aPolyline->ImportShape(theShapes[i], false, theOldPolyline, false); + + if( isUseIndices ) + { + QString aNewName = theNamePrefix + "_" + QString::number( anIndex ); + while( !theDoc->FindObjectByName( aNewName ).IsNull() ) // the object with such a name is not found + { + anIndex++; + aNewName = theNamePrefix + "_" + QString::number( anIndex ); + } + aPolyline->SetName( aNewName ); + } + else + { + aPolyline->SetName( theNamePrefix ); + } + + if( theColor.isValid() ) + aPolyline->SetWireColor( theColor ); + } + return true; } -bool HYDROData_PolylineOperator::CreatePolylines( const std::vector& theCurves ) +double HYDROData_PolylineOperator::ReduceDeflection( + const double theDeflection, + HYDROData_TopoCurve& theCurve, + int& thePieceCount) { - int n = theCurves.size(); - for( int i=0; i aPs; + if (!theCurve.ValuesInKnots(aPs)) + { + return -1; + } + + Handle(TColgp_HArray1OfPnt) aPs2 = new TColgp_HArray1OfPnt(1, aPs.size()); + { + std::list::const_iterator aLastPIt = aPs.end(); + std::list::const_iterator aPIt = aPs.begin(); + for (int aPN = 1; aPIt != aLastPIt; ++aPN, ++aPIt) + { + aPs2->SetValue(aPN, *aPIt); + } + } + Handle(Geom_BSplineCurve) aBSpline2; + const bool isClosed = theCurve.IsClosed(); +#ifndef LIGHT_MODE + if (!CurveCreator_Utils::constructBSpline(aPs2, isClosed, aBSpline2)) +#endif + { + return -1; + } + + // Calculate the piece deflections. + std::deque aSqDefls; + double aMaxSqDefl = 0; + std::list& aEdges = theCurve.Edges(); + std::list::const_iterator aLastEIt = aEdges.end(); + { + std::list::const_iterator aEIt = aEdges.begin(); + for (int aPrevKCount = 0; aEIt != aLastEIt; ++aEIt) + { + TopLoc_Location aLoc; + double aParams[2]; + Handle(Geom_BSplineCurve) aBSpline = Handle(Geom_BSplineCurve)::DownCast( + BRep_Tool::Curve(*aEIt, aLoc, aParams[0], aParams[1])); + const int aKCount = aBSpline->NbKnots(); + for (int aKN = 1; aKN < aKCount; ++aKN) + { + const double aParam = + (aBSpline->Knot(aKN) + aBSpline->Knot(aKN + 1)) * 0.5; + const double aParam2 = (aBSpline2->Knot(aPrevKCount + aKN) + + aBSpline2->Knot(aPrevKCount + aKN + 1)) * 0.5; + const double aSqDefl = Abs(aBSpline->Value(aParam). + SquareDistance(aBSpline2->Value(aParam2))); + aSqDefls.push_back(aSqDefl); + if (aMaxSqDefl < aSqDefl) + { + aMaxSqDefl = aSqDefl; + } + } + aPrevKCount += aKCount - 1; + } + } + + // Check whether the reducing is necessary. + const double aMaxDefl = Sqrt(aMaxSqDefl); + if (aMaxDefl <= theDeflection) + { + return aMaxDefl; + } + + // Reduce the deflections. + const double aThresSqDefl = + Max(aMaxSqDefl * 0.25, theDeflection * theDeflection); + std::list::iterator aEIt = aEdges.begin(); + std::deque::const_iterator aSqDIt = aSqDefls.begin(); + thePieceCount = 0; + for (; aEIt != aLastEIt; ++aEIt) { - TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge2d( theCurves[i] ).Edge(); - //TODO + TopLoc_Location aLoc; + double aParams[2]; + Handle(Geom_BSplineCurve) aBSpline = Handle(Geom_BSplineCurve)::DownCast( + BRep_Tool::Curve(*aEIt, aLoc, aParams[0], aParams[1])); + Handle(Geom_BSplineCurve) aBSpline2 = + Handle(Geom_BSplineCurve)::DownCast(aBSpline->Copy()); + const int aKCount = aBSpline->NbKnots(); + for (int aKN = 1; aKN < aKCount; ++aSqDIt, ++aKN) + { + if (*aSqDIt > aThresSqDefl) + { + aBSpline2->InsertKnot( + (aBSpline->Knot(aKN) + aBSpline->Knot(aKN + 1)) * 0.5); + } + } + TopoDS_Edge aEdge; + BRep_Builder().MakeEdge(aEdge, aBSpline2, Precision::Confusion()); + BRep_Builder().Add(aEdge, TopExp::FirstVertex(*aEIt)); + BRep_Builder().Add(aEdge, TopExp::LastVertex(*aEIt)); + thePieceCount += aBSpline2->NbKnots() - 1; + *aEIt = aEdge; } + return aMaxDefl; +} + +bool HYDROData_PolylineOperator::Extract( const Handle(HYDROData_Document)& theDocument, + const Handle(HYDROData_Object)& theObject ) +{ + if( theObject.IsNull() || theDocument.IsNull() ) + return false; + + QList aBoundShapes; + QStringList aBoundNames; + QMap aNameToShMap; + + theObject->GetBoundaries( aBoundShapes, aBoundNames ); + + for( int i=0, n=aBoundShapes.size(); i 1) + { + BRepLib_MakeWire WM; + WM.Add(LSE); + if (WM.IsDone()) + aShapeOut = WM.Wire(); + else + continue; + } + else continue; + + Handle( HYDROData_PolylineXY ) aPolyline = + Handle( HYDROData_PolylineXY )::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) ); + + if( aPolyline.IsNull() ) + return false; + + aPolyline->SetShape( aShapeOut ); + + int anIndex = 0; + QString aName = K; + while( !theDocument->FindObjectByName( aName ).IsNull() ) + { + anIndex++; + aName = K + "_" + QString::number( anIndex ); + } + aPolyline->SetName( aName ); + } + return true; }