diff --git a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx index 2bdec65f3..7e2e1c650 100644 --- a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx @@ -34,7 +34,12 @@ #include #include #include +#include +#include +#include #include +#include +#include #include #include #include @@ -53,6 +58,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -148,179 +157,55 @@ Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const else if (aType == POSITION_ALONG_PATH) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aPathShape = aCI.GetPath(); - double aValue = aCI.GetDistance(); + Standard_Real aParameter = aCI.GetDistance(); bool aReversed = aCI.GetReverse(); + if (aReversed) + aParameter = 1 - aParameter; TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aPath = aPathShape->GetValue(); + TopoDS_Wire aWire; if (aShapeBase.IsNull() || aPath.IsNull()) return 0; - //Get a Center Of Mass Of Base Object - GProp_GProps aSystem; - gp_Pnt aCenterMass; - if (aShapeBase.ShapeType() == TopAbs_VERTEX) { - aCenterMass = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)); - } else if (aShapeBase.ShapeType() == TopAbs_EDGE || aShapeBase.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } else if (aShapeBase.ShapeType() == TopAbs_FACE || aShapeBase.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } else { - BRepGProp::VolumeProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } - - TopoDS_Shape aTrimmedPath; - gp_Trsf aTrsf; - Handle(Geom_Curve) aCurve; - Standard_Real aFirst =0.,aLast=0.; - Standard_Real aParam = 0.; - Standard_Real aLength = 0.; - - gp_Pnt aPFirst, aPLast; - - if ( aPath.ShapeType() == TopAbs_EDGE ) { // The Path is Edge + if ( aPath.ShapeType() == TopAbs_EDGE ) { TopoDS_Edge anEdge = TopoDS::Edge(aPath); - - BRep_Tool::Range(anEdge,aFirst,aLast); - aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); - if (aReversed) - aCurve = aCurve->Reversed(); - - aCurve->D0(aFirst, aPFirst); - aCurve->D0(aLast, aPLast); - - // Translate a CenterMass of Base Shape to the start of the path - if ( !aPFirst.IsEqual(aCenterMass, gp::Resolution()) ) { - gp_Trsf aCurTrsf; - aCurTrsf.SetTranslation(aCenterMass, aPFirst); - aTrsf.PreMultiply(aCurTrsf); - } - aParam = aFirst + aValue*(aLast - aFirst); // Calculate parameter - } else if ( aPath.ShapeType() == TopAbs_WIRE ) { // The path Shape is Wire - TopoDS_Wire aWire = TopoDS::Wire(aPath); - - // fix edges order - Handle(ShapeFix_Wire) aFixWire = new ShapeFix_Wire; - aFixWire->Load(aWire); - aFixWire->FixReorder(); - aWire = aFixWire->Wire(); - - TopExp_Explorer ex; - TopTools_SequenceOfShape Edges; - Standard_Real nbEdges = 0.; - BRepTools_WireExplorer aWE (aWire); - for (; aWE.More(); aWE.Next(), nbEdges++) // Explore a Wire on Edges - Edges.Append(aWE.Current()); - - Standard_Real aSummOfLen =0.; - Standard_Real aCurLen =0.; - GeomAdaptor_Curve aAdC; - - for(int i=1; i<=Edges.Length(); i++) { // Calculate summary Lenght of edges - TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i)); - BRep_Tool::Range(anEdge,aFirst,aLast); - aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); - aAdC.Load(aCurve,aFirst,aLast); - aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast); - aSummOfLen += aCurLen; - } - - // Move BaseShape to the Start Of the Curve - TopoDS_Edge anEdge; - if (!aReversed) - anEdge = TopoDS::Edge(Edges.Value(1)); - else - anEdge = TopoDS::Edge(Edges.Value(Edges.Length())); - - BRep_Tool::Range(anEdge,aFirst,aLast); - aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); - aCurve->D0(aFirst, aPFirst); - aCurve->D0(aLast, aPLast); - if ( !aPFirst.IsEqual(aCenterMass, gp::Resolution()) ) { - gp_Trsf aCurTrsf; - if (aReversed && anEdge.Orientation() == TopAbs_FORWARD) - aPFirst = aPLast; - - aCurTrsf.SetTranslation(aCenterMass, aPFirst); - aTrsf.PreMultiply(aCurTrsf); - } - - Standard_Real aWireLen = aSummOfLen*aValue; - aSummOfLen = 0; - for(int i=1; i<=Edges.Length(); i++) { - TopoDS_Edge anEdge; - if (!aReversed) - anEdge = TopoDS::Edge(Edges.Value(i)); - else - anEdge = TopoDS::Edge(Edges.Value(Edges.Length() - i + 1)); - - aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast); - BRep_Tool::Range(anEdge,aFirst,aLast); - - if (!aReversed && anEdge.Orientation() == TopAbs_REVERSED) - aCurve = aCurve->Reversed(); - - if (aReversed && anEdge.Orientation() == TopAbs_FORWARD) - aCurve = aCurve->Reversed(); - - aAdC.Load(aCurve,aFirst,aLast); - aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast); - - if ( aWireLen > (aSummOfLen + aCurLen) ) { // Transform a Base object along this Edge - aSummOfLen += aCurLen; - gp_Pnt aP1, aP2; - gp_Vec aStartVec1, aStartVec2, aDestVec1, aDestVec2; - aCurve->D2(aFirst, aP1, aStartVec1, aStartVec2 ); - aCurve->D2(aLast, aP2, aDestVec1, aDestVec2 ); - gp_Trsf aCurTrsf; - if (aStartVec2.Magnitude() > gp::Resolution() && aDestVec2.Magnitude() > gp::Resolution()) { - gp_Ax3 aStartAx3(aP1, aStartVec1, aStartVec2); - gp_Ax3 aDestAx3(aP2, aDestVec1, aDestVec2); - aCurTrsf.SetDisplacement(aStartAx3, aDestAx3); - } else - aCurTrsf.SetTranslation(aP1, aP2); - - aTrsf.PreMultiply(aCurTrsf); - } - else { - aLength = aWireLen - aSummOfLen; - GCPnts_AbscissaPoint anAbsc(aAdC,aLength,aFirst); - if(anAbsc.IsDone()) - aParam = anAbsc.Parameter(); - break; - } - } - } else - return 0; // Unknown Type - - gp_Trsf aCurTrsf; - gp_Pnt aP1, aP2; - gp_Vec aStartVec1, aStartVec2, aDestVec1, aDestVec2; - aCurve->D2(aFirst, aP1, aStartVec1, aStartVec2 ); - aCurve->D2(aParam, aP2, aDestVec1, aDestVec2 ); - - if (aStartVec2.Magnitude() > gp::Resolution() && aDestVec2.Magnitude() > gp::Resolution()) { - gp_Ax3 aStartAx3(aP1, aStartVec1, aStartVec2); - gp_Ax3 aDestAx3(aP2, aDestVec1, aDestVec2); - aCurTrsf.SetDisplacement(aStartAx3, aDestAx3); - } else - aCurTrsf.SetTranslation(aP1, aP2); - - aTrsf.PreMultiply(aCurTrsf); - - if ( !aPFirst.IsEqual(aCenterMass, gp::Resolution()) ) { - gp_Trsf aCurTrsf; - aCurTrsf.SetTranslation(aPFirst, aCenterMass); - aTrsf.PreMultiply(aCurTrsf); + aWire = BRepBuilderAPI_MakeWire(anEdge); } + else if ( aPath.ShapeType() == TopAbs_WIRE) + aWire = TopoDS::Wire(aPath); + else + return 0; - // Perform transformation - BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); - aShape = aBRepTrsf.Shape(); + Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet(); + Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw ); + Handle(BRepFill_LocationLaw) aLocation = new BRepFill_Edge3DLaw(aWire, aLocationLaw); + + aLocation->TransformInCompatibleLaw( 0.01 ); + + //Calculate a Parameter + Standard_Real aFirstParam1 = 0, aLastParam1 = 0; // Parameters of the First edge + Standard_Real aFirstParam2 = 0, aLastParam2 = 0; // Parameters of the Last edge + aLocation->CurvilinearBounds(aLocation->NbLaw(), aFirstParam2, aLastParam2); + + if ( aLocation->NbLaw() > 1) + aLocation->CurvilinearBounds(1, aFirstParam1, aLastParam1); + else if ( aLocation->NbLaw() == 1 ) + aFirstParam1 = aFirstParam2; + else + return 0; + + Standard_Real aParam = (aFirstParam1 + (aLastParam2 - aFirstParam1)*aParameter ); + + TopoDS_Shape CopyShape = aShapeBase; + BRepFill_SectionPlacement Place( aLocation, aShapeBase ); + TopLoc_Location Loc2(Place.Transformation()), Loc1; + Loc1 = CopyShape.Location(); + CopyShape.Location(Loc2.Multiplied(Loc1)); + + aLocation->D0( aParam, CopyShape ); + aShape = CopyShape; } else return 0;