1 // Copyright (C) 2014-2015 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 #include <HYDROData_PolylineOperator.h>
20 #include <HYDROData_Document.h>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRepBuilderAPI_MakeEdge2d.hxx>
24 #include <BRepBuilderAPI_MakeWire.hxx>
25 #include <Extrema_ExtCC.hxx>
26 #include <Extrema_ExtPC.hxx>
27 #include <NCollection_Vector.hxx>
28 #include <Precision.hxx>
29 #include <ShapeAnalysis_TransferParametersProj.hxx>
30 #include <ShapeBuild_Edge.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Wire.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
39 template<class T> void append( std::vector<T>& theList, const std::vector<T>& theList2 )
41 int aSize = theList.size();
42 int aNewSize = aSize + theList2.size();
47 theList.resize( aNewSize );
48 for( int i=aSize, j=0; i<aNewSize; i++, j++ )
49 theList[i] = theList2[j];
52 static TopoDS_Edge ReplaceVertex(
53 const TopoDS_Edge& theEdge, Standard_Integer theVertexIndex)
55 TopoDS_Vertex aVertices[] =
56 {TopExp::FirstVertex(theEdge), TopExp::LastVertex(theEdge)};
57 const TopAbs_Orientation aOrient = theEdge.Orientation();
58 if (aOrient == TopAbs_REVERSED)
62 aVertices[theVertexIndex].EmptyCopy();
63 aVertices[0].Orientation(TopAbs_FORWARD);
64 aVertices[1].Orientation(TopAbs_REVERSED);
65 TopoDS_Edge aFE = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD));
66 TopoDS_Edge aNewEdge =
67 ShapeBuild_Edge().CopyReplaceVertices(aFE, aVertices[0], aVertices[1]);
68 return TopoDS::Edge(aNewEdge.Oriented(aOrient));
71 static Standard_Boolean WireToCurve(
72 const TopoDS_Wire& theWire,
73 NCollection_Vector<TopoDS_Edge>& theEdges,
74 Standard_Boolean& theIsClosed)
76 TopTools_IndexedDataMapOfShapeListOfShape aVertexToEdges;
77 TopExp::MapShapesAndAncestors(theWire,
78 TopAbs_VERTEX, TopAbs_EDGE, aVertexToEdges);
79 const Standard_Integer aVCount = aVertexToEdges.Extent();
82 return Standard_False;
86 Standard_Integer aEndCount = 0;
87 for (Standard_Integer aVN = 1; aVN <= aVCount; ++aVN)
89 const Standard_Integer aEdgeCount =
90 aVertexToEdges.FindFromIndex(aVN).Extent();
97 return Standard_False;
100 theIsClosed = (aEndCount == 0);
101 if (!theIsClosed && aEndCount != 2)
103 return Standard_False;
107 Standard_Integer aVN = 1;
110 while (aVN <= aVCount &&
111 aVertexToEdges.FindFromIndex(aVN).Extent() == 2)
117 TopTools_ListOfShape* aEdges = &aVertexToEdges.ChangeFromIndex(aVN);
118 while (!aEdges->IsEmpty())
120 const TopoDS_Edge aEdge = TopoDS::Edge(aEdges->First());
121 aEdges->RemoveFirst();
122 theEdges.Append(aEdge);
123 Standard_Integer aVN2 =
124 aVertexToEdges.FindIndex(TopExp::FirstVertex(aEdge));
127 aVN2 = aVertexToEdges.FindIndex(TopExp::LastVertex(aEdge));
131 aEdges = &aVertexToEdges.ChangeFromIndex(aVN2);
132 if (aEdges->First().IsEqual(aEdge))
134 aEdges->RemoveFirst();
138 const TopoDS_Edge aEdge = TopoDS::Edge(aEdges->First());
140 aEdges->Append(aEdge);
143 return (!theIsClosed && theEdges.Size() == aVCount - 1) ||
144 (theIsClosed && theEdges.Size() == aVCount);
147 static void CurveToWire(
148 const NCollection_Vector<TopoDS_Edge>& theEdges, TopoDS_Wire& theWire)
150 BRep_Builder aBulder;
151 aBulder.MakeWire(theWire);
152 NCollection_Vector<TopoDS_Edge>::Iterator aEIt(theEdges);
153 for (; aEIt.More(); aEIt.Next())
155 aBulder.Add(theWire, aEIt.Value());
159 static void CurveToWire(
160 const NCollection_Vector<TopoDS_Edge>& theEdges1,
161 const NCollection_Vector<TopoDS_Edge>& theEdges2,
162 TopoDS_Wire& theWire)
164 BRep_Builder aBulder;
165 aBulder.MakeWire(theWire);
166 const NCollection_Vector<TopoDS_Edge>* aEdges[] = {&theEdges1, &theEdges2};
167 for (Standard_Integer aEI = 0; aEI < 2; ++aEI)
169 NCollection_Vector<TopoDS_Edge>::Iterator aEIt(*aEdges[aEI]);
170 for (; aEIt.More(); aEIt.Next())
172 aBulder.Add(theWire, aEIt.Value());
177 static Standard_Real ProjectPointToCurve(
178 const gp_Pnt& thePoint,
179 const Adaptor3d_Curve& theCurve,
180 Standard_Real& theParameter)
182 Extrema_ExtPC aAlgo(thePoint, theCurve);
183 Standard_Integer aMinEN = -2;
184 Standard_Real aMinSqDist = DBL_MAX;
187 const Standard_Integer aECount = aAlgo.NbExt();
188 for (Standard_Integer aEN = 1; aEN <= aECount; ++aEN)
190 const gp_Pnt& aP = aAlgo.Point(aEN).Value();
191 const Standard_Real aSqDist = thePoint.SquareDistance(aP);
192 if (aMinSqDist > aSqDist)
194 aMinSqDist = aSqDist;
200 const Standard_Real aParams[] =
201 {theCurve.FirstParameter(), theCurve.LastParameter()};
202 const gp_Pnt aEnds[] =
203 {theCurve.Value(aParams[0]), theCurve.Value(aParams[1])};
204 const Standard_Real aSqDists[] =
205 {thePoint.SquareDistance(aEnds[0]), thePoint.SquareDistance(aEnds[1])};
206 for (Standard_Integer aEI = 0; aEI < 2; ++aEI)
208 if (aMinSqDist > aSqDists[aEI])
210 aMinSqDist = aSqDists[aEI];
217 theParameter = aParams[-aMinEN];
221 const Extrema_POnCurv& aPOnC = aAlgo.Point(aMinEN);
222 const gp_Pnt& aPoint = aPOnC.Value();
223 theParameter = aPOnC.Parameter();
224 for (Standard_Integer aEI = 0; aEI < 2; ++aEI)
226 if (Abs(theParameter - aParams[aEI]) < Precision::PConfusion() ||
227 aPoint.SquareDistance(aEnds[aEI]) < Precision::SquareConfusion())
229 theParameter = aParams[aEI];
235 static Standard_Real ProjectPointToEdge(
236 const gp_Pnt& thePoint,
237 const TopoDS_Edge& theEdge,
238 Standard_Real& theParameter)
240 return ProjectPointToCurve(thePoint, BRepAdaptor_Curve(theEdge), theParameter);
243 static void SplitCurveByPoint(
244 const NCollection_Vector<TopoDS_Edge>& theEdges,
245 const Standard_Integer theEdgeIndex,
246 const Standard_Real theParameter,
247 NCollection_Vector<TopoDS_Edge>& theEdges1,
248 NCollection_Vector<TopoDS_Edge>& theEdges2)
250 for (Standard_Integer aEI = 0; aEI < theEdgeIndex; ++aEI)
252 theEdges1.Append(theEdges(aEI));
255 const TopoDS_Edge& aEdge = theEdges(theEdgeIndex);
256 BRepAdaptor_Curve aCurve(aEdge);
257 Standard_Integer aParamI = -1;
258 const Standard_Real aEdgeEndParams[] =
259 {aCurve.FirstParameter(), aCurve.LastParameter()};
260 if (Abs(theParameter - aEdgeEndParams[0]) < Precision::PConfusion())
264 else if (Abs(theParameter - aEdgeEndParams[1]) < Precision::PConfusion())
269 const TopAbs_Orientation aOrient = aEdge.Orientation();
270 if (aOrient == TopAbs_REVERSED)
275 NCollection_Vector<TopoDS_Edge>* aEdges = &theEdges2;
276 const Standard_Integer aECount = theEdges.Size();
279 aEdges = (theEdgeIndex == 0) ? &theEdges1 : &theEdges2;
280 aEdges->Append(ReplaceVertex(aEdge, 0));
282 else if (aParamI == 1)
284 theEdges1.Append(ReplaceVertex(aEdge, 1));
288 TopoDS_Edge aFE = TopoDS::Edge(aEdge.Oriented(TopAbs_FORWARD));
289 ShapeAnalysis_TransferParametersProj aSATPP(aFE, TopoDS_Face());
290 aSATPP.SetMaxTolerance(Precision::Confusion());
291 TopoDS_Vertex aSplitV1, aSplitV2;
292 BRep_Builder().MakeVertex(
293 aSplitV1, aCurve.Value(theParameter), Precision::Confusion());
294 BRep_Builder().MakeVertex(
295 aSplitV2, aCurve.Value(theParameter), Precision::Confusion());
296 TopoDS_Edge aEParts[] = {
297 ShapeBuild_Edge().CopyReplaceVertices(aFE, TopoDS_Vertex(),
298 TopoDS::Vertex(aSplitV1.Oriented(TopAbs_REVERSED))),
299 ShapeBuild_Edge().CopyReplaceVertices(aFE, aSplitV2, TopoDS_Vertex())};
300 ShapeBuild_Edge().CopyPCurves(aEParts[0], aFE);
301 ShapeBuild_Edge().CopyPCurves(aEParts[1], aFE);
302 BRep_Builder().SameRange(aEParts[0], Standard_False);
303 BRep_Builder().SameRange(aEParts[1], Standard_False);
304 BRep_Builder().SameParameter(aEParts[0], Standard_False);
305 BRep_Builder().SameParameter(aEParts[1], Standard_False);
306 aSATPP.TransferRange(aEParts[0],
307 aEdgeEndParams[0], theParameter, Standard_False);
308 aSATPP.TransferRange(aEParts[1],
309 theParameter, aEdgeEndParams[1], Standard_False);
310 aEParts[0].Orientation(aOrient);
311 aEParts[1].Orientation(aOrient);
313 const Standard_Integer aFirstPI = (aOrient != TopAbs_REVERSED) ? 0 : 1;
314 theEdges1.Append(aEParts[aFirstPI]);
315 theEdges2.Append(aEParts[1 - aFirstPI]);
317 for (Standard_Integer aEI = theEdgeIndex + 1; aEI < aECount; ++aEI)
319 aEdges->Append(theEdges(aEI));
323 static void SplitCurveByPoints(
324 const NCollection_Vector<TopoDS_Edge>& theCurve,
325 const NCollection_Vector<NCollection_Sequence<Standard_Real> >& theParameters,
326 NCollection_Vector<NCollection_Vector<TopoDS_Edge> >& theSplittedCurves)
328 NCollection_Vector<TopoDS_Edge> aCurves[3];
329 aCurves[0] = theCurve;
330 Standard_Integer aCI = 0, aEI = 0;
331 NCollection_Vector<TopoDS_Edge>::Iterator aEIt(theCurve);
332 for (NCollection_Vector<NCollection_Sequence<Standard_Real> >::Iterator
333 aPLIt(theParameters); aPLIt.More(); ++aEI, aEIt.Next(), aPLIt.Next())
335 const Standard_Boolean isForward =
336 (aEIt.Value().Orientation() != TopAbs_REVERSED);
337 for (NCollection_Sequence<Standard_Real>::Iterator
338 aPIt(aPLIt.Value(), isForward); aPIt.More(); aPIt.Next())
340 const Standard_Integer aCI1 = (aCI + 1) % 3, aCI2 = (aCI + 2) % 3;
341 SplitCurveByPoint(aCurves[aCI], aEI,
342 aPIt.Value(), aCurves[aCI1], aCurves[aCI2]);
343 if (!aCurves[aCI2].IsEmpty())
345 theSplittedCurves.Append(aCurves[aCI1]);
346 aCurves[aCI].Clear();
350 aCurves[aCI1].Clear();
353 theSplittedCurves.Append(aCurves[aCI]);
356 static Standard_Integer AppendIntersectionPoint(
357 const Adaptor3d_Curve& theCurve,
358 const Standard_Real theParameter,
359 NCollection_Sequence<Standard_Real>& theParameters)
361 // Check the coincidence.
362 NCollection_Sequence<Standard_Real> aEndParams;
363 aEndParams.Append(theCurve.FirstParameter());
364 aEndParams.Append(theCurve.LastParameter());
365 NCollection_Sequence<Standard_Real>* aParams[] =
366 {&theParameters, &aEndParams};
367 const gp_Pnt aPoint = theCurve.Value(theParameter);
368 for (Standard_Integer aLI = 0; aLI < 2; ++aLI)
370 NCollection_Sequence<Standard_Real>::Iterator aPIt(*aParams[aLI]);
371 for (Standard_Integer aPI = 0; aPIt.More(); aPIt.Next(), ++aPI)
373 const Standard_Real aParam = aPIt.Value();
374 if (Abs(theParameter - aParam) < Precision::PConfusion() ||
375 aPoint.SquareDistance(theCurve.Value(aParam)) <=
376 Precision::SquareConfusion())
378 Standard_Integer aIntCount = 0;
383 theParameters.Prepend(aEndParams.First());
387 theParameters.Append(aEndParams.Last());
396 // Calculate the position to insert.
397 NCollection_Sequence<Standard_Real>::Iterator aPIt(theParameters);
398 if (aPIt.More() && aPIt.Value() < theParameter)
400 NCollection_Sequence<Standard_Real>::Iterator aPIt2 = aPIt;
402 for (; aPIt2.More() && aPIt2.Value() < theParameter;
403 aPIt.Next(), aPIt2.Next());
404 theParameters.InsertAfter(aPIt, theParameter);
408 theParameters.Prepend(theParameter);
413 static Standard_Integer IntersectEdge(
414 const TopoDS_Edge& theEdge1,
415 const TopoDS_Edge& theEdge2,
416 NCollection_Sequence<Standard_Real>& theParameters)
419 Standard_Integer aIntCount = 0;
420 BRepAdaptor_Curve aCurve1 = BRepAdaptor_Curve(theEdge1);
421 BRepAdaptor_Curve aCurve2 = BRepAdaptor_Curve(theEdge2);
422 const gp_Pnt aEndPs[] = {aCurve2.Value(aCurve2.FirstParameter()),
423 aCurve2.Value(aCurve2.LastParameter())};
424 for (Standard_Integer aPI = 0; aPI < 2; ++aPI)
426 Standard_Real aParameter;
427 if (ProjectPointToCurve(aEndPs[aPI], aCurve1, aParameter) <=
428 Precision::SquareConfusion())
430 AppendIntersectionPoint(aCurve1, aParameter, theParameters);
434 // Process the internal extrema.
435 Extrema_ExtCC aAlgo(aCurve1, aCurve2);
438 const Standard_Integer aECount = aAlgo.NbExt();
439 for (Standard_Integer aEN = 1; aEN <= aECount; ++aEN)
441 Extrema_POnCurv aP1, aP2;
442 aAlgo.Points(aEN, aP1, aP2);
443 if (aP1.Value().SquareDistance(aP2.Value()) <=
444 Precision::SquareConfusion())
446 AppendIntersectionPoint(aCurve1, aP1.Parameter(), theParameters);
453 static Standard_Integer IntersectCurve(
454 const NCollection_Vector<TopoDS_Edge>& theEdges,
455 const TopoDS_Wire& theWire,
456 NCollection_Vector<NCollection_Sequence<Standard_Real> >& theParameters)
458 Standard_Integer aIntCount = 0;
459 const Standard_Integer aECount1 = theEdges.Size();
460 for (Standard_Integer aEI1 = 0; aEI1 < aECount1; ++aEI1)
462 const TopoDS_Edge& aEdge1 = theEdges(aEI1);
463 TopExp_Explorer aEIt2(theWire, TopAbs_EDGE);
464 for (; aEIt2.More(); aEIt2.Next())
466 aIntCount += IntersectEdge(aEdge1,
467 TopoDS::Edge(aEIt2.Current()), theParameters(aEI1));
473 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
474 const Handle( HYDROData_PolylineXY )& thePolyline,
475 const gp_Pnt2d& thePoint,
476 double theTolerance ) const
478 std::vector<gp_Pnt2d> aPointsList( 1 );
479 aPointsList[0] = thePoint;
480 std::vector<TopoDS_Wire> aCurves = GetWires( thePolyline );
482 for( int i=0, n=aCurves.size(); i<n; i++ )
484 std::vector<TopoDS_Shape> aCurvesList = Split( aCurves[i], thePoint, theTolerance );
485 bool isLocalOK = CreatePolylines( theDoc, thePolyline->GetName(), aCurvesList, true );
486 isOK = isOK && isLocalOK;
491 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
492 const Handle( HYDROData_PolylineXY )& thePolyline,
493 const Handle( HYDROData_PolylineXY )& theTool,
494 double theTolerance ) const
496 HYDROData_SequenceOfObjects aSeq;
497 aSeq.Append( theTool );
498 return split( theDoc, thePolyline, aSeq, theTolerance, -1 );
501 bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theDoc,
502 const HYDROData_SequenceOfObjects& thePolylines,
503 double theTolerance )
505 int f = thePolylines.Lower(), l = thePolylines.Upper();
506 for( int i=f; i<=l; i++ )
508 Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) );
509 if( !split( theDoc, aPolyline, thePolylines, theTolerance, i ) )
515 bool HYDROData_PolylineOperator::Merge( const Handle( HYDROData_Document )& theDoc,
516 const QString& theName,
517 const HYDROData_SequenceOfObjects& thePolylines,
518 bool isConnectByNewSegment,
519 double theTolerance )
521 TopoDS_Shape aMergedPolyline;
523 int f = thePolylines.Lower(), l = thePolylines.Upper();
524 for( int i=f; i<=l; i++ )
526 Handle( HYDROData_PolylineXY ) aPolyline = Handle( HYDROData_PolylineXY )::DownCast( thePolylines.Value( i ) );
527 std::vector<TopoDS_Wire> aCurves = GetWires( aPolyline );
528 for( int j=0, m=aCurves.size(); j<m; j++ )
529 if( !Merge( aMergedPolyline, aCurves[j], isConnectByNewSegment, theTolerance ) )
533 std::vector<TopoDS_Shape> aShapes( 1 );
534 aShapes[0] = aMergedPolyline;
535 CreatePolylines( theDoc, theName, aShapes, false );
540 bool HYDROData_PolylineOperator::Merge( TopoDS_Shape& theShape, const TopoDS_Wire& theWire,
541 bool isConnectByNewSegment, double theTolerance )
547 bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theDoc,
548 const Handle( HYDROData_PolylineXY )& thePolyline,
549 const HYDROData_SequenceOfObjects& theTools,
551 int theIgnoreIndex ) const
553 std::vector<TopoDS_Wire> aCurves = GetWires( thePolyline );
554 std::vector<TopoDS_Wire> aToolCurves;
555 for( int i=theTools.Lower(), n=theTools.Upper(); i<=n; i++ )
556 if( i!=theIgnoreIndex )
558 Handle( HYDROData_PolylineXY ) aToolPolyline =
559 Handle( HYDROData_PolylineXY )::DownCast( theTools.Value( i ) );
560 append( aToolCurves, GetWires( aToolPolyline ) );
563 const int aPSCount = aCurves.size();
564 const int aTSCount = aToolCurves.size();
565 std::vector<TopoDS_Shape> aResult;
566 for (int aPSI = 0; aPSI < aPSCount; ++aPSI)
568 NCollection_Vector<TopoDS_Edge> aCurve;
569 Standard_Boolean aIsClosed;
570 if (!WireToCurve(aCurves[aPSI], aCurve, aIsClosed))
575 NCollection_Vector<NCollection_Sequence<Standard_Real> > aParams;
576 aParams.SetValue(aPSCount - 1, NCollection_Sequence<Standard_Real>());
577 for (int aTSI = 0; aTSI < aTSCount; ++aTSI)
579 IntersectCurve(aCurve, aToolCurves[aTSI], aParams);
582 NCollection_Vector<NCollection_Vector<TopoDS_Edge> > aSplittedCurves;
583 SplitCurveByPoints(aCurve, aParams, aSplittedCurves);
585 Standard_Boolean aIsClosed2 = aIsClosed;
588 const NCollection_Sequence<Standard_Real>& aPs = aParams.First();
591 const TopoDS_Edge& aEdge = aCurve.First();
592 const Standard_Boolean isForward =
593 (aEdge.Orientation() != TopAbs_REVERSED);
594 const Standard_Real aParam = isForward ? aPs.First() : aPs.Last();
595 BRepAdaptor_Curve aCurve(aEdge);
596 const Standard_Real aEndParam = isForward ?
597 aCurve.FirstParameter() : aCurve.LastParameter();
598 aIsClosed2 = (Abs(aParam - aEndParam) > Precision::PConfusion());
603 const NCollection_Sequence<Standard_Real>& aPs = aParams.Last();
606 const TopoDS_Edge& aEdge = aCurve.Last();
607 const Standard_Boolean isForward =
608 (aEdge.Orientation() != TopAbs_REVERSED);
609 const Standard_Real aParam = isForward ? aPs.Last() : aPs.First();
610 BRepAdaptor_Curve aCurve(aEdge);
611 const Standard_Real aEndParam = isForward ?
612 aCurve.LastParameter() : aCurve.FirstParameter();
613 aIsClosed2 = (Abs(aParam - aEndParam) >= Precision::PConfusion());
618 Standard_Integer aFSCI = 0, aLSCI = aSplittedCurves.Size() - 1;
619 if (aIsClosed2 && aFSCI < aLSCI)
622 CurveToWire(aSplittedCurves(aLSCI), aSplittedCurves(aFSCI), aWire);
623 aResult.push_back(aWire);
628 for (Standard_Integer aSCI = aFSCI; aSCI <= aLSCI; ++aSCI)
631 CurveToWire(aSplittedCurves(aSCI), aWire);
632 aResult.push_back(aWire);
636 CreatePolylines(theDoc, thePolyline->GetName(), aResult, true);
640 std::vector<TopoDS_Wire> HYDROData_PolylineOperator::GetWires( const Handle( HYDROData_PolylineXY )& thePolyline )
642 std::vector<TopoDS_Wire> aResult;
644 TopoDS_Shape aShape = thePolyline->GetShape();
646 if( aShape.ShapeType()==TopAbs_WIRE )
648 aResult.push_back( TopoDS::Wire( aShape ) );
652 TopExp_Explorer anExp( aShape, TopAbs_WIRE );
653 for( ; anExp.More(); anExp.Next() )
655 aResult.push_back( TopoDS::Wire( anExp.Current() ) );
661 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
662 const gp_Pnt2d& thePoint,
663 double theTolerance )
665 std::vector<TopoDS_Shape> aResult;
666 NCollection_Vector<TopoDS_Edge> aEdges;
667 Standard_Boolean isClosed;
668 if (!WireToCurve(theWire, aEdges, isClosed))
670 aResult.push_back(theWire);
674 const gp_Pnt aP(thePoint.X(), thePoint.Y(), 0);
675 Standard_Real aMinSqDist = DBL_MAX;
677 Standard_Real aSParam;
678 for (int aECount = aEdges.Size(), aEI = 0; aEI < aECount; ++aEI)
680 Standard_Real aParam;
681 const Standard_Real aSqDist =
682 ProjectPointToEdge(aP, aEdges(aEI), aParam);
683 if (aMinSqDist > aSqDist)
685 aMinSqDist = aSqDist;
691 NCollection_Vector<TopoDS_Edge> aEdges1, aEdges2;
692 SplitCurveByPoint(aEdges, aSEI, aSParam, aEdges1, aEdges2);
696 CurveToWire(aEdges1, aWire);
697 if (!aEdges2.IsEmpty())
699 aResult.push_back(aWire);
700 CurveToWire(aEdges2, aWire);
705 if (!aEdges2.IsEmpty())
707 CurveToWire(aEdges2, aEdges1, aWire);
711 CurveToWire(aEdges1, aWire);
714 aResult.push_back(aWire);
718 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const TopoDS_Wire& theWire,
719 const TopoDS_Wire& theTool,
720 double theTolerance )
722 std::vector<TopoDS_Shape> aResult;
723 NCollection_Vector<TopoDS_Edge> aWEdges, aTEdges;
724 Standard_Boolean aIsWClosed, aIsTClosed;
725 if (!WireToCurve(theWire, aWEdges, aIsWClosed) ||
726 !WireToCurve(theTool, aTEdges, aIsTClosed))
736 std::vector<TopoDS_Shape> HYDROData_PolylineOperator::Split( const std::vector<TopoDS_Wire>& theWires,
737 double theTolerance )
739 std::vector<TopoDS_Shape> aResult;
744 bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc,
745 const QString& theNamePrefix,
746 const std::vector<TopoDS_Shape>& theShapes,
749 if( theDoc.IsNull() )
752 int n = theShapes.size();
754 for( int i=0; i<n; i++ )
756 Handle( HYDROData_PolylineXY ) aPolyline =
757 Handle( HYDROData_PolylineXY )::DownCast( theDoc->CreateObject( KIND_POLYLINEXY ) );
758 if( aPolyline.IsNull() )
761 aPolyline->SetShape( theShapes[i] );
765 QString aNewName = theNamePrefix + "_" + QString::number( anIndex );
766 if( theDoc->FindObjectByName( aNewName ).IsNull() ) // the object with such a name is not found
767 aPolyline->SetName( aNewName );
772 aPolyline->SetName( theNamePrefix );