@@ -31,6 +31,7 @@
Loading
31 31
#include "contrib/MakePatches.hxx"
32 32
#include "geometry/CTiglTopoAlgorithms.h"
33 33
#include "geometry/CTiglBSplineAlgorithms.h"
34 +
#include "system/CTiglError.h"
34 35
35 36
36 37
#include <TopoDS.hxx>
@@ -240,6 +241,15 @@
Loading
240 241
241 242
void CTiglMakeLoft::makeLoftWithoutGuides()
242 243
{
244 +
    // check number of edges are all same
245 +
    std::vector<unsigned int> edgeCountPerProfile;
246 +
    for (const auto& profile : profiles) {
247 +
        edgeCountPerProfile.push_back(GetNumberOfEdges(profile));
248 +
    }
249 +
    if (!AllSame(edgeCountPerProfile.begin(), edgeCountPerProfile.end())) {
250 +
        throw tigl::CTiglError("Number of edges not equal in CTiglMakeLoft");
251 +
    }
252 +
243 253
    TopoDS_Shell faces;
244 254
    BRep_Builder builder;
245 255
    builder.MakeShell(faces);

@@ -449,6 +449,19 @@
Loading
449 449
    return theScale;
450 450
}
451 451
452 +
double CTiglBSplineAlgorithms::scale(const TColgp_Array1OfPnt& points)
453 +
{
454 +
    double theScale = 0.;
455 +
456 +
    for (int i = points.Lower(); i <= points.Upper(); ++i) {
457 +
        for (int j = i + 1; j < points.Upper(); ++j) {
458 +
            double dist = points.Value(i).Distance(points.Value(j));
459 +
            theScale = std::max(theScale, dist);
460 +
        }
461 +
    }
462 +
    return theScale;
463 +
}
464 +
452 465
std::vector<double> CTiglBSplineAlgorithms::computeParamsBSplineCurve(const Handle(TColgp_HArray1OfPnt)& points, const double alpha)
453 466
{
454 467
    return computeParamsBSplineCurve(points, 0., 1., alpha);

@@ -190,6 +190,19 @@
Loading
190 190
191 191
    // Build the B-Spline
192 192
    auto occPoints = OccArray(points);
193 +
194 +
    // we always want to include the endpoint, if it's the same as the startpoint
195 +
    // we use the middle to enforce closing of the spline
196 +
    gp_Pnt pStart = points.front().Get_gp_Pnt();
197 +
    gp_Pnt pEnd   = points.back().Get_gp_Pnt();
198 +
199 +
    // this check allows some tolerance, based on the absolute size of the profile
200 +
    if (pStart.Distance(pEnd) < 0.005 * CTiglBSplineAlgorithms::scale(occPoints->Array1())) {
201 +
        gp_Pnt pMiddle = 0.5 * (pStart.XYZ() + pEnd.XYZ());
202 +
        occPoints->SetValue(occPoints->Lower(), pMiddle);
203 +
        occPoints->SetValue(occPoints->Upper(), pMiddle);
204 +
    }
205 +
193 206
    CTiglInterpolatePointsWithKinks interp(occPoints, kinks, params, 0.5, 3);
194 207
    auto spline = interp.Curve();
195 208

@@ -362,6 +362,15 @@
Loading
362 362
    return idx < array.size();
363 363
}
364 364
365 +
/**
366 +
 * Returns true, if all elements are the same
367 +
 */
368 +
template <typename ForwardIter>
369 +
bool AllSame(ForwardIter begin, ForwardIter end)
370 +
{
371 +
    return std::adjacent_find( begin, end, std::not_equal_to<typename std::iterator_traits<ForwardIter>::value_type>() ) == end;
372 +
}
373 +
365 374
template <class ArrayType, typename BinaryPredicate, typename BinaryMerge>
366 375
void ReplaceAdjacentWithMerged(ArrayType& list, BinaryPredicate is_adjacent, BinaryMerge merged)
367 376
{

@@ -242,6 +242,9 @@
Loading
242 242
    /// Returns the scale of the point matrix
243 243
    TIGL_EXPORT static double scale(const TColgp_Array2OfPnt& points);
244 244
245 +
    /// Returns the scale of the point list by searching for the largest distance between two points
246 +
    TIGL_EXPORT static double scale(const TColgp_Array1OfPnt& points);
247 +
245 248
    /**
246 249
     * Returns positions, where the curve has kinks (C1 Discontinuities)
247 250
     */
Files Coverage
src 69.44%
Project Totals (425 files) 69.44%
1
codecov:
2
  require_ci_to_pass: yes
3

4
coverage:
5
  precision: 2
6
  round: down
7
  range: "25...100"
8

9
parsers:
10
  gcov:
11
    branch_detection:
12
      conditional: yes
13
      loop: yes
14
      method: no
15
      macro: no
16

17
comment:
18
  layout: "reach,diff,flags,tree"
19
  behavior: default
20
  require_changes: no
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading