Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve: Enable to use more than 3 wing guide curves #748

Merged
merged 36 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
97317ee
Correctly map wing surface names in case of more than 3 guide curves
rainman110 Jun 4, 2020
6d3c4e1
Fixed compilation with g++
rainman110 Jun 4, 2020
7a7cf22
Removed log message
rainman110 Jun 4, 2020
3b7ff53
Fixed face names of wing segment
rainman110 Jun 4, 2020
48dcdc0
fixed bug in TiGL Viewer
rainman110 Jun 6, 2020
c6ec8d5
Added functions to match knots of surfaces
rainman110 Oct 7, 2020
dd1486c
Added some geometry functions to python bindings
rainman110 Oct 7, 2020
ed8a4e3
Added function to change parametrization of surfaces
rainman110 Oct 8, 2020
99a9c6b
Added surface concatenation algorithm
rainman110 Oct 8, 2020
e21a6be
Added tests for concatCurvesU
rainman110 Oct 8, 2020
42330c9
Added very simple surface approximation algorithm
rainman110 Oct 8, 2020
6d3c74c
Added test for surface approximation
rainman110 Oct 8, 2020
814347a
Fixed a bug
rainman110 Oct 8, 2020
f0bd217
Added algorithm to concat multiple surfaces
rainman110 Oct 9, 2020
ab2974d
Extended CTiglTransformation to transform surfaces
rainman110 Oct 9, 2020
b4a0ee9
Set cpp11 requirement for tigl_3cpp target
rainman110 Oct 9, 2020
28e3709
Concatenate surfaces to make getpoint working
rainman110 Oct 9, 2020
30ead36
Fixed bug
rainman110 Oct 9, 2020
cabb148
Added cpacs test file
rainman110 Oct 12, 2020
6d8491d
Some code improvements
rainman110 Oct 12, 2020
9aaebd1
Shuffled guide curves
rainman110 Oct 12, 2020
0989e7e
Added test case for surface transformation
rainman110 Oct 12, 2020
7a090aa
Some simplification
rainman110 Oct 12, 2020
76fb237
Added one more test case
rainman110 Oct 12, 2020
d11160b
Added tests for concatsurface class
rainman110 Oct 12, 2020
42e810c
Moved unused code into ifdef
rainman110 Oct 12, 2020
d799916
Removed dead code
rainman110 Oct 15, 2020
4c0b203
Moved FindIndex and Contains to tiglcommonfunctions.h
rainman110 Oct 15, 2020
650c689
Added tests and documentation for new functions
rainman110 Oct 15, 2020
70ddea2
Fixed copy & paste error
rainman110 Oct 15, 2020
e73737f
Renamed function approxSurface to makeKnotsUniform
rainman110 Oct 15, 2020
936699a
Removed duplicate code in createCommonKnotsVectorSurface
rainman110 Oct 15, 2020
61a00c1
Avoid code duplication of guide curve start parameters
rainman110 Oct 15, 2020
845036f
Fixed code according to comments
rainman110 Oct 15, 2020
57bdbf3
Changed code to comply with tolerance at other places
rainman110 Oct 15, 2020
fcd82a3
Fixed warnings
rainman110 Oct 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions TIGLViewer/src/TIGLScriptEngine.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <utility>

/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
Expand Down
11 changes: 1 addition & 10 deletions TIGLViewer/src/TIGLViewerDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1969,16 +1969,7 @@ void TIGLViewerDocument::drawWingComponentSegment()
return;
}

for (int i = 1; i <= GetConfiguration().GetWingCount();++i) {
tigl::CCPACSWing& wing = GetConfiguration().GetWing(i);
for (int j = 1; j <= wing.GetComponentSegmentCount();++j) {
auto& segment = static_cast<tigl::CCPACSWingComponentSegment&>(wing.GetComponentSegment(j));
if (segment.GetUID() == csUid.toStdString()) {
drawWingComponentSegment(segment);
break;
}
}
}
drawComponentByUID(csUid);
}

void TIGLViewerDocument::drawWingComponentSegmentPoints()
Expand Down
6 changes: 6 additions & 0 deletions bindings/python_internal/geometry.i
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
#include "CTiglIntersectBSplines.h"
#include "CTiglInterpolatePointsWithKinks.h"
#include "CTiglApproxResult.h"
#include "SurfTools.hxx"
#include "CTiglConcatSurfaces.h"
%}


Expand All @@ -80,7 +82,9 @@

%template(CPointContainer) std::vector<gp_Pnt>;
%template(BSplineCurveList) std::vector<Handle_Geom_BSplineCurve>;
%template(BSplineSurfaceList) std::vector<Handle_Geom_BSplineSurface>;
%template(CurveList) std::vector<Handle_Geom_Curve>;
%template(SurfaceList) std::vector<Handle_Geom_Surface>;
%template(CurveIntersectionResultList) std::vector<tigl::CurveIntersectionResult>;

%boost_optional(tigl::CCPACSPointAbsRel)
Expand All @@ -89,6 +93,8 @@
%boost_optional(tigl::generated::CPACSPointX)
%boost_optional(tigl::generated::CPACSPointXYZ)

%include "CTiglConcatSurfaces.h"
%include "SurfTools.hxx"
%include "CTiglApproxResult.h"
%include "CTiglIntersectBSplines.h"
%include "CTiglPointsToBSplineInterpolation.h"
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ endforeach()

# object library containing just the compiled sources
add_library(tigl3_objects OBJECT ${TIGL_SRC})
target_compile_features(tigl3_objects PRIVATE cxx_std_11)
set_property(TARGET tigl3_objects PROPERTY POSITION_INDEPENDENT_CODE ON) # needed for shared libraries

target_include_directories(tigl3_objects
Expand Down Expand Up @@ -207,6 +208,7 @@ target_include_directories(tigl3_cpp INTERFACE
)

target_link_libraries(tigl3_cpp INTERFACE ${OpenCASCADE_LIBRARIES} Boost::boost Boost::disable_autolinking)
target_compile_features(tigl3_cpp INTERFACE cxx_std_11)

if (TARGET glog::glog)
target_link_libraries (tigl3_cpp INTERFACE glog::glog)
Expand Down
38 changes: 38 additions & 0 deletions src/common/tiglcommonfunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,44 @@ size_t IndexFromUid(const std::vector<std::unique_ptr<T> >& vectorOfPointers, co
return found - vectorOfPointers.begin();
}

/**
* @brief Searches for a entry in a range and returns its index
*
* This function can be used with std::arrays, std::vectors
* and also possible other containers supported by std::distance
*
* If the index is not found, the size of the range will be returned instead
*/
template <typename ForwardIter, typename Compare>
size_t FindIndex(ForwardIter begin, ForwardIter end, Compare comp)
{
const auto it = std::find_if(begin, end, comp);
if (it != end) {
return std::distance(begin, it);
}
else {
return std::distance(begin, end);
}
}

/**
* @brief Checks, whether an array contains a value or not
*
* @param array The array to be searched in
* @param val The value to be saerched for
* @param tolerance This functions is typically used with floating point values. The tolerance allows
* to search for a value within the specified tolerance.
*/
template <typename ArrayLike, typename ValueType>
bool Contains(const ArrayLike& array, ValueType val, ValueType tolerance)
{
auto idx = FindIndex(std::begin(array), std::end(array), [val, tolerance](const typename ArrayLike::value_type& cval) {
return fabs(cval - val) < tolerance;
});

return idx < array.size();
}

template <class ArrayType, typename BinaryPredicate, typename BinaryMerge>
void ReplaceAdjacentWithMerged(ArrayType& list, BinaryPredicate is_adjacent, BinaryMerge merged)
{
Expand Down
174 changes: 164 additions & 10 deletions src/geometry/CTiglBSplineAlgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "CTiglPointsToBSplineInterpolation.h"
#include "to_string.h"
#include "tiglcommonfunctions.h"
#include "Debugging.h"

#include <Standard_Version.hxx>
#include <Geom2d_BSplineCurve.hxx>
Expand Down Expand Up @@ -534,24 +535,24 @@ std::vector<Handle(Geom_BSplineCurve)> CTiglBSplineAlgorithms::createCommonKnots
return std::vector<Handle(Geom_BSplineCurve)>(splines_adapter.begin(), splines_adapter.end());
}

std::vector<Handle(Geom_BSplineSurface) > CTiglBSplineAlgorithms::createCommonKnotsVectorSurface(const std::vector<Handle(Geom_BSplineSurface) >& old_surfaces_vector)
std::vector<Handle(Geom_BSplineSurface) > CTiglBSplineAlgorithms::createCommonKnotsVectorSurface(const std::vector<Handle(Geom_BSplineSurface) >& old_surfaces_vector, SurfaceDirection dir)
{
// all B-spline surfaces must have the same parameter range in u- and v-direction
// TODO: Match parameter range

// Create a copy that we can modify
std::vector<SurfAdapterView> adapterSplines;
for (size_t i = 0; i < old_surfaces_vector.size(); ++i) {
adapterSplines.push_back(SurfAdapterView(Handle(Geom_BSplineSurface)::DownCast(old_surfaces_vector[i]->Copy()), udir));
}

// first in u direction
makeGeometryCompatibleImpl(adapterSplines, 1e-15);

for (size_t i = 0; i < old_surfaces_vector.size(); ++i) adapterSplines[i].setDir(vdir);
if (dir == SurfaceDirection::u || dir == SurfaceDirection::both) {
// first in u direction
makeGeometryCompatibleImpl(adapterSplines, 1e-14);
}

// now in v direction
makeGeometryCompatibleImpl(adapterSplines, 1e-15);
if (dir == SurfaceDirection::v || dir == SurfaceDirection::both) {
// now in v direction
for (size_t i = 0; i < old_surfaces_vector.size(); ++i) adapterSplines[i].setDir(vdir);
makeGeometryCompatibleImpl(adapterSplines, 1e-14);
}

return std::vector<Handle(Geom_BSplineSurface)>(adapterSplines.begin(), adapterSplines.end());
}
Expand Down Expand Up @@ -818,6 +819,23 @@ void CTiglBSplineAlgorithms::reparametrizeBSpline(Geom_BSplineCurve& spline, dou
}
}

void CTiglBSplineAlgorithms::reparametrizeBSpline(Geom_BSplineSurface& spline, double umin, double umax, double vmin, double vmax, double tol)
rainman110 marked this conversation as resolved.
Show resolved Hide resolved
{
if (std::abs(spline.UKnot(1) - umin) > tol || std::abs(spline.UKnot(spline.NbUKnots()) - umax) > tol) {
TColStd_Array1OfReal aKnots (1, spline.NbUKnots());
spline.UKnots (aKnots);
BSplCLib::Reparametrize (umin, umax, aKnots);
spline.SetUKnots (aKnots);
}

if (std::abs(spline.VKnot(1) - vmin) > tol || std::abs(spline.VKnot(spline.NbVKnots()) - vmax) > tol) {
TColStd_Array1OfReal aKnots (1, spline.NbVKnots());
spline.VKnots (aKnots);
BSplCLib::Reparametrize (vmin, vmax, aKnots);
spline.SetVKnots (aKnots);
}
}

CTiglApproxResult CTiglBSplineAlgorithms::reparametrizeBSplineNiceKnots(Handle(Geom_BSplineCurve) spline)
{
if (spline.IsNull()) {
Expand Down Expand Up @@ -1139,4 +1157,140 @@ Handle(Geom_BSplineCurve) CTiglBSplineAlgorithms::concatCurves(std::vector<Handl
return result;
}

Handle(Geom_BSplineSurface) CTiglBSplineAlgorithms::concatSurfacesUDir(Handle(Geom_BSplineSurface) bspl1,
Handle(Geom_BSplineSurface) bspl2,
double space_tol)
{

DEBUG_SCOPE(debug);
debug.addShape(BRepBuilderAPI_MakeFace(bspl1, 1e-6).Face(), "surf1");
debug.addShape(BRepBuilderAPI_MakeFace(bspl2, 1e-6).Face(), "surf2");

// the surfaces must not be periodic in u direction
assert (bspl1->IsUPeriodic() == false);
assert (bspl2->IsUPeriodic() == false);

// we dont have nurbs implemented right now
assert (bspl1->IsURational() == false);
assert (bspl2->IsURational() == false);
assert (bspl1->IsVRational() == false);
assert (bspl2->IsVRational() == false);

double param_tol = 1e-14;

// check that surfaces are following parametrically
double umin1, umax1, vmin1, vmax1;
bspl1->Bounds(umin1, umax1, vmin1, vmax1);
double umin2, umax2, vmin2, vmax2;
bspl2->Bounds(umin2, umax2, vmin2, vmax2);

if (std::abs(umax1 - umin2) > param_tol) {
std::stringstream str;
str << "Surfaces do not follow in u-parametric direction in CTiglBSplineAlgorithms::concatSurfacesUDir. ";
str << "Surface 1 ends at " << umax1 << ", Surface 2 begins at " << umin2 << "!";
throw CTiglError(str.str(), TIGL_MATH_ERROR);
}

bspl1->SetVNotPeriodic();
bspl2->SetVNotPeriodic();

auto u_degree = std::max(bspl1->UDegree(), bspl2->UDegree());
auto v_degree = std::max(bspl1->VDegree(), bspl2->VDegree());

bspl1->IncreaseDegree(u_degree, v_degree);
bspl2->IncreaseDegree(u_degree, v_degree);

// check that corner points match
auto leftCornerDist = bspl1->Value(umax1, vmin1).Distance(bspl2->Value(umin2, vmin2));
auto rightCornerDist = bspl1->Value(umax1, vmax1).Distance(bspl2->Value(umin2, vmax2)) ;
if (leftCornerDist > space_tol || rightCornerDist > space_tol) {
throw CTiglError("Surfaces don't match within tolerances in CTiglBSplineAlgorithms::concatSurfacesUDir.", TIGL_MATH_ERROR);
}

auto spl_vec = CTiglBSplineAlgorithms::createCommonKnotsVectorSurface({bspl1, bspl2}, SurfaceDirection::v);
bspl1 = spl_vec[0];
bspl2 = spl_vec[1];

assert(bspl1->NbVPoles() == bspl2->NbVPoles());

// concat control points
TColgp_Array2OfPnt cpsNew(1, bspl1->NbUPoles() + bspl2->NbUPoles() - 1, 1, bspl1->NbVPoles());
for (int iv = 0; iv < bspl1->NbVPoles(); ++iv) {
for (int iu = 0; iu < bspl1->NbUPoles() - 1; ++iu) {
cpsNew.SetValue(iu+1, iv+1, bspl1->Pole(iu+1, iv+1));
}
auto offset = bspl1->NbUPoles();
for (int iu = 0; iu < bspl2->NbUPoles(); ++iu) {
cpsNew.SetValue(iu + offset, iv+1, bspl2->Pole(iu+1, iv+1));
}
}

// concat knots and mults
TColStd_Array1OfReal uknots_new(1, bspl1->NbUKnots() + bspl2->NbUKnots() - 1);
TColStd_Array1OfInteger umults_new(1, bspl1->NbUKnots() + bspl2->NbUKnots() - 1);

for (int i = 0; i < bspl1->NbUKnots()-1; ++i) {
uknots_new.SetValue(i+1, bspl1->UKnot(i+1));
umults_new.SetValue(i+1, bspl1->UMultiplicity(i+1));
}

int middleIdx = bspl1->NbUKnots();
uknots_new.SetValue(middleIdx, 0.5 * (bspl1->UKnot(middleIdx) + bspl2->UKnot(1)));
umults_new.SetValue(middleIdx, bspl1->UMultiplicity(middleIdx) - 1);

for (int i = 1; i < bspl2->NbUKnots(); ++i) {
uknots_new.SetValue(i + middleIdx, bspl2->UKnot(i+1));
umults_new.SetValue(i + middleIdx, bspl2->UMultiplicity(i+1));
}

// we simply take the v-knots of the first spline
TColStd_Array1OfReal vknots_new(1, bspl1->NbVKnots());
TColStd_Array1OfInteger vmults_new(1, bspl1->NbVKnots());
bspl1->VKnots(vknots_new);
bspl1->VMultiplicities(vmults_new);

#ifdef DEBUG
int sum_umults = 0;
for (int i = umults_new.Lower(); i <= umults_new.Upper(); ++i) {
sum_umults += umults_new.Value(i);
}

int sum_vmults = 0;
for (int i = vmults_new.Lower(); i <= vmults_new.Upper(); ++i) {
sum_vmults += vmults_new.Value(i);
}

assert(cpsNew.ColLength() + u_degree + 1 == sum_umults);
assert(cpsNew.RowLength() + v_degree + 1 == sum_vmults);
#endif

return new Geom_BSplineSurface(cpsNew, uknots_new, vknots_new,
umults_new, vmults_new,
u_degree, v_degree, false, false);
}

Handle(Geom_BSplineSurface) CTiglBSplineAlgorithms::makeKnotsUniform(Handle(Geom_BSplineSurface) surf, unsigned int nseg_u, unsigned int nseg_v)
{
double u1, u2, v1, v2;
surf->Bounds(u1, u2, v1, v2);

// we create a degree 3 approximation in all directions
auto ncp_u = std::max(4, static_cast<int>(nseg_u + 1));
auto ncp_v = std::max(4, static_cast<int>(nseg_v + 1));

auto u = LinspaceWithBreaks(u1, u2, ncp_u, {});
auto v = LinspaceWithBreaks(v1, v2, ncp_v, {});

TColgp_Array2OfPnt points(1, ncp_u, 1, ncp_v);

for (size_t i = 0; i < u.size(); ++i) {
for (size_t j = 0; j < v.size(); ++j) {
auto pnt = surf->Value(u[i], v[j]);
points.SetValue(static_cast<Standard_Integer>(i+1), static_cast<Standard_Integer>(j+1), pnt);
}
}

return CTiglBSplineAlgorithms::pointsToSurface(points, u, v, true, true);
}

} // namespace tigl