Rational BSplines don't work

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
dekoning
Posts: 51
Joined: Wed Nov 19, 2014 4:32 pm

Rational BSplines don't work

Post by dekoning »

Hey guys,

Maybe you know it already but I'd like to report that setting the weight of Part.BSpline() to any value other than 1 doesn't work (e.g. rational BSplines don't work). Take for example the following code:

Code: Select all

from FreeCAD import Vector
import Part

poles = [Vector(0,0),Vector(0.5,1),Vector(1,0)]
bsplinecurve = Part.BSplineCurve()
bsplinecurve.buildFromPoles(poles)
bsplinecurve.setWeight(2,0.5)
Part.show(bsplinecurve.toShape())
It gives the error:

Code: Select all

Exception: ACCESS VIOLATION at address 0xFFFFFFFFFFFFFFFF during 'READ' operation
The use of rational Bezier curves does work as shown by the code below:

Code: Select all

from FreeCAD import Vector
import Part

poles = [Vector(0,0),Vector(0.5,1),Vector(1,0)]
beziercurve = Part.BezierCurve()
beziercurve.setPoles(poles)
beziercurve.setWeight(2,0.5)
Part.show(beziercurve.toShape())
FYI I'm using:
OS: Windows 7
Word size: 64-bit
Version: 0.14.3700 (Git)
Branch: releases/FreeCAD-0-14
Hash: 32f5aae0a64333ec8d5d160dbc46e690510c8fe1
Python version: 2.7.6
Qt version: 4.8.5
Coin version: 4.0.0a
SoQt version: 1.6.0a
OCC version: 6.6.0
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Rational BSplines don't work

Post by shoogen »

I can reproduce the problem on OCCT 6.8.1-dev. It is very likely to be an upstream problem. Thanks for the report.

EDIT: not reproduce able in DRAWEXE

Code: Select all

> bsplinecurve b2 2 2  0.0 3  1.0 3  0 0 0 1.0  0.5 1 0 0.5  1 0 0 1.0
> mkedge e1 b2 0.0 1.0
wmayer
Founder
Posts: 20302
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Rational BSplines don't work

Post by wmayer »

I can confirm the bug too. The stack trace is:

Code: Select all

>	TKMathd.dll!TColStd_Array1OfReal::ChangeValue(const int Index=1)  Line 99 + 0x5 bytes	C++
 	TKMathd.dll!TColStd_Array1OfReal::operator()(const int Index=1)  Line 82	C++
 	TKMathd.dll!BSplCLib::BuildCache(const double U=0.00000000000000000, const double SpanDomain=1.0000000000000000, const bool Periodic=false, const int Degree=2, const TColStd_Array1OfReal & FlatKnots={...}, const TColgp_Array1OfPnt & Poles={...}, const TColStd_Array1OfReal & Weights={...}, TColgp_Array1OfPnt & CachePoles={...}, TColStd_Array1OfReal & CacheWeights={...})  Line 1074 + 0x2b bytes	C++
 	TKG3dd.dll!Geom_BSplineCurve::ValidateCache(const double Parameter=0.00000000000000000)  Line 1272	C++
 	TKG3dd.dll!Geom_BSplineCurve::D0(const double U=0.00000000000000000, gp_Pnt & P={...})  Line 121	C++
 	TKG3dd.dll!Geom_Curve::Value(const double U=0.00000000000000000)  Line 65	C++
 	TKTopAlgod.dll!BRepLib_MakeEdge::Init(const Handle_Geom_Curve & CC={...}, const TopoDS_Vertex & VV1={...}, const TopoDS_Vertex & VV2={...}, const double pp1=0.00000000000000000, const double pp2=1.0000000000000000)  Line 820 + 0x2c bytes	C++
 	TKTopAlgod.dll!BRepLib_MakeEdge::Init(const Handle_Geom_Curve & C={...}, const double p1=0.00000000000000000, const double p2=1.0000000000000000)  Line 670 + 0x3d bytes	C++
 	TKTopAlgod.dll!BRepLib_MakeEdge::BRepLib_MakeEdge(const Handle_Geom_Curve & L={...}, const double p1=0.00000000000000000, const double p2=1.0000000000000000)  Line 502 + 0x1b bytes	C++
 	TKTopAlgod.dll!BRepBuilderAPI_MakeEdge::BRepBuilderAPI_MakeEdge(const Handle_Geom_Curve & L={...}, const double p1=0.00000000000000000, const double p2=1.0000000000000000)  Line 419 + 0x76 bytes	C++
 	Part_d.pyd!Part::GeometryCurvePy::toShape(_object * args=0x0000000003137058)  Line 105 + 0x21 bytes	C++
The actual bug is inside Geom_BSplineCurve::ValidateCache.

Code: Select all


void Geom_BSplineCurve::ValidateCache(const Standard_Real  Parameter) 
{
  Standard_Real NewParameter ;
  Standard_Integer LocalIndex = 0 ;
  //
  // check if the degree did not change
  //
  if (cachepoles->Upper() < deg + 1) {                                 <<========= this check fails because cachepoles->Upper() returns "3" and "deg" is equal "2". This means "cachewieghts"
                                                                                             is still a null handle but further down its method "ChangeArray1" is called
    cachepoles = new TColgp_HArray1OfPnt(1,deg + 1);
    if (rational) {
      cacheweights  = new TColStd_HArray1OfReal(1,deg + 1);
    }
  }
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Rational BSplines don't work

Post by shoogen »

Thanks Werner. That explains why the curve actually needs to be changed from non-rational to rational (without increasing the degree), to reproduce the problem. I haven't found a DRAWEXE command to achieve this.
I reported it as http://tracker.dev.opencascade.org/view.php?id=25706

@dekonig:
As a workaround you can create the curve as rational right away

Code: Select all

bsplinecurve.buildFromPolesMultsKnots(poles=(FreeCAD.Vector(0,0),FreeCAD.Vector(0.5,1),FreeCAD.Vector(1,0)),weights=(1.0,0.5,1))
wmayer
Founder
Posts: 20302
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Rational BSplines don't work

Post by wmayer »

dekoning
Posts: 51
Joined: Wed Nov 19, 2014 4:32 pm

Re: Rational BSplines don't work

Post by dekoning »

Thnx guys, you are the best !
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Rational BSplines don't work

Post by shoogen »

Yes, they are.
Post Reply