View Issue Details

IDProjectCategoryView StatusLast Update
0000358FreeCADFeaturepublic2017-03-27 08:27
Reporterwmayer Assigned Towmayer  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Fixed in Version0.17 
Summary0000358: BSpline curves not closing correctly
DescriptionSee https://sourceforge.net/apps/phpbb/free-cad/viewtopic.php?f=10&t=1019&p=7812#p7812
TagsNo tags attached.
FreeCAD Information

Activities

wmayer

2011-05-26 06:45

administrator   ~0000863

First script uses the points in a certain order doing an interpolation:

from FreeCAD import Base

pts=[]
pts.append(Base.Vector(10.106740,-0.173045,110.000000))
pts.append(Base.Vector(10.876900,12.552288,110.000000))
pts.append(Base.Vector(2.146670,24.053253,110.000000))
pts.append(Base.Vector(10.568193,33.859135,110.000000))
pts.append(Base.Vector(22.640881,26.377998,110.000000))
pts.append(Base.Vector(33.179409,29.244604,110.000000))
pts.append(Base.Vector(46.792278,29.475332,110.000000))
pts.append(Base.Vector(57.932823,26.863115,110.000000))
pts.append(Base.Vector(69.864944,32.936234,110.000000))
pts.append(Base.Vector(81.339508,27.226950,110.000000))
pts.append(Base.Vector(93.168350,29.244604,110.000000))
pts.append(Base.Vector(106.781219,29.475332,110.000000))
pts.append(Base.Vector(118.208069,27.469503,110.000000))
pts.append(Base.Vector(129.161713,33.628414,110.000000))
pts.append(Base.Vector(137.698593,24.399343,110.000000))
pts.append(Base.Vector(128.637985,12.673570,110.000000))
pts.append(Base.Vector(129.969254,-0.173045,110.000000))
pts.append(Base.Vector(129.123093,-12.188456,110.000000))
pts.append(Base.Vector(137.813950,-24.283981,110.000000))
pts.append(Base.Vector(129.853882,-34.205227,110.000000))
pts.append(Base.Vector(117.601677,-26.984392,110.000000))
pts.append(Base.Vector(106.550491,-29.013878,110.000000))
pts.append(Base.Vector(93.514435,-29.590694,110.000000))
pts.append(Base.Vector(82.105621,-26.693552,110.000000))
pts.append(Base.Vector(70.095673,-33.282322,110.000000))
pts.append(Base.Vector(59.481319,-26.922842,110.000000))
pts.append(Base.Vector(46.330826,-29.359968,110.000000))
pts.append(Base.Vector(32.948681,-29.244606,110.000000))
pts.append(Base.Vector(22.597166,-25.847414,110.000000))
pts.append(Base.Vector(10.568193,-33.859138,110.000000))
pts.append(Base.Vector(2.377396,-24.168617,110.000000))
pts.append(Base.Vector(11.240733,-13.886350,110.000000))

import Part
spline=Part.BSplineCurve()

spline.interpolate(pts, True)
Part.show(spline.toShape())

The order of points now has circulated. This means the result actually must be the same but the OCC algorithm delivers something different. At least the kink issue is solved.

from FreeCAD import Base

pts=[]
pts.append(Base.Vector(129.161713,33.628414,110.000000))
pts.append(Base.Vector(137.698593,24.399343,110.000000))
pts.append(Base.Vector(128.637985,12.673570,110.000000))
pts.append(Base.Vector(129.969254,-0.173045,110.000000))
pts.append(Base.Vector(129.123093,-12.188456,110.000000))
pts.append(Base.Vector(137.813950,-24.283981,110.000000))
pts.append(Base.Vector(129.853882,-34.205227,110.000000))
pts.append(Base.Vector(117.601677,-26.984392,110.000000))
pts.append(Base.Vector(106.550491,-29.013878,110.000000))
pts.append(Base.Vector(93.514435,-29.590694,110.000000))
pts.append(Base.Vector(82.105621,-26.693552,110.000000))
pts.append(Base.Vector(70.095673,-33.282322,110.000000))
pts.append(Base.Vector(59.481319,-26.922842,110.000000))
pts.append(Base.Vector(46.330826,-29.359968,110.000000))
pts.append(Base.Vector(32.948681,-29.244606,110.000000))
pts.append(Base.Vector(22.597166,-25.847414,110.000000))
pts.append(Base.Vector(10.568193,-33.859138,110.000000))
pts.append(Base.Vector(2.377396,-24.168617,110.000000))
pts.append(Base.Vector(11.240733,-13.886350,110.000000))
pts.append(Base.Vector(10.106740,-0.173045,110.000000))
pts.append(Base.Vector(10.876900,12.552288,110.000000))
pts.append(Base.Vector(2.146670,24.053253,110.000000))
pts.append(Base.Vector(10.568193,33.859135,110.000000))
pts.append(Base.Vector(22.640881,26.377998,110.000000))
pts.append(Base.Vector(33.179409,29.244604,110.000000))
pts.append(Base.Vector(46.792278,29.475332,110.000000))
pts.append(Base.Vector(57.932823,26.863115,110.000000))
pts.append(Base.Vector(69.864944,32.936234,110.000000))
pts.append(Base.Vector(81.339508,27.226950,110.000000))
pts.append(Base.Vector(93.168350,29.244604,110.000000))
pts.append(Base.Vector(106.781219,29.475332,110.000000))
pts.append(Base.Vector(118.208069,27.469503,110.000000))

import Part
spline=Part.BSplineCurve()

spline.interpolate(pts, True)
Part.show(spline.toShape())

As workaround we can post-process the spline by fixing the first control point directly. One way could be to do two fits with the normal order of points and the "circulated" order. Then we can replace the first control point by that of the second curve. Is a bit ugly but should work.

shoogen

2013-10-23 06:09

developer   ~0003786

Though the flag is called closed in FreeCAD it means periodic.
//! If PeriodicFlag is true, the constrained BSpline

//! curve will be periodic and closed. In this case,

//! the junction point is the first point of the table Points.

how ever the resulting curve is not periodic.

wmayer

2013-10-24 11:47

administrator   ~0003797

Now, it's possible to create a fully symmetric curve. The trick is to mirror the control points and then create a periodic b-spline curve from the poles.

from FreeCAD import Base

pts=[]
pts.append(Base.Vector(10.106740,-0.173045,110.000000))
pts.append(Base.Vector(10.876900,12.552288,110.000000))
pts.append(Base.Vector(2.146670,24.053253,110.000000))
pts.append(Base.Vector(10.568193,33.859135,110.000000))
pts.append(Base.Vector(22.640881,26.377998,110.000000))
pts.append(Base.Vector(33.179409,29.244604,110.000000))
pts.append(Base.Vector(46.792278,29.475332,110.000000))
pts.append(Base.Vector(57.932823,26.863115,110.000000))
pts.append(Base.Vector(69.864944,32.936234,110.000000))
pts.append(Base.Vector(81.339508,27.226950,110.000000))
pts.append(Base.Vector(93.168350,29.244604,110.000000))
pts.append(Base.Vector(106.781219,29.475332,110.000000))
pts.append(Base.Vector(118.208069,27.469503,110.000000))
pts.append(Base.Vector(129.161713,33.628414,110.000000))
pts.append(Base.Vector(137.698593,24.399343,110.000000))
pts.append(Base.Vector(128.637985,12.673570,110.000000))
pts.append(Base.Vector(129.969254,-0.173045,110.000000))
pts.append(Base.Vector(129.123093,-12.188456,110.000000))
pts.append(Base.Vector(137.813950,-24.283981,110.000000))
pts.append(Base.Vector(129.853882,-34.205227,110.000000))
pts.append(Base.Vector(117.601677,-26.984392,110.000000))
pts.append(Base.Vector(106.550491,-29.013878,110.000000))
pts.append(Base.Vector(93.514435,-29.590694,110.000000))
pts.append(Base.Vector(82.105621,-26.693552,110.000000))
pts.append(Base.Vector(70.095673,-33.282322,110.000000))
pts.append(Base.Vector(59.481319,-26.922842,110.000000))
pts.append(Base.Vector(46.330826,-29.359968,110.000000))
pts.append(Base.Vector(32.948681,-29.244606,110.000000))
pts.append(Base.Vector(22.597166,-25.847414,110.000000))
pts.append(Base.Vector(10.568193,-33.859138,110.000000))
pts.append(Base.Vector(2.377396,-24.168617,110.000000))
pts.append(Base.Vector(11.240733,-13.886350,110.000000))

import Part
spline=Part.BSplineCurve()
spline.interpolate(pts, True)
p=spline.getPoles()[9:26]
spline.translate((-p[0].x,-p[0].y,-p[0].z))
p=spline.getPoles()[9:26]

c=Part.BSplineCurve()
q=[]
q.extend(p)
for i in reversed(p[1:-1]):
    q.append(App.Vector(-i.x,i.y,i.z))

c.buildFromPoles(q,True,3)
c.translate((p[0].x,p[0].y,p[0].z))
App.newDocument()
App.ActiveDocument.addObject("Part::Spline","Symmetric").Shape=c.toShape()
App.ActiveDocument.addObject("Part::Spline","Nonsymmetric").Shape=spline.toShape()

triplus

2017-01-10 15:23

developer   ~0007603

It would be cool if at some point in the future closed BSpline curve would be periodic.

http://forum.freecadweb.org/viewtopic.php?f=3&t=16473&start=120#p152442

Thanks in advance.

wmayer

2017-01-21 15:18

administrator   ~0007907

With the spline support in the sketcher this is possible now. You only have to make sure that the start and end control points are symmetric to the mirror plane.

Related Changesets

FreeCAD: master f6c776e5

2013-10-24 12:18:03

wmayer

Details Diff
0000358: BSpline curves not closing correctly Affected Issues
0000358
mod - src/Mod/Part/App/BSplineCurvePyImp.cpp Diff File

Issue History

Date Modified Username Field Change
2011-05-25 17:25 wmayer New Issue
2011-05-25 17:25 wmayer Status new => assigned
2011-05-25 17:25 wmayer Assigned To => wmayer
2011-05-26 06:45 wmayer Note Added: 0000863
2011-11-10 12:34 Jriegel Target Version 0.12 =>
2013-10-23 06:09 shoogen Note Added: 0003786
2013-10-24 11:30 wmayer Category Bug => Feature
2013-10-24 11:47 wmayer Note Added: 0003797
2017-01-10 15:23 triplus Note Added: 0007603
2017-01-21 15:18 wmayer Note Added: 0007907
2017-01-21 15:18 wmayer Status assigned => closed
2017-01-21 15:18 wmayer Resolution open => fixed
2017-01-21 15:18 wmayer Fixed in Version => 0.17
2017-03-27 08:27 Kunda1 Changeset attached => FreeCAD master f6c776e5