Skip to content

Commit

Permalink
Merge pull request #979 from DLR-SC/970-make-tiglwinginterpolatexsi-w…
Browse files Browse the repository at this point in the history
…ork-on-a-single-segment-that-is-not-part-of-a-component-segment

970 make tiglwinginterpolatexsi work on a single segment that is not part of a component segment
  • Loading branch information
joergbrech authored Jan 3, 2024
2 parents ec63eee + b9db981 commit 8918ca3
Show file tree
Hide file tree
Showing 8 changed files with 569 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/api/tigl.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2010-08-13 Markus Litz <[email protected]>
Expand Down
7 changes: 7 additions & 0 deletions src/wing/CCPACSWingComponentSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,13 @@ TopoDS_Wire CCPACSWingComponentSegment::GetCSLine(double eta1, double xsi1, doub

void CCPACSWingComponentSegment::GetSegmentIntersection(const std::string& segmentUID, double csEta1, double csXsi1, double csEta2, double csXsi2, double eta, double &xsi) const
{
// check if the segment is contained in this component segment
tigl::CCPACSWingSegment& segment = wing->GetSegment(segmentUID);

if(this->IsSegmentContained(segment) == false) {
throw CTiglError("The wing segment with UID " + segmentUID + " is not contained in this component segment.", TIGL_UID_ERROR);
}

double errorDistance = 0;
InterpolateXsi(GetUID(), EtaXsi(csEta1, csXsi1),
GetUID(), EtaXsi(csEta2, csXsi2),
Expand Down
134 changes: 86 additions & 48 deletions src/wing/tigletaxsifunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,68 +225,106 @@ void InterpolateXsi(const std::string& refUID1, const EtaXsi& etaXsi1,
throw CTiglError("Eta not in range [0,1] in InterpolateXsi.", TIGL_MATH_ERROR);
}

// make sure all uids refer to the same wing
const auto& wingcs1 = _getBelongingComponentSegment(refUID1, uidMgr);
const auto& wingcs2 = _getBelongingComponentSegment(refUID2, uidMgr);
const auto& wingcs3 = _getBelongingComponentSegment(targetUID, uidMgr);
// declare points to compute the (component) segment line
gp_Pnt p1;
gp_Pnt p2;

// declare points to compute the iso eta line of segment
gp_Pnt pLE;
gp_Pnt pTE;

std::string wingUID1;
std::string wingUID2;
std::string wingUIDTarget;

// compute the start point of the (component) segment line
if (uidMgr.IsType<CCPACSWingSegment>(refUID1)) {
const auto& segment1 = uidMgr.ResolveObject<CCPACSWingSegment>(refUID1);
p1 = segment1.GetChordPoint(etaXsi1.eta, etaXsi1.xsi);
wingUID1 = segment1.GetParent()->GetParent<CCPACSWing>()->GetUID();
}
else if (uidMgr.IsType<CCPACSWingComponentSegment>(refUID1)) {
const auto& compSeg1 = uidMgr.ResolveObject<CCPACSWingComponentSegment>(refUID1);
p1 = compSeg1.GetPoint(etaXsi1.eta, etaXsi1.xsi);
wingUID1 = compSeg1.GetParent()->GetParent()->GetUID();
}

// compute the end point of the (component) segment line
if (uidMgr.IsType<CCPACSWingSegment>(refUID2)) {
const auto& segment2 = uidMgr.ResolveObject<CCPACSWingSegment>(refUID2);
p2 = segment2.GetChordPoint(etaXsi2.eta, etaXsi2.xsi);
wingUID2 = segment2.GetParent()->GetParent<CCPACSWing>()->GetUID();
}
else if (uidMgr.IsType<CCPACSWingComponentSegment>(refUID2)) {
const auto& compSeg2 = uidMgr.ResolveObject<CCPACSWingComponentSegment>(refUID2);
p2 = compSeg2.GetPoint(etaXsi2.eta, etaXsi2.xsi);
wingUID2 = compSeg2.GetParent()->GetParent()->GetUID();
}

if (&wingcs1 != &wingcs2 || &wingcs1 != &wingcs3 || &wingcs2 != &wingcs3) {
throw CTiglError("The referenced UIDs don't lie on the same component segment in InterpolateXsi.", TIGL_UID_ERROR);
// compute the start and end point of the iso eta line
if (uidMgr.IsType<CCPACSWingSegment>(targetUID)) {
const auto& segmentTarget = uidMgr.ResolveObject<CCPACSWingSegment>(targetUID);
pLE = segmentTarget.GetChordPoint(eta, 0.);
pTE = segmentTarget.GetChordPoint(eta, 1.);
wingUIDTarget = segmentTarget.GetParent()->GetParent<CCPACSWing>()->GetUID();
}
else if (uidMgr.IsType<CCPACSWingComponentSegment>(targetUID)) {
const auto& compSegTarget = uidMgr.ResolveObject<CCPACSWingComponentSegment>(targetUID);
pLE = compSegTarget.GetPoint(eta, 0.);
pTE = compSegTarget.GetPoint(eta, 1.);
wingUIDTarget = compSegTarget.GetParent()->GetParent()->GetUID();
}

EtaXsi etaXsiOn1 = transformEtaXsiToCSOrTed(etaXsi1, refUID1, uidMgr);
EtaXsi etaXsiOn2 = transformEtaXsiToCSOrTed(etaXsi2, refUID2, uidMgr);
double etaTarget = transformEtaXsiToCSOrTed(EtaXsi(eta, 0), targetUID, uidMgr).eta;
// throw an error if the UIDs do not refer to one and the same wing
if (wingUID1 != wingUID2 || wingUID2 != wingUIDTarget) {
throw CTiglError("The referenced segments or component segments don't lie on the same wing.", TIGL_UID_ERROR);
}

// compute component segment line
gp_Pnt p1 = wingcs1.GetPoint(etaXsiOn1.eta, etaXsiOn1.xsi);
gp_Pnt p2 = wingcs1.GetPoint(etaXsiOn2.eta, etaXsiOn2.xsi);
gp_Lin csLine(p1, p2.XYZ() - p1.XYZ());
// compute (component) segment line
gp_Lin Line(p1, p2.XYZ() - p1.XYZ());

// compute iso eta line of segment
gp_Pnt pLE = wingcs3.GetPoint(etaTarget, 0.);
gp_Pnt pTE = wingcs3.GetPoint(etaTarget, 1.);
double chordDepth = pTE.Distance(pLE);
// compute iso eta line of segment
double chordDepth = pTE.Distance(pLE);
gp_Lin etaLine(pLE, pTE.XYZ() - pLE.XYZ());

gp_Lin etaLine(pLE, pTE.XYZ() - pLE.XYZ());
// check, if both lines are parallel
if (etaLine.Direction().IsParallel(Line.Direction(), M_PI/180.)) {
throw CTiglError("(Component) segment line does not intersect iso eta line of segment.", TIGL_MATH_ERROR);
}

// check, if both lines are parallel
if (etaLine.Direction().IsParallel(csLine.Direction(), M_PI/180.)) {
throw CTiglError("Component segment line does not intersect iso eta line of segment in CCPACSWingComponentSegment::GetSegmentIntersection.", TIGL_MATH_ERROR);
}
Handle(Geom_Curve) Curve = new Geom_Line(Line);
Handle(Geom_Curve) etaCurve = new Geom_Line(etaLine);
GeomAdaptor_Curve AdptAcuve(Curve);
GeomAdaptor_Curve etaAdptCurve(etaCurve);

Handle(Geom_Curve) csCurve = new Geom_Line(csLine);
Handle(Geom_Curve) etaCurve = new Geom_Line(etaLine);
GeomAdaptor_Curve csAdptAcuve(csCurve);
GeomAdaptor_Curve etaAdptCurve(etaCurve);
// find point on etaLine, that minimizes distance to Line
Extrema_ExtCC minimizer(AdptAcuve, etaAdptCurve);
minimizer.Perform();

// find point on etaLine, that minimizes distance to csLine
Extrema_ExtCC minimizer(csAdptAcuve, etaAdptCurve);
minimizer.Perform();
// there should be exactly on minimum between two lines
// if they are not parallel
if (!minimizer.IsDone() || minimizer.NbExt() != 1) {
throw CTiglError("(Component) segment line does not intersect iso eta line of segment.", TIGL_MATH_ERROR);
}

// there should be exactly on minimum between two lines
// if they are not parallel
if (!minimizer.IsDone() || minimizer.NbExt() != 1) {
throw CTiglError("Component segment line does not intersect iso eta line of segment in CCPACSWingComponentSegment::GetSegmentIntersection.", TIGL_MATH_ERROR);
}
Extrema_POnCurv pOnLine, pOnEtaLine;
minimizer.Points(1, pOnLine, pOnEtaLine);

Extrema_POnCurv pOnCSLine, pOnEtaLine;
minimizer.Points(1, pOnCSLine, pOnEtaLine);
// If parameter on Line is < 0 or larger than
// Length of Line, there is not actual intersection,
// i.e. the Line is chosen too small
// We use a tolerance here, to account for small user errors
double tol = 1e-5;
if (pOnLine.Parameter() < -tol || pOnLine.Parameter() > p1.Distance(p2) + tol) {
throw CTiglError("(Component) segment line does not intersect iso eta line of segment.", TIGL_MATH_ERROR);
}

// If parameter on CS line is < 0 or larger than
// Length of line, there is not actual intersection,
// i.e. the CS Line is chosen too small
// We use a tolerance here, to account for small user errors
double tol = 1e-5;
if (pOnCSLine.Parameter() < -tol || pOnCSLine.Parameter() > p1.Distance(p2) + tol) {
throw CTiglError("Component segment line does not intersect iso eta line of segment in CCPACSWingComponentSegment::GetSegmentIntersection.", TIGL_MATH_ERROR);
}
xsi = pOnEtaLine.Parameter()/chordDepth;

xsi = pOnEtaLine.Parameter()/chordDepth;
// compute the error distance
// This is the distance from the line to the nearest point on the chord face
errorDistance = pOnLine.Value().Distance(pOnEtaLine.Value());

// compute the error distance
// This is the distance from the line to the nearest point on the chord face
errorDistance = pOnCSLine.Value().Distance(pOnEtaLine.Value());
}

} // namespace tigl
7 changes: 4 additions & 3 deletions src/wing/tigletaxsifunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ TIGL_EXPORT double transformXsiToCSOrTed(double xsi, const std::string& referenc
TIGL_EXPORT EtaXsi transformEtaXsiToCSOrTed(EtaXsi etaXsi, const std::string& referenceUid, const CTiglUIDManager& uidMgr);

/**
* @brief Interpolates the xsi coordinate given an eta coordinate and a straight line defined by two points
* on a segment or component segment.
* @brief Interpolates the xsi coordinate given an eta coordinate of a target segment or target component segment and a straight line defined by two points
* - the first point lying on one segment or component segment and the other one lying on another segment or component segment.
* There is no need that any of the refered segments or component segments coincide, nor that a segment has to be contained in a component segment.
*
* The eta coordinate and the targetUID might refer to a component segment or to a normal wing segment
* All segments and component segments have to belong to one and the same wing.
*
* @param refUID1 Reference UID of the component referring to the first point
* @param etaXsi1 Eta / xsi coordinates of the first point
Expand Down
Loading

0 comments on commit 8918ca3

Please sign in to comment.