From 0184a027dd5854562adf1bfa4dbf90865476d1d3 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Sun, 19 Jun 2016 17:22:10 +0200 Subject: [PATCH] split polylines, keep original polyline points on split --- src/HYDROData/HYDROData_PolylineOperator.cxx | 17 +- src/HYDROData/HYDROData_PolylineOperator.h | 5 +- src/HYDROData/HYDROData_PolylineXY.cxx | 164 +++++++++++++++++-- src/HYDROData/HYDROData_PolylineXY.h | 1 + src/HYDROData/HYDROData_TopoCurve.cxx | 2 +- src/HYDROData/HYDROData_TopoCurve.h | 10 +- 6 files changed, 166 insertions(+), 33 deletions(-) diff --git a/src/HYDROData/HYDROData_PolylineOperator.cxx b/src/HYDROData/HYDROData_PolylineOperator.cxx index 947de751..5c241ad8 100644 --- a/src/HYDROData/HYDROData_PolylineOperator.cxx +++ b/src/HYDROData/HYDROData_PolylineOperator.cxx @@ -88,8 +88,7 @@ bool HYDROData_PolylineOperator::Split( const Handle( HYDROData_Document )& theD { std::vector aCurvesList; Split( aCurves[i], thePoint, theTolerance, aCurvesList ); - bool isLocalOK = CreatePolylines( theDoc, thePolyline->GetName(), - aCurvesList, true, thePolyline->GetWireColor() ); + bool isLocalOK = CreatePolylines( theDoc, thePolyline, aCurvesList, true ); isOK = isOK && isLocalOK; } return isOK; @@ -234,7 +233,7 @@ bool HYDROData_PolylineOperator::split( const Handle( HYDROData_Document )& theD } } - CreatePolylines( theDoc, thePolyline->GetName(), aResult, true, thePolyline->GetWireColor() ); + CreatePolylines( theDoc, thePolyline, aResult, true ); //CreatePolylinesSplit( theDoc, thePolyline, aResult, true ); return true; } @@ -335,14 +334,18 @@ void HYDROData_PolylineOperator::Split( //} bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Document )& theDoc, - const QString& theNamePrefix, + const Handle( HYDROData_PolylineXY )& theOldPolyline, const std::vector& theShapes, - bool isUseIndices, - const QColor& theColor ) + bool isUseIndices ) { 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; @@ -353,7 +356,7 @@ bool HYDROData_PolylineOperator::CreatePolylines( const Handle( HYDROData_Docume if( aPolyline.IsNull() ) return false; - aPolyline->ImportShape(theShapes[i], false, false); + aPolyline->ImportShape(theShapes[i], false, theOldPolyline, false); //aPolyline->SetShape( theShapes[i] ); diff --git a/src/HYDROData/HYDROData_PolylineOperator.h b/src/HYDROData/HYDROData_PolylineOperator.h index ed1716c0..364f27a8 100644 --- a/src/HYDROData/HYDROData_PolylineOperator.h +++ b/src/HYDROData/HYDROData_PolylineOperator.h @@ -88,10 +88,9 @@ protected: // bool isUseIndices); static bool CreatePolylines( const Handle( HYDROData_Document )& theDoc, - const QString& theNamePrefix, + const Handle( HYDROData_PolylineXY )& theOldPolyline, const std::vector& theShape, - bool isUseIndices, - const QColor& theColor ); + bool isUseIndices ); }; #endif diff --git a/src/HYDROData/HYDROData_PolylineXY.cxx b/src/HYDROData/HYDROData_PolylineXY.cxx index 20629aa0..5eb6ed56 100644 --- a/src/HYDROData/HYDROData_PolylineXY.cxx +++ b/src/HYDROData/HYDROData_PolylineXY.cxx @@ -86,6 +86,7 @@ #include "HYDRO_trace.hxx" #include #include +#include static const Standard_GUID GUID_IS_UNEDITABLE("e5799736-9030-4051-91a4-2e58321fa153"); @@ -342,7 +343,8 @@ bool convertEdgesToSections( const TopoDS_Edge& NCollection_Sequence& theSectPoints, bool IsCanBeClosed, bool IsInterpolationAllowed, - double theDeflection ) + double theDeflection, + const Handle( HYDROData_PolylineXY )& theOldPolyline ) { DEBTRACE("convertEdgesToSections") Standard_Real aFirst = 0.0, aLast = 0.0; @@ -442,22 +444,147 @@ bool convertEdgesToSections( const TopoDS_Edge& isNewSection = true; aPointsList.Clear(); - BRepAdaptor_Curve anAdaptorCurve( theEdge ); - GCPnts_QuasiUniformDeflection aDiscrete( anAdaptorCurve, theDeflection ); + BRepAdaptor_Curve anAdaptorCurve(theEdge); + if (theOldPolyline.IsNull()) // --- no previous polyline: build a set of points from scratch for the spline + { + GCPnts_QuasiUniformDeflection aDiscrete(anAdaptorCurve, theDeflection); - int aNbPoints = aDiscrete.NbPoints(); + int aNbPoints = aDiscrete.NbPoints(); - // Decrease the number of imported poles because of last one - // pole is the closing point which are the start point - if ( anIsEdgeClosed ) aNbPoints--; + // Decrease the number of imported poles because of last one + // pole is the closing point which are the start point + if (anIsEdgeClosed) + aNbPoints--; - for ( int i = 1; i <= aNbPoints; ++i ) - { - const gp_Pnt& aPoint = aDiscrete.Value( i ); + for (int i = 1; i <= aNbPoints; ++i) + { + const gp_Pnt& aPoint = aDiscrete.Value(i); + HYDROData_PolylineXY::Point aSectPoint(aPoint.X(), aPoint.Y()); + aPointsList.Append(aSectPoint); + } - HYDROData_PolylineXY::Point aSectPoint( aPoint.X(), aPoint.Y() ); - aPointsList.Append( aSectPoint ); - } + gp_Pnt endPts[] = {gp_Pnt(aPointsList.First().X(),aPointsList.First().Y(), 0), + gp_Pnt(aPointsList.Last().X(),aPointsList.Last().Y(), 0) }; + DEBTRACE("curve start: "<< endPts[0].X() << " " << endPts[0].Y()); + DEBTRACE("curve end: "<< endPts[1].X() << " " << endPts[1].Y()); + } + else // --- split of a previous polyline: try to retrieve old sets of points and add intersection points + { + const gp_Pnt aEndPs[] = { anAdaptorCurve.Value(anAdaptorCurve.FirstParameter()).XYZ(), + anAdaptorCurve.Value(anAdaptorCurve.LastParameter()).XYZ() }; + double midPar = (anAdaptorCurve.LastParameter() + anAdaptorCurve.FirstParameter())/2; + gp_Pnt midPnt; + anAdaptorCurve.D0(midPar, midPnt); + DEBTRACE("curve first point: " << aEndPs[0].X() << " " << aEndPs[0].Y() << " " << aEndPs[0].Z()); + DEBTRACE("curve last point: " << aEndPs[1].X() << " " << aEndPs[1].Y() << " " << aEndPs[1].Z()); + DEBTRACE("curve mid point: " << midPnt.X() << " " << midPnt.Y() << " " << midPnt.Z()); + + std::vector aCurves; + HYDROData_PolylineOperator::GetWires(theOldPolyline, aCurves); + + int nbSections = theOldPolyline->NbSections(); + DEBTRACE("nbSections: "<< nbSections << ", nbCurves: " << aCurves.size() ); + for (int isec = 0; isec < nbSections; isec++) + { + DEBTRACE("section: "<< isec); + bool isOldSectionclosed = theOldPolyline->IsClosedSection(isec); + TopoDS_Wire aWire = aCurves[isec]; // we suppose sections and wires are in the same order + TopExp_Explorer anExp(aWire, TopAbs_EDGE); + TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current()); // the first is OK: only one normally with splines + BRepAdaptor_Curve adaptorOldCurve(anEdge); + double pfirst = adaptorOldCurve.FirstParameter(); + double plast = adaptorOldCurve.LastParameter(); + DEBTRACE("previous curve first last : "<< pfirst << " " << plast); + double p[3] = {-1, -1}; + double d0= ProjectPointToCurve(aEndPs[0].XYZ(), adaptorOldCurve,p[0]); + double d1= ProjectPointToCurve(aEndPs[1].XYZ(), adaptorOldCurve,p[1]); + double d2= ProjectPointToCurve(midPnt.XYZ(), adaptorOldCurve, p[2]); + DEBTRACE("d0: "< 1.e-3) and (abs(pmax - plast) >1.e-3))) // internal points forward + forward = true; + else if ((pmin > pmax) and((abs(pmin - plast)> 1.e-3) and (abs(pmax - pfirst) >1.e-3))) // internal points reverse + { + pmin = p[1]; + pmax = p[0]; + forward = false; + } + else if ((abs(pmin - plast) <1.e-3) and (p[2] < pmax)) // forward, replace pmin par pfirst + pmin = pfirst; + else if ((abs(pmin - plast) <1.e-3) and (p[2] > pmax)) // reverse + { + pmin = p[1]; + pmax = p[0]; + forward = false; + } + else if ((abs(pmax - pfirst) <1.e-3) and (p[2] < pmin)) // reverse + { + pmin = p[1]; + pmax = p[0]; + forward = false; + } + else if ((abs(pmax - pfirst) <1.e-3) and (p[2] > pmin)) // forward, replace pmax par plast + pmax = plast; + } + HYDROData_PolylineXY::Point aFirstPoint, aLastPoint; + if (forward) + { + aFirstPoint = HYDROData_PolylineXY::Point(aEndPs[0].X(), aEndPs[0].Y()); + aLastPoint = HYDROData_PolylineXY::Point(aEndPs[1].X(), aEndPs[1].Y()); + } + else + { + aFirstPoint = HYDROData_PolylineXY::Point(aEndPs[1].X(), aEndPs[1].Y()); + aLastPoint = HYDROData_PolylineXY::Point(aEndPs[0].X(), aEndPs[0].Y()); + } + aPointsList.Append(aFirstPoint); + + HYDROData_PolylineXY::PointsList aSectPoints = theOldPolyline->GetPoints(isec, false); + int nbPoints = aSectPoints.Length(); + if (forward) + for (int i=1; i pmin) and (param < pmax)) + { + DEBTRACE("param: " << param); + aPointsList.Append(aPoint); + } + } + else + for (int i=nbPoints -1; i>0; i--) + { + HYDROData_PolylineXY::Point aPoint = aSectPoints.Value(i); + gp_XYZ p(aPoint.X(), aPoint.Y(), 0); + double param =-1; + double d = ProjectPointToCurve(p, adaptorOldCurve, param); + if ((param > pmin) and (param < pmax)) + { + DEBTRACE("param: " << param); + aPointsList.Append(aPoint); + } + } + + aPointsList.Append(aLastPoint); + } + + } + } } if ( aPointsList.IsEmpty() ) @@ -483,6 +610,7 @@ bool convertEdgesToSections( const TopoDS_Edge& bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape, bool IsInterpolationAllowed, + const Handle( HYDROData_PolylineXY )& theOldPolyline, bool IsClosureAllowed, double theDeviation ) { @@ -505,8 +633,9 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape, TopoDS_Edge anEdge = TopoDS::Edge( theShape ); // anIsCanBeImported = convertEdgeToSection( anEdge, aSectNames, aSectTypes, // aSectClosures, aSectPoints, true, IsInterpolationAllowed, theDeviation ); - anIsCanBeImported = convertEdgesToSections( anEdge, aSectNames, aSectTypes, - aSectClosures, aSectPoints, IsClosureAllowed, IsInterpolationAllowed, theDeviation ); + anIsCanBeImported = convertEdgesToSections( anEdge, aSectNames, aSectTypes, aSectClosures, + aSectPoints, IsClosureAllowed, IsInterpolationAllowed, + theDeviation, theOldPolyline ); } else if ( theShape.ShapeType() == TopAbs_WIRE ) { @@ -518,8 +647,9 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape, for ( int i = 1, n = anEdges.Length(); i <= n && anIsCanBeImported; ++i ) { TopoDS_Edge aWireEdge = TopoDS::Edge( anEdges.Value( i ) ); - anIsCanBeImported = convertEdgesToSections( aWireEdge, aSectNames, aSectTypes, - aSectClosures, aSectPoints, IsClosureAllowed, IsInterpolationAllowed, theDeviation ); + anIsCanBeImported = convertEdgesToSections( aWireEdge, aSectNames, aSectTypes, aSectClosures, + aSectPoints, IsClosureAllowed, IsInterpolationAllowed, + theDeviation, theOldPolyline ); } } diff --git a/src/HYDROData/HYDROData_PolylineXY.h b/src/HYDROData/HYDROData_PolylineXY.h index 39d01e72..5e050cf9 100644 --- a/src/HYDROData/HYDROData_PolylineXY.h +++ b/src/HYDROData/HYDROData_PolylineXY.h @@ -132,6 +132,7 @@ public: */ HYDRODATA_EXPORT virtual bool ImportShape( const TopoDS_Shape& theShape, bool IsInterpolationAllowed, + const Handle( HYDROData_PolylineXY )& theOldPolyline = NULL, bool IsClosureAllowed = true, double theDeviation = 1.); diff --git a/src/HYDROData/HYDROData_TopoCurve.cxx b/src/HYDROData/HYDROData_TopoCurve.cxx index 540dd8b0..a69395d4 100644 --- a/src/HYDROData/HYDROData_TopoCurve.cxx +++ b/src/HYDROData/HYDROData_TopoCurve.cxx @@ -134,7 +134,7 @@ static TopoDS_Edge ReplaceVertex( } // Projects the point to the curve. -static double ProjectPointToCurve( +double ProjectPointToCurve( const gp_XYZ& thePoint, const Adaptor3d_Curve& theCurve, double& theParameter) diff --git a/src/HYDROData/HYDROData_TopoCurve.h b/src/HYDROData/HYDROData_TopoCurve.h index bb187c0e..c707e2a5 100644 --- a/src/HYDROData/HYDROData_TopoCurve.h +++ b/src/HYDROData/HYDROData_TopoCurve.h @@ -26,14 +26,14 @@ #include #include #include -//#include -//#include +#include +#include class TopoDS_Wire; -//double ProjectPointToCurve(const gp_XYZ& thePoint, -// const Adaptor3d_Curve& theCurve, -// double& theParameter); +double ProjectPointToCurve(const gp_XYZ& thePoint, + const Adaptor3d_Curve& theCurve, + double& theParameter); //! The type represents a 1 manifold connected topo curve //! with forward orientation. -- 2.39.2