Sketcher: Bezier curves

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

triplus wrote:What you implemented is curvature comb with bounding curve. Without this feature it would be really hard to inspect the curvature.

P.S. It makes perfect sense and thanks for adding the feature.
What I refer to is actually the conversion to NURBS. Those circle, arc of circle, ellipse, arc of ellipse, arc of hyperbola and arc of parabola that are now BSplines.

The problem is in needing to change the behavior of show internal unused geometry, because if constraints are enforced at showing the poles, the shapes loose the geometry.

However, after reading your reactions, well, I get that what has to be done is change the the show/restore to work like the other forms, and provide another mechanism for the autoconstraining of weights on creation.
yorik wrote:FreeCAD is getting the most gorgeous curve editor out there!
Probably not, but I gladly accept the compliment :D
emills2 wrote: SInce Werner mentioned combs external to the sketcher, just wanted to point out that Chris_G's macro, as written way back, could be assigned outside of the sketch, and still show during sketch editing. I haven't updated it since last august.
I guess this does require that the AutoUpdate function of the sketcher is active... so it would also update all other geometry using that sketch during edition... Not trying to defend one choice over the other. I have learned a long time ago that what seems right at a given moment turns to be a bad decision later on, just trying to fairly compare what you get from each.

Anyway, "external" from wmayer, at least in one option, is just hardlinking the algorithm, which would be exactly the same as it is today... when it will be available. I am all for such an option... when available.
emills2 wrote:The use case is to manually adjust the control points across a joint to maintain curvature flow:
if the combs touch at the end, you have G2 continuity
if the comb tangents are aligned, you have G3 continuity (more better)

The physical world impact is highlight flow: if you look at a modern car, the reflections have no 'breaks' in them. The tangents join, the curvature joins, and the derivative of curvature with respect to arclength joins.
Thanks for this interpretation of the comb. I did not know it and I find it enlightening.
emills2 wrote:This addition to sketcher looks awesome! Thanks Abdullah. I hope someone makes a windows build soon!
Welcome!! You may start using Linux in the meanwhile :lol: Just a joke. I am almost sure that when this goes to master, sgrogan will be more than happy to make one...
emills2 wrote:The upshot is that we will often want to raise degrees and insert knot into curves without changing the way they currently look.
Understood. I am trying to find a way to get into the knots without implementing De Boor and its differentials... while I sleep...
wmayer wrote:
Some time for reflexion. Do you think such a conversion to NURB is useful? What do you think you could do with it?
This will be useful. I just have pushed a commit to master to convert an arbitrary curve to a B-Spline or NURBS. The default implementation of toNurbs does the same as toBSpline but for the conics it can be re-implemented to return a real NURBS.

Since we don't have a GUI tool to change the knot vector this would be a good way to bring a real NURBS of a circle into a sketch.
We really need to get better synchronised more often :)

This is what I did yesterday to produce that picture:

Code: Select all

int SketchObject::ConvertToNURB(int GeoId)
{
    if (GeoId < 0 || GeoId > getHighestCurveIndex())
        return -1;
    
    const Part::Geometry *geo = getGeometry(GeoId);
    
    if(geo->getTypeId() == Part::GeomPoint::getClassTypeId())
        return -1;
    
    const Part::GeomCurve *geo1 = static_cast<const Part::GeomCurve *>(geo);
    
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(geo1->handle());
    
    Handle_Geom_BSplineCurve ncurve = GeomConvert::CurveToBSplineCurve(c);
    
    Part::GeomBSplineCurve* bspline = new Part::GeomBSplineCurve(ncurve);
    
    delGeometry(GeoId);
    addGeometry(bspline);
    
}
I like that you made it into Part:Geometry.

I selected GeomConvert because it is specific for the types we have in the Sketcher, but I did not know ShapeConstruct_Curve, which for the Sketcher geometries uses GeomConvert, so it is the same.

So now I will switch my code to use yours... well I learned GeomConvert exists :lol:
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

emills2 wrote:
microelly2 wrote:I have created coincident triples of poles to get hard edges for my pad.
Is it possible to force a real edge creation on padding for this case?

For one edge I can use the starting point of the bspline but for the other not.
I don't know the full rationale perfectly, but i remember reading that this is generally recommended against.

The preferred method is to raise the multiplicity of the knot at that location. Each multiplicity reduces continuity by one. When multplicity reach the order, you get continuity 0. A hard corner.
I think I would not know how to answer.

Well, I guess a hardcorner it is. Knot multiplicity just indicates that there is zero length segment controlled by the same pole, and this well, is a zero length segment controlled by another pole that is the same as the former. It would be good to know why it is recommended against...
emills2
Posts: 875
Joined: Tue Apr 28, 2015 11:23 pm

Re: Sketcher: Bezier curves

Post by emills2 »

abdullah wrote:. It would be good to know why it is recommended against...
I think it wreaks havoc on all the NURBS tool that depend on the convex shell property. If you duplicate poles , you have 0 length segments in your grid. BAD! The knot vector is MADE for the purpose of limiting the zone of influence of poles. This is called the local control property. Raising the multiplicity of knots is a specific feature of NURBS. It actually is equivalent to acing two bezier side to side. They make a hard corner and each tangent is independent..

The reverse property can be used to soften a hard corner. Join two bezier and start removing knots....it kinda blends together.

It's really hard to keep track of to be honest. I build everything out of 4 point and 6 point cubics myself. I only allow complex knot vectors in curves if i know how to integrate them in surfaces.

Ps you dont need deboor for knots. Freecad does it already. InsertKnot() will add poles to keep the curve identical while accomodating the new knot vector.

For microelly's case, there is a function that raises multiplicity directly. Play around with it....insert a knot at t=your point ot interest, then raise mult.
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

emills2 wrote:Ps you dont need deboor for knots. Freecad does it already. InsertKnot() will add poles to keep the curve identical while accomodating the new knot vector.
Well, well established answer is that I do, because the solver is the one that keeps the (new to be inserted) internal geometry points (representing a knot) on the knot position. It does this by linking the points x,y to the position with respect to all other bspline parameters, so that for example, when you change a pole, the knot position is updated. This implies not only the position per se, but the differentials, so that the solver knows how to minimize the error function that puts the knot point at the knot position.

What I am thinking is that if there is a way to not do exactly that and be able to provide something functional enough, then I may get away with it... still thinking (I have lots of other things going on, so not thinking too hard yet :) )
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Sketcher: Bezier curves

Post by microelly2 »

Changing the multiplicity of a knot is one way to get hard edges.
But if you have a surface where a fillet/soft edge morphs to a hard edge (poles collaps) and smooth again to a fillet?
This case is hard to model with knot multiplicities.



example:

Code: Select all


coords=[
(0,0,0),(0,0,0),(0,-80,10),(0,-30,20),(0,0,30),(0,30,20),(0,40,0),
(-30,0,0),(-30,0,0),(-30,-60,10),(-30,-30,30),(-30,0,40),(-30,30,30),(-30,40,0),

(-60,0,-50),(-60,0,-50),(-60,-40,0),(-60,-30,40),(-60,0,50),(-60,30,40),(-60,30,0),
(-100,0,-20),(-100,0,-20),(-100,-30,0),(-100,-30,40),(-80,0,60),(-100,30,40),(-100,20,0),

(-200,20,30),(-200,-20,30),(-200,-30,20),(-150,-20,80),(-120,0,80),(-150,20,80),(-200,20,20),

(-250,0,20),(-250,0,20),(-250,-30,20),(-200,-20,80),(-120,0,100),(-200,20,80),(-250,50,20),
(-350,0,0),(-350,0,0),(-355,-30,20),(-305,-70,80),(-155,0,120),(-305,80,80),(-355,50,20),
(-355,10,0),(-355,-10,0),(-355,-30,50),(-305,-40,130),(-155,0,130),(-305,40,130),(-355,50,50),
(-360,10,150),(-360,-10,150),(-355,-30,150),(-265,-40,150),(-155,0,150),(-265,40,150),(-355,50,150),
]

import Points
pts=[FreeCAD.Vector(p) for p in coords]
# Points.show(Points.Points(pts))

NbUPoles=7
NbVPoles=9# 10

pts=np.array(pts).reshape(NbVPoles,NbUPoles,3)


bs=Part.BSplineSurface()

kv=[1.0/(NbVPoles-3)*i for i in range(NbVPoles-2)]
mv=[4] +[1]*(NbVPoles-4) +[4]

ku=[1.0/(NbUPoles-1)*i for i in range(NbUPoles)]
mu=[2]+[1]*(NbUPoles-2)+[2]

vdegree=3
udegree=3

bs=Part.BSplineSurface()
bs.buildFromPolesMultsKnots(pts, mv, mu, kv, ku, False,True ,vdegree,udegree)

sh=bs.toShape()
sp=App.ActiveDocument.addObject("Part::Spline","Poles")
sp.Shape=sh
sp.ViewObject.ControlPoints=True
emills2
Posts: 875
Joined: Tue Apr 28, 2015 11:23 pm

Re: Sketcher: Bezier curves

Post by emills2 »

I don't remember where i read about double control points being undesirable, and now looking back in The NURBs Book i see they do it as well. So it can't be too bad.

By luck they also show the multiplicity technique in the same picture. It's pretty neat actually, double pole uniform knot on a cubic gives tangent-like control in the local area (tangent to control poly), and double pole + double knot collapses to the control point. is the second picture closer to what you where looking for?
Piegl tiller double control points.PNG
Piegl tiller double control points.PNG (127.44 KiB) Viewed 1433 times
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Sketcher: Bezier curves

Post by wmayer »

abdullah wrote: I like that you made it into Part:Geometry.

I selected GeomConvert because it is specific for the types we have in the Sketcher, but I did not know ShapeConstruct_Curve, which for the Sketcher geometries uses GeomConvert, so it is the same.

So now I will switch my code to use yours... well I learned GeomConvert exists
That's exactly one of these cases which are not sketcher specific and thus should be available for other modules, too. Btw, I have pushed a further commit to get a real NURBS out of a circle and arc of circle. Doing this for ellipse and arc of ellipse will be trivial now.

About the GeomConvert I am not sure this works for arbitrary curves. When looking at the ShapeConstruct_Curve code then GeomConvert is only used for lines and Bezier curves. For all other types the curve is sampled and then a B-spline is approximated.
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Sketcher: Bezier curves

Post by microelly2 »

There are realy some useful properties of the uniform Splines.
For degree 3 I often use:
3 Controlpoints at the same position -> sharp corner
4 Controlpoints collinear -> planar subface
5 or 6 Controlpoints collinear -> the planar subface goes through the inner poles.
These all are constraints that can be forced by the sketcher now.
My idea was that it should be possible sometime to replace/reuse a classical subobject (line/planar segment) of a BSpline surface for classical constructions. This in not the task of the sketcher but the postprocessing: pad and pocket.
abdullah
Veteran
Posts: 4935
Joined: Sun May 04, 2014 3:16 pm
Contact:

Re: Sketcher: Bezier curves

Post by abdullah »

wmayer wrote:
abdullah wrote: I like that you made it into Part:Geometry.

I selected GeomConvert because it is specific for the types we have in the Sketcher, but I did not know ShapeConstruct_Curve, which for the Sketcher geometries uses GeomConvert, so it is the same.

So now I will switch my code to use yours... well I learned GeomConvert exists
That's exactly one of these cases which are not sketcher specific and thus should be available for other modules, too. Btw, I have pushed a further commit to get a real NURBS out of a circle and arc of circle. Doing this for ellipse and arc of ellipse will be trivial now.

About the GeomConvert I am not sure this works for arbitrary curves. When looking at the ShapeConstruct_Curve code then GeomConvert is only used for lines and Bezier curves. For all other types the curve is sampled and then a B-spline is approximated.
I probably misunderstood the GeomConvert, I was expecting to get a real nurbs out of it, not an approximation for those specific cases. I also understand that is not for arbitrary curves. It is weird that we do not have in OCC a function that does this for common conics... why do these people take such a hard work to apply approximations to specific shapes (conics) instead of the exact NURBS representation, that is existing?
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Sketcher: Bezier curves

Post by wmayer »

I probably misunderstood the GeomConvert, I was expecting to get a real nurbs out of it, not an approximation for those specific cases. I also understand that is not for arbitrary curves. It is weird that we do not have in OCC a function that does this for common conics... why do these people take such a hard work to apply approximations to specific shapes (conics) instead of the exact NURBS representation, that is existing?
You can see this for a circle when calling toBSpline() and then adding the spline to the sketcher. When you check the control points and weights you will realize that it can't be an exact NURBS representation of the circle.

I don't know why they do it this way but maybe other algorithms have problems with rational splines. For example with boolean operations you often run into problems just with normal B-spline surfaces and maybe this becomes worse with real NURBS.
Post Reply