0019827: EDF 736 GEOM : Duplication of a object along an elliptic path

This commit is contained in:
dmv 2009-02-25 12:03:38 +00:00
parent d64bb43293
commit 476c4f91de

View File

@ -34,7 +34,12 @@
#include <ShHealOper_EdgeDivide.hxx> #include <ShHealOper_EdgeDivide.hxx>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
#include <BRepFill_LocationLaw.hxx>
#include <BRepFill_Edge3DLaw.hxx>
#include <BRepFill_SectionPlacement.hxx>
#include <BRepTools_WireExplorer.hxx> #include <BRepTools_WireExplorer.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx> #include <TopoDS_Vertex.hxx>
@ -53,6 +58,10 @@
#include <BRepGProp.hxx> #include <BRepGProp.hxx>
#include <ShapeFix_Wire.hxx> #include <ShapeFix_Wire.hxx>
#include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <gp_Vec.hxx> #include <gp_Vec.hxx>
@ -148,179 +157,55 @@ Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const
else if (aType == POSITION_ALONG_PATH) { else if (aType == POSITION_ALONG_PATH) {
Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aRefShape = aCI.GetShape();
Handle(GEOM_Function) aPathShape = aCI.GetPath(); Handle(GEOM_Function) aPathShape = aCI.GetPath();
double aValue = aCI.GetDistance(); Standard_Real aParameter = aCI.GetDistance();
bool aReversed = aCI.GetReverse(); bool aReversed = aCI.GetReverse();
if (aReversed)
aParameter = 1 - aParameter;
TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aShapeBase = aRefShape->GetValue();
TopoDS_Shape aPath = aPathShape->GetValue(); TopoDS_Shape aPath = aPathShape->GetValue();
TopoDS_Wire aWire;
if (aShapeBase.IsNull() || aPath.IsNull()) if (aShapeBase.IsNull() || aPath.IsNull())
return 0; return 0;
//Get a Center Of Mass Of Base Object if ( aPath.ShapeType() == TopAbs_EDGE ) {
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
TopoDS_Edge anEdge = TopoDS::Edge(aPath); TopoDS_Edge anEdge = TopoDS::Edge(aPath);
aWire = BRepBuilderAPI_MakeWire(anEdge);
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);
} }
else if ( aPath.ShapeType() == TopAbs_WIRE)
aWire = TopoDS::Wire(aPath);
else
return 0;
// Perform transformation Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet();
BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw );
aShape = aBRepTrsf.Shape(); 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 else
return 0; return 0;