mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-11-15 10:08:35 +05:00
0019827: EDF 736 GEOM : Duplication of a object along an elliptic path
This commit is contained in:
parent
d64bb43293
commit
476c4f91de
@ -34,7 +34,12 @@
|
||||
#include <ShHealOper_EdgeDivide.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRepFill_LocationLaw.hxx>
|
||||
#include <BRepFill_Edge3DLaw.hxx>
|
||||
#include <BRepFill_SectionPlacement.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepBuilderAPI_MakeVertex.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
@ -53,6 +58,10 @@
|
||||
#include <BRepGProp.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
|
||||
#include <GeomFill_TrihedronLaw.hxx>
|
||||
#include <GeomFill_CurveAndTrihedron.hxx>
|
||||
#include <GeomFill_CorrectedFrenet.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
@ -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);
|
||||
aWire = BRepBuilderAPI_MakeWire(anEdge);
|
||||
}
|
||||
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 if ( aPath.ShapeType() == TopAbs_WIRE)
|
||||
aWire = TopoDS::Wire(aPath);
|
||||
else
|
||||
anEdge = TopoDS::Edge(Edges.Value(Edges.Length()));
|
||||
return 0;
|
||||
|
||||
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;
|
||||
Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet();
|
||||
Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw );
|
||||
Handle(BRepFill_LocationLaw) aLocation = new BRepFill_Edge3DLaw(aWire, aLocationLaw);
|
||||
|
||||
aCurTrsf.SetTranslation(aCenterMass, aPFirst);
|
||||
aTrsf.PreMultiply(aCurTrsf);
|
||||
}
|
||||
aLocation->TransformInCompatibleLaw( 0.01 );
|
||||
|
||||
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));
|
||||
//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
|
||||
anEdge = TopoDS::Edge(Edges.Value(Edges.Length() - i + 1));
|
||||
return 0;
|
||||
|
||||
aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast);
|
||||
BRep_Tool::Range(anEdge,aFirst,aLast);
|
||||
Standard_Real aParam = (aFirstParam1 + (aLastParam2 - aFirstParam1)*aParameter );
|
||||
|
||||
if (!aReversed && anEdge.Orientation() == TopAbs_REVERSED)
|
||||
aCurve = aCurve->Reversed();
|
||||
TopoDS_Shape CopyShape = aShapeBase;
|
||||
BRepFill_SectionPlacement Place( aLocation, aShapeBase );
|
||||
TopLoc_Location Loc2(Place.Transformation()), Loc1;
|
||||
Loc1 = CopyShape.Location();
|
||||
CopyShape.Location(Loc2.Multiplied(Loc1));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Perform transformation
|
||||
BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
|
||||
aShape = aBRepTrsf.Shape();
|
||||
aLocation->D0( aParam, CopyShape );
|
||||
aShape = CopyShape;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user