X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_PolylineOperator.cxx;h=acec03bc92e29fc11ce8ba12797f2a41b99bdb54;hb=f165c19739951b4490e4c86df56b603935fc0d16;hp=dff7ce3eaadc044141048e6117066b4d3b0d6a6b;hpb=55fe0d2de7e15a256965d71280dc61fd58863d7e;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_PolylineOperator.cxx b/src/HYDROData/HYDROData_PolylineOperator.cxx index dff7ce3e..acec03bc 100644 --- a/src/HYDROData/HYDROData_PolylineOperator.cxx +++ b/src/HYDROData/HYDROData_PolylineOperator.cxx @@ -18,10 +18,23 @@ #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include template void append( std::vector& theList, const std::vector& theList2 ) { @@ -36,139 +49,728 @@ template void append( std::vector& theList, const std::vector& th theList[i] = theList2[j]; } +static TopoDS_Edge ReplaceVertex( + const TopoDS_Edge& theEdge, Standard_Integer theVertexIndex) +{ + TopoDS_Vertex aVertices[] = + {TopExp::FirstVertex(theEdge), TopExp::LastVertex(theEdge)}; + const TopAbs_Orientation aOrient = theEdge.Orientation(); + if (aOrient == TopAbs_REVERSED) + { + theVertexIndex ^= 1; + } + aVertices[theVertexIndex].EmptyCopy(); + aVertices[0].Orientation(TopAbs_FORWARD); + aVertices[1].Orientation(TopAbs_REVERSED); + TopoDS_Edge aFE = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD)); + TopoDS_Edge aNewEdge = + ShapeBuild_Edge().CopyReplaceVertices(aFE, aVertices[0], aVertices[1]); + return TopoDS::Edge(aNewEdge.Oriented(aOrient)); +} + +static Standard_Boolean WireToCurve( + const TopoDS_Wire& theWire, + NCollection_Vector& theEdges, + Standard_Boolean& theIsClosed) +{ + TopTools_IndexedDataMapOfShapeListOfShape aVertexToEdges; + TopExp::MapShapesAndAncestors(theWire, + TopAbs_VERTEX, TopAbs_EDGE, aVertexToEdges); + const Standard_Integer aVCount = aVertexToEdges.Extent(); + if (aVCount == 0) + { + return Standard_False; + } + + { + Standard_Integer aEndCount = 0; + for (Standard_Integer aVN = 1; aVN <= aVCount; ++aVN) + { + const Standard_Integer aEdgeCount = + aVertexToEdges.FindFromIndex(aVN).Extent(); + if (aEdgeCount == 1) + { + ++aEndCount; + } + if (aEdgeCount > 2) + { + return Standard_False; + } + } + theIsClosed = (aEndCount == 0); + if (!theIsClosed && aEndCount != 2) + { + return Standard_False; + } + } + + Standard_Integer aVN = 1; + if (!theIsClosed) + { + while (aVN <= aVCount && + aVertexToEdges.FindFromIndex(aVN).Extent() == 2) + { + ++aVN; + } + } + + TopTools_ListOfShape* aEdges = &aVertexToEdges.ChangeFromIndex(aVN); + while (!aEdges->IsEmpty()) + { + const TopoDS_Edge aEdge = TopoDS::Edge(aEdges->First()); + aEdges->RemoveFirst(); + theEdges.Append(aEdge); + Standard_Integer aVN2 = + aVertexToEdges.FindIndex(TopExp::FirstVertex(aEdge)); + if (aVN2 == aVN) + { + aVN2 = aVertexToEdges.FindIndex(TopExp::LastVertex(aEdge)); + } + aVN = aVN2; + + aEdges = &aVertexToEdges.ChangeFromIndex(aVN2); + if (aEdges->First().IsEqual(aEdge)) + { + aEdges->RemoveFirst(); + } + else + { + const TopoDS_Edge aEdge = TopoDS::Edge(aEdges->First()); + aEdges->Clear(); + aEdges->Append(aEdge); + } + } + return (!theIsClosed && theEdges.Size() == aVCount - 1) || + (theIsClosed && theEdges.Size() == aVCount); +} + +static void CurveToWire( + const NCollection_Vector& theEdges, TopoDS_Wire& theWire) +{ + BRep_Builder aBulder; + aBulder.MakeWire(theWire); + NCollection_Vector::Iterator aEIt(theEdges); + for (; aEIt.More(); aEIt.Next()) + { + aBulder.Add(theWire, aEIt.Value()); + } +} + +static void CurveToWire( + const NCollection_Vector& theEdges1, + const NCollection_Vector& theEdges2, + TopoDS_Wire& theWire) +{ + BRep_Builder aBulder; + aBulder.MakeWire(theWire); + const NCollection_Vector* aEdges[] = {&theEdges1, &theEdges2}; + for (Standard_Integer aEI = 0; aEI < 2; ++aEI) + { + NCollection_Vector::Iterator aEIt(*aEdges[aEI]); + for (; aEIt.More(); aEIt.Next()) + { + aBulder.Add(theWire, aEIt.Value()); + } + } +} + +static Standard_Real ProjectPointToCurve( + const gp_Pnt& thePoint, + const Adaptor3d_Curve& theCurve, + Standard_Real& theParameter) +{ + Extrema_ExtPC aAlgo(thePoint, theCurve); + Standard_Integer aMinEN = -2; + Standard_Real aMinSqDist = DBL_MAX; + if (aAlgo.IsDone()) + { + const Standard_Integer aECount = aAlgo.NbExt(); + for (Standard_Integer aEN = 1; aEN <= aECount; ++aEN) + { + const gp_Pnt& aP = aAlgo.Point(aEN).Value(); + const Standard_Real aSqDist = thePoint.SquareDistance(aP); + if (aMinSqDist > aSqDist) + { + aMinSqDist = aSqDist; + aMinEN = aEN; + } + } + } + + const Standard_Real aParams[] = + {theCurve.FirstParameter(), theCurve.LastParameter()}; + const gp_Pnt aEnds[] = + {theCurve.Value(aParams[0]), theCurve.Value(aParams[1])}; + const Standard_Real aSqDists[] = + {thePoint.SquareDistance(aEnds[0]), thePoint.SquareDistance(aEnds[1])}; + for (Standard_Integer aEI = 0; aEI < 2; ++aEI) + { + if (aMinSqDist > aSqDists[aEI]) + { + aMinSqDist = aSqDists[aEI]; + aMinEN = -aEI; + } + } + + if (aMinEN <= 0) + { + theParameter = aParams[-aMinEN]; + return aMinSqDist; + } + + const Extrema_POnCurv& aPOnC = aAlgo.Point(aMinEN); + const gp_Pnt& aPoint = aPOnC.Value(); + theParameter = aPOnC.Parameter(); + for (Standard_Integer aEI = 0; aEI < 2; ++aEI) + { + if (Abs(theParameter - aParams[aEI]) < Precision::PConfusion() || + aPoint.SquareDistance(aEnds[aEI]) < Precision::SquareConfusion()) + { + theParameter = aParams[aEI]; + } + } + return aMinSqDist; +} + +static Standard_Real ProjectPointToEdge( + const gp_Pnt& thePoint, + const TopoDS_Edge& theEdge, + Standard_Real& theParameter) +{ + return ProjectPointToCurve(thePoint, BRepAdaptor_Curve(theEdge), theParameter); +} + +static void SplitCurveByPoint( + const NCollection_Vector& theEdges, + const Standard_Integer theEdgeIndex, + const Standard_Real theParameter, + NCollection_Vector& theEdges1, + NCollection_Vector& theEdges2) +{ + for (Standard_Integer aEI = 0; aEI < theEdgeIndex; ++aEI) + { + theEdges1.Append(theEdges(aEI)); + } + + const TopoDS_Edge& aEdge = theEdges(theEdgeIndex); + BRepAdaptor_Curve aCurve(aEdge); + Standard_Integer aParamI = -1; + const Standard_Real aEdgeEndParams[] = + {aCurve.FirstParameter(), aCurve.LastParameter()}; + if (Abs(theParameter - aEdgeEndParams[0]) < Precision::PConfusion()) + { + aParamI = 0; + } + else if (Abs(theParameter - aEdgeEndParams[1]) < Precision::PConfusion()) + { + aParamI = 1; + } + + const TopAbs_Orientation aOrient = aEdge.Orientation(); + if (aOrient == TopAbs_REVERSED) + { + aParamI ^= 1; + } + + NCollection_Vector* aEdges = &theEdges2; + const Standard_Integer aECount = theEdges.Size(); + if (aParamI == 0) + { + aEdges = (theEdgeIndex == 0) ? &theEdges1 : &theEdges2; + aEdges->Append(ReplaceVertex(aEdge, 0)); + } + else if (aParamI == 1) + { + theEdges1.Append(ReplaceVertex(aEdge, 1)); + } + else + { + TopoDS_Edge aFE = TopoDS::Edge(aEdge.Oriented(TopAbs_FORWARD)); + ShapeAnalysis_TransferParametersProj aSATPP(aFE, TopoDS_Face()); + aSATPP.SetMaxTolerance(Precision::Confusion()); + TopoDS_Vertex aSplitV1, aSplitV2; + BRep_Builder().MakeVertex( + aSplitV1, aCurve.Value(theParameter), Precision::Confusion()); + BRep_Builder().MakeVertex( + aSplitV2, aCurve.Value(theParameter), Precision::Confusion()); + TopoDS_Edge aEParts[] = { + ShapeBuild_Edge().CopyReplaceVertices(aFE, TopoDS_Vertex(), + TopoDS::Vertex(aSplitV1.Oriented(TopAbs_REVERSED))), + ShapeBuild_Edge().CopyReplaceVertices(aFE, aSplitV2, TopoDS_Vertex())}; + ShapeBuild_Edge().CopyPCurves(aEParts[0], aFE); + ShapeBuild_Edge().CopyPCurves(aEParts[1], aFE); + BRep_Builder().SameRange(aEParts[0], Standard_False); + BRep_Builder().SameRange(aEParts[1], Standard_False); + BRep_Builder().SameParameter(aEParts[0], Standard_False); + BRep_Builder().SameParameter(aEParts[1], Standard_False); + aSATPP.TransferRange(aEParts[0], + aEdgeEndParams[0], theParameter, Standard_False); + aSATPP.TransferRange(aEParts[1], + theParameter, aEdgeEndParams[1], Standard_False); + aEParts[0].Orientation(aOrient); + aEParts[1].Orientation(aOrient); + + const Standard_Integer aFirstPI = (aOrient != TopAbs_REVERSED) ? 0 : 1; + theEdges1.Append(aEParts[aFirstPI]); + theEdges2.Append(aEParts[1 - aFirstPI]); + } + for (Standard_Integer aEI = theEdgeIndex + 1; aEI < aECount; ++aEI) + { + aEdges->Append(theEdges(aEI)); + } +} + +static void SplitCurveByPoints( + const NCollection_Vector& theCurve, + const NCollection_Vector >& theParameters, + NCollection_Vector >& theSplittedCurves) +{ + NCollection_Vector aCurves[3]; + aCurves[0] = theCurve; + Standard_Integer aCI = 0, aEI = 0; + NCollection_Vector::Iterator aEIt(theCurve); + for (NCollection_Vector >::Iterator + aPLIt(theParameters); aPLIt.More(); ++aEI, aEIt.Next(), aPLIt.Next()) + { + const Standard_Boolean isForward = + (aEIt.Value().Orientation() != TopAbs_REVERSED); + for (NCollection_Sequence::Iterator + aPIt(aPLIt.Value(), isForward); aPIt.More(); aPIt.Next()) + { + const Standard_Integer aCI1 = (aCI + 1) % 3, aCI2 = (aCI + 2) % 3; + SplitCurveByPoint(aCurves[aCI], aEI, + aPIt.Value(), aCurves[aCI1], aCurves[aCI2]); + if (!aCurves[aCI2].IsEmpty()) + { + theSplittedCurves.Append(aCurves[aCI1]); + aCurves[aCI].Clear(); + aCI = aCI2; + aEI = 0; + } + aCurves[aCI1].Clear(); + } + } + theSplittedCurves.Append(aCurves[aCI]); +} + +static Standard_Integer AppendIntersectionPoint( + const Adaptor3d_Curve& theCurve, + const Standard_Real theParameter, + NCollection_Sequence& theParameters) +{ + // Check the coincidence. + NCollection_Sequence aEndParams; + aEndParams.Append(theCurve.FirstParameter()); + aEndParams.Append(theCurve.LastParameter()); + NCollection_Sequence* aParams[] = + {&theParameters, &aEndParams}; + const gp_Pnt aPoint = theCurve.Value(theParameter); + for (Standard_Integer aLI = 0; aLI < 2; ++aLI) + { + NCollection_Sequence::Iterator aPIt(*aParams[aLI]); + for (Standard_Integer aPI = 0; aPIt.More(); aPIt.Next(), ++aPI) + { + const Standard_Real aParam = aPIt.Value(); + if (Abs(theParameter - aParam) < Precision::PConfusion() || + aPoint.SquareDistance(theCurve.Value(aParam)) <= + Precision::SquareConfusion()) + { + Standard_Integer aIntCount = 0; + if (aLI != 0) + { + if (aPI == 0) + { + theParameters.Prepend(aEndParams.First()); + } + else + { + theParameters.Append(aEndParams.Last()); + } + ++aIntCount; + } + return aIntCount; + } + } + } + + // Calculate the position to insert. + NCollection_Sequence::Iterator aPIt(theParameters); + if (aPIt.More() && aPIt.Value() < theParameter) + { + NCollection_Sequence::Iterator aPIt2 = aPIt; + aPIt2.Next(); + for (; aPIt2.More() && aPIt2.Value() < theParameter; + aPIt.Next(), aPIt2.Next()); + theParameters.InsertAfter(aPIt, theParameter); + } + else + { + theParameters.Prepend(theParameter); + } + return 1; +} + +static Standard_Integer IntersectEdge( + const TopoDS_Edge& theEdge1, + const TopoDS_Edge& theEdge2, + NCollection_Sequence& theParameters) +{ + // Process the ends. + Standard_Integer aIntCount = 0; + BRepAdaptor_Curve aCurve1 = BRepAdaptor_Curve(theEdge1); + BRepAdaptor_Curve aCurve2 = BRepAdaptor_Curve(theEdge2); + const gp_Pnt aEndPs[] = {aCurve2.Value(aCurve2.FirstParameter()), + aCurve2.Value(aCurve2.LastParameter())}; + for (Standard_Integer aPI = 0; aPI < 2; ++aPI) + { + Standard_Real aParameter; + if (ProjectPointToCurve(aEndPs[aPI], aCurve1, aParameter) <= + Precision::SquareConfusion()) + { + AppendIntersectionPoint(aCurve1, aParameter, theParameters); + } + } + + // Process the internal extrema. + Extrema_ExtCC aAlgo(aCurve1, aCurve2); + if (aAlgo.IsDone()) + { + const Standard_Integer aECount = aAlgo.NbExt(); + for (Standard_Integer aEN = 1; aEN <= aECount; ++aEN) + { + Extrema_POnCurv aP1, aP2; + aAlgo.Points(aEN, aP1, aP2); + if (aP1.Value().SquareDistance(aP2.Value()) <= + Precision::SquareConfusion()) + { + AppendIntersectionPoint(aCurve1, aP1.Parameter(), theParameters); + } + } + } + return aIntCount; +} + +static Standard_Integer IntersectCurve( + const NCollection_Vector& theEdges, + const TopoDS_Wire& theWire, + NCollection_Vector >& theParameters) +{ + Standard_Integer aIntCount = 0; + const Standard_Integer aECount1 = theEdges.Size(); + for (Standard_Integer aEI1 = 0; aEI1 < aECount1; ++aEI1) + { + const TopoDS_Edge& aEdge1 = theEdges(aEI1); + TopExp_Explorer aEIt2(theWire, TopAbs_EDGE); + for (; aEIt2.More(); aEIt2.Next()) + { + aIntCount += IntersectEdge(aEdge1, + TopoDS::Edge(aEIt2.Current()), theParameters(aEI1)); + } + } + return aIntCount; +} bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, - const TCollection_AsciiString& theNamePrefix, const Handle( HYDROData_PolylineXY )& thePolyline, - const gp_Pnt2d& thePoint ) const + const gp_Pnt2d& thePoint, + double theTolerance ) const { std::vector aPointsList( 1 ); aPointsList[0] = thePoint; - std::vector aCurves = GetCurves( thePolyline ); + std::vector aCurves = GetWires( thePolyline ); bool isOK = true; for( int i=0, n=aCurves.size(); i aCurvesList = Split( aCurves[i], aPointsList ); - bool isLocalOK = CreatePolylines( theDoc, theNamePrefix, aCurvesList ); + std::vector aCurvesList = Split( aCurves[i], thePoint, theTolerance ); + bool isLocalOK = CreatePolylines( theDoc, thePolyline->GetName(), aCurvesList, true ); isOK = isOK && isLocalOK; } return isOK; } bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, - const TCollection_AsciiString& theNamePrefix, - const Handle( HYDROData_PolylineXY )& thePolyline, - const Handle( HYDROData_PolylineXY )& theTool ) const + const Handle( HYDROData_PolylineXY )& thePolyline, + const Handle( HYDROData_PolylineXY )& theTool, + double theTolerance ) 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( theDoc, theNamePrefix, aCurvesList ); - isOK = isOK && isLocalOK; - } - return isOK; + HYDROData_SequenceOfObjects aSeq; + aSeq.Append( theTool ); + return split( theDoc, thePolyline, aSeq, theTolerance, -1 ); } bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc, - const TCollection_AsciiString& theNamePrefix, - const HYDROData_SequenceOfObjects& thePolylines ) + 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 ); + if( !split( theDoc, aPolyline, thePolylines, theTolerance, i ) ) + return false; } + return true; +} - for( int i=0, n=anAllCurves.size(); i aCompletePointsList; - for( int j=0; j aPointsList = Intersection( anAllCurves[i], anAllCurves[j] ); - append( aCompletePointsList, aPointsList ); - } - std::vector aCurvesList = Split( anAllCurves[i], aCompletePointsList ); - bool isLocalOK = CreatePolylines( theDoc, theNamePrefix, aCurvesList ); - isOK = isOK && isLocalOK; + Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) ); + std::vector aCurves = GetWires( aPolyline ); + for( int j=0, m=aCurves.size(); j aShapes( 1 ); + aShapes[0] = aMergedPolyline; + CreatePolylines( theDoc, theName, aShapes, false ); + + return true; } -bool HYDROData_PolylineOperator::Merge( const Handle( HYDROData_Document )& theDoc, - const TCollection_AsciiString& theName, - const HYDROData_SequenceOfObjects& thePolylines, - bool isConnectByNewSegment ) +bool HYDROData_PolylineOperator::Merge( TopoDS_Shape& theShape, const TopoDS_Wire& theWire, + bool isConnectByNewSegment, double theTolerance ) { //TODO + return true; +} - TopoDS_Shape aMergedPolyline; +bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theDoc, + const Handle( HYDROData_PolylineXY )& thePolyline, + const HYDROData_SequenceOfObjects& theTools, + double theTolerance, + int theIgnoreIndex ) const +{ + std::vector aCurves = GetWires( thePolyline ); + 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 ) ); + append( aToolCurves, GetWires( aToolPolyline ) ); + } - Handle( HYDROData_PolylineXY ) aPolyline = - Handle( HYDROData_PolylineXY )::DownCast( theDoc->CreateObject( KIND_POLYLINEXY ) ); - if( aPolyline.IsNull() ) - return false; + const int aPSCount = aCurves.size(); + const int aTSCount = aToolCurves.size(); + std::vector aResult; + for (int aPSI = 0; aPSI < aPSCount; ++aPSI) + { + NCollection_Vector aCurve; + Standard_Boolean aIsClosed; + if (!WireToCurve(aCurves[aPSI], aCurve, aIsClosed)) + { + continue; + } - aPolyline->SetShape( aMergedPolyline ); - //TODO: set name + NCollection_Vector > aParams; + aParams.SetValue(aPSCount - 1, NCollection_Sequence()); + for (int aTSI = 0; aTSI < aTSCount; ++aTSI) + { + IntersectCurve(aCurve, aToolCurves[aTSI], aParams); + } + + NCollection_Vector > aSplittedCurves; + SplitCurveByPoints(aCurve, aParams, aSplittedCurves); + + Standard_Boolean aIsClosed2 = aIsClosed; + if (aIsClosed2) + { + const NCollection_Sequence& aPs = aParams.First(); + if (!aPs.IsEmpty()) + { + const TopoDS_Edge& aEdge = aCurve.First(); + const Standard_Boolean isForward = + (aEdge.Orientation() != TopAbs_REVERSED); + const Standard_Real aParam = isForward ? aPs.First() : aPs.Last(); + BRepAdaptor_Curve aCurve(aEdge); + const Standard_Real aEndParam = isForward ? + aCurve.FirstParameter() : aCurve.LastParameter(); + aIsClosed2 = (Abs(aParam - aEndParam) > Precision::PConfusion()); + } + + if (aIsClosed2) + { + const NCollection_Sequence& aPs = aParams.Last(); + if (!aPs.IsEmpty()) + { + const TopoDS_Edge& aEdge = aCurve.Last(); + const Standard_Boolean isForward = + (aEdge.Orientation() != TopAbs_REVERSED); + const Standard_Real aParam = isForward ? aPs.Last() : aPs.First(); + BRepAdaptor_Curve aCurve(aEdge); + const Standard_Real aEndParam = isForward ? + aCurve.LastParameter() : aCurve.FirstParameter(); + aIsClosed2 = (Abs(aParam - aEndParam) >= Precision::PConfusion()); + } + } + } + + Standard_Integer aFSCI = 0, aLSCI = aSplittedCurves.Size() - 1; + if (aIsClosed2 && aFSCI < aLSCI) + { + TopoDS_Wire aWire; + CurveToWire(aSplittedCurves(aLSCI), aSplittedCurves(aFSCI), aWire); + aResult.push_back(aWire); + ++aFSCI; + --aLSCI; + } + + for (Standard_Integer aSCI = aFSCI; aSCI <= aLSCI; ++aSCI) + { + TopoDS_Wire aWire; + CurveToWire(aSplittedCurves(aSCI), aWire); + aResult.push_back(aWire); + } + } + CreatePolylines(theDoc, thePolyline->GetName(), aResult, true); return true; } -std::vector HYDROData_PolylineOperator::GetCurves( const Handle( HYDROData_PolylineXY )& thePolyline ) +std::vector HYDROData_PolylineOperator::GetWires( const Handle( HYDROData_PolylineXY )& thePolyline ) { - std::vector aResult; - //TODO + std::vector aResult; + + TopoDS_Shape aShape = thePolyline->GetShape(); + + if( aShape.ShapeType()==TopAbs_WIRE ) + { + aResult.push_back( TopoDS::Wire( aShape ) ); + } + else + { + TopExp_Explorer anExp( aShape, TopAbs_WIRE ); + for( ; anExp.More(); anExp.Next() ) + { + aResult.push_back( TopoDS::Wire( anExp.Current() ) ); + } + } return aResult; } -std::vector HYDROData_PolylineOperator::Intersection( const Handle( Geom2d_Curve )& theCurve, - const Handle( Geom2d_Curve )& theTool ) +std::vector HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire, + const gp_Pnt2d& thePoint, + double theTolerance ) { - std::vector aResult; + std::vector aResult; + NCollection_Vector aEdges; + Standard_Boolean isClosed; + if (!WireToCurve(theWire, aEdges, isClosed)) + { + aResult.push_back(theWire); + return aResult; + } + + const gp_Pnt aP(thePoint.X(), thePoint.Y(), 0); + Standard_Real aMinSqDist = DBL_MAX; + int aSEI = -1; + Standard_Real aSParam; + for (int aECount = aEdges.Size(), aEI = 0; aEI < aECount; ++aEI) + { + Standard_Real aParam; + const Standard_Real aSqDist = + ProjectPointToEdge(aP, aEdges(aEI), aParam); + if (aMinSqDist > aSqDist) + { + aMinSqDist = aSqDist; + aSEI = aEI; + aSParam = aParam; + } + } + + NCollection_Vector aEdges1, aEdges2; + SplitCurveByPoint(aEdges, aSEI, aSParam, aEdges1, aEdges2); + TopoDS_Wire aWire; + if (!isClosed) + { + CurveToWire(aEdges1, aWire); + if (!aEdges2.IsEmpty()) + { + aResult.push_back(aWire); + CurveToWire(aEdges2, aWire); + } + } + else + { + if (!aEdges2.IsEmpty()) + { + CurveToWire(aEdges2, aEdges1, aWire); + } + else + { + CurveToWire(aEdges1, aWire); + } + } + aResult.push_back(aWire); + return aResult; +} + +std::vector HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire, + const TopoDS_Wire& theTool, + double theTolerance ) +{ + std::vector aResult; + NCollection_Vector aWEdges, aTEdges; + Standard_Boolean aIsWClosed, aIsTClosed; + if (!WireToCurve(theWire, aWEdges, aIsWClosed) || + !WireToCurve(theTool, aTEdges, aIsTClosed)) + { + return aResult; + } + + //TODO return aResult; } -std::vector HYDROData_PolylineOperator::Split( const Handle( Geom2d_Curve )& theCurve, - const std::vector& thePoints ) +std::vector HYDROData_PolylineOperator::Split( const std::vector& theWires, + double theTolerance ) { - std::vector aResult; + std::vector aResult; //TODO return aResult; } bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc, - const TCollection_AsciiString& theNamePrefix, - const std::vector& theCurves ) + const QString& theNamePrefix, + const std::vector& theShapes, + bool isUseIndices ) { if( theDoc.IsNull() ) return false; - int n = theCurves.size(); + int n = theShapes.size(); + int anIndex = 1; for( int i=0; iCreateObject( KIND_POLYLINEXY ) ); if( aPolyline.IsNull() ) return false; - aPolyline->SetShape( aMakeWire.Wire() ); - //TODO: set name + aPolyline->SetShape( theShapes[i] ); + + if( isUseIndices ) + { + QString aNewName = theNamePrefix + "_" + QString::number( anIndex ); + if( theDoc->FindObjectByName( aNewName ).IsNull() ) // the object with such a name is not found + aPolyline->SetName( aNewName ); + anIndex++; + } + else + { + aPolyline->SetName( theNamePrefix ); + } } return true; }