+ // Check input parameters
+ if ( theGuideLine.IsNull() || theProfile.IsNull() ) {
+ return false;
+ }
+
+ TopoDS_Wire aPathWire = TopoDS::Wire( theGuideLine->GetShape3D() );
+ TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetShape3D() );
+ if ( aPathWire.IsNull() || aProfileWire.IsNull() ) {
+ return false;
+ }
+
+#ifdef DEB_CHANNEL
+ BRepTools::Write( aPathWire, "guideline.brep" );
+ BRepTools::Write( aProfileWire, "profile.brep" );
+#endif
+
+ // Pre-processing
+ Handle(HYDROData_PolylineXY) aPolylineXY = theGuideLine->GetPolylineXY();
+ if ( aPolylineXY.IsNull() ) {
+ return false;
+ }
+
+ /*
+ HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
+ HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 );
+ int aNbPoints = aPolylinePoints.Length();
+ */
+
+ HYDROData_Polyline3D::Polyline3DPoints aPolylinePoints3D = theGuideLine->GetPoints();
+ int aNbPoints = aPolylinePoints3D.Length();
+ if ( aNbPoints < 2 ) {
+ return false;
+ }
+
+ // Get tangent in each point of the guide line ( 2D )
+ TColgp_Array1OfDir aTangents( 1, aNbPoints );
+
+ HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
+
+ if ( aSectionType == HYDROData_IPolyline::SECTION_POLYLINE ) {
+ for ( int i = 1; i <= aNbPoints; ++i ) {
+ gp_XYZ aPnt = aPolylinePoints3D.Value( i );
+ aPnt.SetZ( 0. );
+ gp_XYZ aPrevPnt;
+ if ( i > 1 ) {
+ aPrevPnt = aPolylinePoints3D.Value( i - 1 );
+ aPrevPnt.SetZ( 0. );
+ }
+
+ gp_Vec aDir;
+ if ( i < aNbPoints ) {
+ gp_XYZ aNextPnt = aPolylinePoints3D.Value( i + 1 );
+ aNextPnt.SetZ( 0. );
+
+ gp_Vec anEdgeVec( aPnt, aNextPnt );
+
+ if ( i == 1 ) {
+ aDir = anEdgeVec;
+ } else {
+ gp_Vec aPrevVec( aPrevPnt, aPnt );
+ aDir = aPrevVec.Normalized() + anEdgeVec.Normalized();
+ }
+ } else {
+ aDir = gp_Vec( aPrevPnt, aPnt );
+ }
+
+ aTangents.SetValue( i, aDir );
+ }
+ } else {
+ // Get curve from the first edge ( 2D )
+ TopTools_SequenceOfShape anEdges;
+ HYDROData_ShapesTool::ExploreShapeToShapes( aPolylineXY->GetShape(), TopAbs_EDGE, anEdges );
+ Standard_Real aStart, anEnd;
+
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve( TopoDS::Edge( anEdges.First() ), aStart, anEnd );
+ GeomAPI_ProjectPointOnCurve aProject;
+
+ // Get tangents
+ for ( int i = 1; i <= aNbPoints; ++i ) {
+ gp_XYZ aPointToTest = aPolylinePoints3D.Value( i );
+ aPointToTest.SetZ( 0. );
+
+ aProject.Init( aPointToTest, aCurve );
+ Quantity_Parameter aParam = aProject.LowerDistanceParameter();
+ gp_Pnt aPnt;
+ gp_Vec aDir;
+ aCurve->D1( aParam, aPnt, aDir);
+
+ aTangents.SetValue( i, aDir );
+ }
+ }
+
+ // Get the profile middle point ( 3D )
+ gp_Pnt aMiddlePoint( theProfile->GetMiddlePoint( true ) );
+
+ // Translate the profile to each point on the guide line ( 3D )
+ Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, aNbPoints );
+ Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, aNbPoints );
+ Handle(TopTools_HArray1OfShape) anArrOfProfiles = new TopTools_HArray1OfShape( 1, aNbPoints );
+
+ for ( int i = 1; i <= aNbPoints; ++i ) {
+ // Get point on the guide line
+ gp_Pnt aPointOnGuide( aPolylinePoints3D.Value( i ) );
+
+ // Define translation and rotation:
+ gp_Trsf Translation, Rotation;
+
+ // Translation
+ Translation.SetTranslation( aMiddlePoint, aPointOnGuide );
+ TopoDS_Wire aTransformedProfile =
+ TopoDS::Wire( BRepBuilderAPI_Transform( aProfileWire, Translation, Standard_True ) );
+
+ // Rotation
+ gp_Vec aVertical( 0., 0., 1. );
+ TopoDS_Vertex aLeftVertex, aRightVertex;
+ TopExp::Vertices( aTransformedProfile, aLeftVertex, aRightVertex );
+ gp_Pnt aLeftPoint = BRep_Tool::Pnt( aLeftVertex );
+ gp_Pnt aRightPoint = BRep_Tool::Pnt( aRightVertex );
+ gp_Vec aLeftToRight( aLeftPoint, aRightPoint);
+ gp_Vec NormalToProfile = aVertical ^ aLeftToRight;
+
+ gp_Vec aDir = aTangents.Value( i );
+ gp_Vec AxisOfRotation = NormalToProfile ^ aDir;
+ if (AxisOfRotation.Magnitude() <= gp::Resolution()) {
+ if ( aVertical * aLeftToRight < 0. ) {
+ gp_Ax1 theVertical(aPointOnGuide, gp::DZ() );
+ Rotation.SetRotation(theVertical, M_PI);
+ }
+ } else {
+ gp_Ax1 theAxis(aPointOnGuide, AxisOfRotation);
+ Standard_Real theAngle = NormalToProfile.AngleWithRef(aDir, AxisOfRotation);
+ Rotation.SetRotation(theAxis, theAngle);
+ }
+
+ aTransformedProfile = TopoDS::Wire(BRepBuilderAPI_Transform( aTransformedProfile, Rotation, Standard_True) );
+
+ // Get the first and the last points of the transformed profile
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices( aTransformedProfile, V1, V2 );
+
+ // Fill the data
+ anArrayOfFPnt->SetValue( i, BRep_Tool::Pnt( V1 ) );
+ anArrayOfLPnt->SetValue( i, BRep_Tool::Pnt( V2 ) );
+
+ anArrOfProfiles->SetValue( i, aTransformedProfile );
+ }
+
+ // Create presentation
+ HYDROData_Stream::PrsDefinition aPrs;
+ Handle(TopTools_HArray1OfShape) anArrOf2DProfiles; // we don't need 2D profiles for channel/digue presentation
+ bool aRes = HYDROData_Stream::CreatePresentations( anArrayOfFPnt, anArrayOfLPnt,
+ anArrOfProfiles, anArrOf2DProfiles, aPrs );
+ if ( aRes ) {
+ thePrs.myPrs3D = aPrs.myPrs3D;
+ thePrs.myPrs2D = TopoDS::Face( aPrs.myPrs2D );
+ BRepBuilderAPI_MakeWire aMakeWire( aPrs.myLeftBank ) ;
+ thePrs.myLeftBank = aMakeWire.Wire();
+ aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myRightBank );
+ thePrs.myRightBank = aMakeWire.Wire();
+ aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myInlet );
+ thePrs.myInlet = aMakeWire.Wire();
+ aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myOutlet );
+ thePrs.myOutlet = aMakeWire.Wire();
+ }
+
+ return aRes;