Skip to content

Commit

Permalink
Merge pull request #1015 from DLR-SC/745-issue_kinks_guides
Browse files Browse the repository at this point in the history
Consistent implementation for combining fuselage guide curves and kinks
  • Loading branch information
joergbrech authored Jul 31, 2024
2 parents 8f02c5b + 967c6c1 commit a334bd3
Show file tree
Hide file tree
Showing 28 changed files with 1,598 additions and 103 deletions.
56 changes: 38 additions & 18 deletions cpacs_gen_input/cpacs_schema.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -13790,31 +13790,51 @@ The fuel tank volume type should also be used for the wing fuel tank</xsd:docume
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="fromRelativeCircumference" type="doubleBaseType">
<xsd:sequence>
<xsd:choice>
<xsd:element name="fromRelativeCircumference" type="doubleBaseType">
<xsd:annotation>
<xsd:documentation>Reference to the relative circumference
position from which the guide curve shall start. Valid values
are in the interval -1.0...1.0.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="fromParameter" type="doubleBaseType">
<xsd:annotation>
<xsd:documentation>Reference to the parameter
position from which the guide curve shall start. Valid values
are in the interval -1.0...1.0.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:element minOccurs="0" name="tangent" type="pointXYZType">
<xsd:annotation>
<xsd:documentation>Reference to the relative circumference
position from which the guide curve shall start. Valid values
<xsd:documentation>Tangent at first point</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:choice>
<xsd:sequence>
<xsd:choice>
<xsd:element name="toRelativeCircumference" type="doubleBaseType">
<xsd:annotation>
<xsd:documentation>The relative circumference
position at which the guide curve shall end. Valid values
are in the interval -1.0...1.0.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element minOccurs="0" name="tangent" type="pointXYZType">
</xsd:element>
<xsd:element name="toParameter" type="doubleBaseType">
<xsd:annotation>
<xsd:documentation>Tangent at first point</xsd:documentation>
<xsd:documentation>The parameter
position at which the guide curve shall end. Valid values
are in the interval -1.0...1.0.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:choice>
<xsd:sequence>
<xsd:element name="toRelativeCircumference" type="doubleBaseType">
<xsd:annotation>
<xsd:documentation>The relative circumference
position at which the guide curve shall end. Valid values
are in the interval -1.0...1.0.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:element minOccurs="0" name="tangent" type="pointXYZType">
<xsd:annotation>
<xsd:documentation>Tangent at last point</xsd:documentation>
Expand Down
17 changes: 17 additions & 0 deletions src/common/tiglcommonfunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,23 @@ void EdgeGetPointTangent(const TopoDS_Edge& edge, double alpha, gp_Pnt& point, g
}
}

void EdgeGetPointTangentBasedOnParam(const TopoDS_Edge& edge, double alpha, gp_Pnt& point, gp_Vec& tangent)
{
// ETA 3D point
Standard_Real umin, umax;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, umin, umax);

if (alpha < umin || alpha > umax) {
throw tigl::CTiglError("Parameter alpha not in the range umin <= alpha <= umax in EdgeGetPointTangent", TIGL_ERROR);
}

GeomAdaptor_Curve adaptorCurve(curve, umin, umax);
Standard_Real len = GCPnts_AbscissaPoint::Length( adaptorCurve, umin, umax );
adaptorCurve.D1( alpha, point, tangent );
// normalize tangent to length of the curve
tangent = len*tangent/tangent.Magnitude();
}

Standard_Real ProjectPointOnWire(const TopoDS_Wire& wire, gp_Pnt p)
{
return ProjectPointOnWireAtAngle(wire, p, gp_Dir(1,0,0), M_PI/2.);
Expand Down
1 change: 1 addition & 0 deletions src/common/tiglcommonfunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ TIGL_EXPORT gp_Pnt GetLastPoint(const TopoDS_Edge& e);

TIGL_EXPORT gp_Pnt EdgeGetPoint(const TopoDS_Edge& edge, double alpha);
TIGL_EXPORT void EdgeGetPointTangent(const TopoDS_Edge& edge, double alpha, gp_Pnt& point, gp_Vec& normal);
TIGL_EXPORT void EdgeGetPointTangentBasedOnParam(const TopoDS_Edge& edge, double alpha, gp_Pnt& point, gp_Vec& tangent);

// calculates the alpha value for a given point on a wire
TIGL_EXPORT Standard_Real ProjectPointOnWire(const TopoDS_Wire& wire, gp_Pnt p);
Expand Down
47 changes: 39 additions & 8 deletions src/fuselage/CCPACSFuselageProfileGetPointAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "TopExp_Explorer.hxx"
#include "TopoDS.hxx"
#include "tiglcommonfunctions.h"
#include "CCPACSGuideCurve.h"

namespace tigl
{
Expand All @@ -53,10 +54,33 @@ CCPACSFuselageProfileGetPointAlgo::CCPACSFuselageProfileGetPointAlgo (const TopT
wireLength = GetLength(wire);
}

void CCPACSFuselageProfileGetPointAlgo::GetPointTangent(const double& alpha, gp_Pnt& point, gp_Vec& tangent)
void CCPACSFuselageProfileGetPointAlgo::GetPointTangent(const double& alpha, gp_Pnt& point,
gp_Vec& tangent, const CCPACSGuideCurve::FromOrToDefinition& fromOrToDefinition)
{
// alpha<0.0 : use line in the direction of the tangent at alpha=0.0
if (alpha<0.0) {
Standard_Real umin, umax;
TopoDS_Edge edge;
if (fromOrToDefinition == CCPACSGuideCurve::FromOrToDefinition::PARAMETER) {
// For some reasons, the choice of wire as shape to choose the parameter on, did not work.
// <BRepAdaptor_CompCurve>.D1( alpha, point, tangent) based on a wire did not produce the expected result.
// That is why, the first edge is extracted. It is implicitely assumed that the wire consists of exactly one edge.
// More than one edge might lead to unexpected result when used in combination with PARAMETER
if (GetNumberOfEdges(wire) > 1) {
LOG(WARNING) << "CCPACSFuselageProfileGetPointAlgo::GetPointTangent: Defining start or end point of guide curve via parameter on wires consisting of 2 or more edges might lead to unexpected results.";
}
// Get parameter range of edge
edge = GetEdge(wire, 0);
BRep_Tool::Range(edge, umin, umax);
}
else if (fromOrToDefinition == CCPACSGuideCurve::FromOrToDefinition::CIRCUMFERENCE || fromOrToDefinition == CCPACSGuideCurve::FromOrToDefinition::UID) {
umin = 0.;
umax = 1.;
}
else {
throw CTiglError("CCPACSFuselageProfileGetPointAlgo::GetPointTangent(): Either a from/toCircumference, a from/toParameter or a from/toGuideCurveUID must be present", TIGL_NOT_FOUND);
}

// alpha<umin : use line in the direction of the tangent at alpha=umin
if (alpha<umin) {
// get startpoint
gp_Pnt startpoint;
WireGetPointTangent(wire, 0.0, startpoint, tangent);
Expand All @@ -66,17 +90,24 @@ void CCPACSFuselageProfileGetPointAlgo::GetPointTangent(const double& alpha, gp_
gp_Dir dir(-1.0*tangent);
// construct line
Geom_Line line(startpoint, dir);
// map [-infinity, 0.0] to [0.0, infinity] and scale by profile length
// map [-infinity, umin] to [umin, infinity] and scale by profile length
Standard_Real zeta = wireLength*(-1.0*alpha);
// get point on line at distance zeta from the start point
line.D0(zeta, point);
}
else if (alpha>=0.0 && alpha<=1.0) {
WireGetPointTangent(wire, alpha, point, tangent);
else if (alpha>=umin && alpha<=umax) {

// When the alpha is based on the parameter (and not on the circumference), a different way of computing the point (and therefore tangent) is chosen
if (fromOrToDefinition == CCPACSGuideCurve::FromOrToDefinition::PARAMETER) {
EdgeGetPointTangentBasedOnParam(edge, alpha, point, tangent);
}
else {
WireGetPointTangent(wire, alpha, point, tangent);
}
// length of tangent has to be equal two the length of the profile curve
tangent = wireLength * tangent/tangent.Magnitude();
}
// alpha>1.0 : use line in the direction of the tangent at alpha=1.0
// alpha>umax : use line in the direction of the tangent at alpha=umax
else {
// get startpoint
gp_Pnt startpoint;
Expand All @@ -87,7 +118,7 @@ void CCPACSFuselageProfileGetPointAlgo::GetPointTangent(const double& alpha, gp_
gp_Dir dir(tangent);
// construct line
Geom_Line line(startpoint, dir);
// map [1.0, infinity] to [0.0, infinity] and scale by profile length
// map [umax, infinity] to [umin, infinity] and scale by profile length
Standard_Real zeta = wireLength*(alpha - 1.0);
// get point on line at distance zeta from the start point
line.D0(zeta, point);
Expand Down
5 changes: 4 additions & 1 deletion src/fuselage/CCPACSFuselageProfileGetPointAlgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "TopTools_SequenceOfShape.hxx"
#include "gp_Pnt.hxx"
#include "gp_Vec.hxx"
#include "CCPACSGuideCurve.h"

#ifndef CCPACSFUSELAGEPROFILEGETPOINTALGO_H
#define CCPACSFUSELAGEPROFILEGETPOINTALGO_H
Expand All @@ -57,8 +58,10 @@ class CCPACSFuselageProfileGetPointAlgo
*
* \param point Point on the profile corresponding to the parameter alpha
* \param tangent Tangent on the profile corresponding to the parameter alpha
* \param fromOrToDefinition Define the basis on which the point on the curve should be found (circumference or parameter)
*/
TIGL_EXPORT void GetPointTangent(const double& alpha, gp_Pnt& point, gp_Vec& tangent);
TIGL_EXPORT void GetPointTangent(const double& alpha, gp_Pnt& point,
gp_Vec& tangent, const CCPACSGuideCurve::FromOrToDefinition& fromOrToDefinition=CCPACSGuideCurve::FromOrToDefinition::CIRCUMFERENCE);

private:
TopoDS_Wire wire; /**< Wire of the fuselage profile */
Expand Down
11 changes: 10 additions & 1 deletion src/fuselage/CCPACSFuselageSegments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,16 @@ void CCPACSFuselageSegments::BuildGuideCurves(TopoDS_Compound& cache) const
const CCPACSGuideCurve& curve = segmentCurves.GetGuideCurve(iguide);
if (!curve.GetFromGuideCurveUID_choice1()) {
// this is a root curve
double relCirc= *curve.GetFromRelativeCircumference_choice2();
double relCirc;
if (curve.GetFromRelativeCircumference_choice2_1()) {
relCirc = *curve.GetFromRelativeCircumference_choice2_1();
}
else if(curve.GetFromParameter_choice2_2()) {
relCirc = *curve.GetFromParameter_choice2_2();
}
else {
throw CTiglError("CCPACSFuselageSegments::BuildGuideCurves(): Either a fromCircumference or a fromParameter must be present", TIGL_NOT_FOUND);
}
//TODO: determine if half fuselage or not. If not
//the guide curve at relCirc=1 should be inserted at relCirc=0
roots.insert(std::make_pair(relCirc, &curve));
Expand Down
24 changes: 17 additions & 7 deletions src/fuselage/CTiglFuselageSegmentGuidecurveBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,22 @@ std::vector<gp_Pnt> CTiglFuselageSegmentGuidecurveBuilder::BuildGuideCurvePnts(c
double outerScale = GetLength(outerChordLineWire);


// get relative circumference of inner profile
double fromRelativeCircumference = guideCurve->GetFromRelativeCircumference();
// get relative circumference or parameter value of inner profile (depending on chosen CPACS node)
double fromDefinitionValue = guideCurve->GetFromDefinitionValue();
// get relative circumference or parameter value of outer profile (depending on chosen CPACS node)
double toDefinitionValue = guideCurve->GetToDefinitionValue();

// get relative circumference of outer profile
double toRelativeCircumference = guideCurve->GetToRelativeCircumference();
// get guide curve profile UID
std::string guideCurveProfileUID = guideCurve->GetGuideCurveProfileUID();

// decide whether the guide curve's starting point is defined based on circumference or parameter
CCPACSGuideCurve::FromOrToDefinition fromDefinition = guideCurve->GetFromDefinition();
// decide whether the guide curve's end point is defined based on circumference or parameter
CCPACSGuideCurve::FromOrToDefinition toDefinition = guideCurve->GetToDefinition();
if (toDefinition == CCPACSGuideCurve::FromOrToDefinition::UID) {
throw CTiglError("CTiglFuselageSegmentGuidecurveBuilder::BuildGuideCurvePnts(): toDefinition must not be UID", TIGL_NOT_FOUND);
}

// get guide curve profile
CCPACSConfiguration const& config = m_segment.GetParent()->GetConfiguration();
CCPACSGuideCurveProfile const& guideCurveProfile = config.GetGuideCurveProfile(guideCurveProfileUID);
Expand All @@ -102,12 +110,14 @@ std::vector<gp_Pnt> CTiglFuselageSegmentGuidecurveBuilder::BuildGuideCurvePnts(c
// construct guide curve algorithm
std::vector<gp_Pnt> guideCurvePnts = CCPACSGuideCurveAlgo<CCPACSFuselageProfileGetPointAlgo> (startWireContainer,
endWireContainer,
fromRelativeCircumference,
toRelativeCircumference,
fromDefinitionValue,
toDefinitionValue,
innerScale,
outerScale,
rxDir,
guideCurveProfile);
guideCurveProfile,
fromDefinition,
toDefinition);
return guideCurvePnts;
}

Expand Down
Loading

0 comments on commit a334bd3

Please sign in to comment.