Hello everybody
I have some requirement to create a free NURBS surface, then make some manipulation like trim and intersect, then export it to iges or step.
the difficulty is to create the free NURBS surface, I have all data of the surface
control points: in OCCT, it's Poles
[
[p00x, p00y, p00z, p00w], [p01x, p01y, p01z, p01w], [p02x, p02y, p02z, p02w]...,
[p10x, p10y, p10z, p10w], [p11x, p11y, p11z, p11w], [p12x, p12y, p12z, p12w]...,
...
]
Udegree: degree of U direction, integer
Uknots: knots for U direction, Uknots.length = Poles[0].length+Udegree+1
[0,0,...Udegree+1 0s, u1, u2, u3...un, 1, 1, Udegree+1 1s]
Vdegree: similar like Udegree
Vknots: similar like Uknots, Vknots.length = Poles.length+Vdegree+1
I checked addon manager in FreeCAD, and installed "nurbs" addon, but the functions can't work, my FreeCAD is 0.18.16131 win64 on win10
also "nurbs" addon seems can make nurbs spline from a sketch in a plane, but my points are not in the same plane
can anybody give me some guidance?
how can I create a free NURBS surface?
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
-
- Posts: 16
- Joined: Mon Jul 29, 2019 11:07 pm
Re: how can I create a free NURBS surface?
edit: examples below are from Part module. no addons are required for what you want. But you could take a look at my Silk addon
example from https://github.com/edwardvmills/Silk/bl ... chNURBS.py
here is how i format my curves:
note that i separate the weights from x y z because i find it easier to pass them to .setPole() that way
and for a surface example:
both of these functions are adapted from examples i received from Werner originally.
the key difference for you is going to be whether to hard code the knot vectors and grid size or not. in my case, i like to work with clearly predefined sizes
edit: sorry just notice that the comment indents are jacked.
example from https://github.com/edwardvmills/Silk/bl ... chNURBS.py
here is how i format my curves:
Code: Select all
def Bezier_Cubic_curve(poles): # pinned cubic rational B spline, 4 control points
# Part.BSplineCurve(), cubic bezier form
#draws a degree 3 rational bspline from first to last point,
# second and third act as tangents
# poles is a list: [[[x,y,z],w],[[x,y,z],w],[[x,y,z],w],[[x,y,z],w]]
## nKnot = 4 + 3 +1 = 8
## Order = 3 + 1 = 4
degree=3
nPoles=4
knot=[0,0,0,0,1,1,1,1]
bs=Part.BSplineCurve()
bs.increaseDegree(degree)
id=1
for i in range(0,len(knot)): #-1):
bs.insertKnot(knot[i],id,0.0000001)
i=0
for ii in range(0,nPoles):
bs.setPole(ii+1,poles[i][0],poles[i][1])
i=i+1;
return bs
and for a surface example:
Code: Select all
def NURBS_Cubic_66_surf(grid_66): # given a 6 x 6 control grid, build the cubic
# NURBS surface from a Part.BSplineSurface().
# len(knot_u) := nNodes_u + degree_u + 1
# len(knot_v) := nNodes_v + degree_v + 1
degree_u=3
degree_v=3
nNodes_u=6
nNodes_v=6
knot_u=[0,0,0,0,1.0/3.0,2.0/3.0,1,1,1,1]
knot_v=[0,0,0,0,1.0/3.0,2.0/3.0,1,1,1,1]
NURBS_Cubic_66_surf=Part.BSplineSurface()
NURBS_Cubic_66_surf.increaseDegree(degree_u,degree_v)
id=1
for i in range(0,len(knot_u)): #-1):
NURBS_Cubic_66_surf.insertUKnot(knot_u[i],id,0.0000001)
id=1
for i in range(0,len(knot_v)): #-1):
NURBS_Cubic_66_surf.insertVKnot(knot_v[i],id,0.0000001)
i=0
for jj in range(0,nNodes_v):
for ii in range(0,nNodes_u):
NURBS_Cubic_66_surf.setPole(ii+1,jj+1,grid_66[i][0],grid_66[i][1]);
i=i+1;
return NURBS_Cubic_66_surf
the key difference for you is going to be whether to hard code the knot vectors and grid size or not. in my case, i like to work with clearly predefined sizes
edit: sorry just notice that the comment indents are jacked.
-
- Posts: 16
- Joined: Mon Jul 29, 2019 11:07 pm
Re: how can I create a free NURBS surface?
thank you emills2
by your guidance, I created some demo code
after I run it, there was no error hint, so it should run well, but nothing is displayed on the screen, could you please give me some more advise?
by your guidance, I created some demo code
Code: Select all
import FreeCAD
import Part
FreeCAD.newDocument("test")
FreeCAD.setActiveDocument("test")
FreeCAD.ActiveDocument = FreeCAD.getDocument("test")
# NURBS surface from a Part.BSplineSurface().
# len(knot_u) := nNodes_u + degree_u + 1
# len(knot_v) := nNodes_v + degree_v + 1
poles=[[[15.5, 4.8, 1.46, 1.0], [10.18, 4.8, 0.89, 1.0], [1.8, 8.9, 0.57, 1.0], [0, 15, 0.43, 1.0], [0, 22, -0.02, 1.0]], [[15.15, 17.05, 1.13, 1.0], [11.7, 17.05, 0.81, 1.0], [6.72, 17.1, 0.48, 1.0], [4.31, 18.74, 0.38, 1.0], [3.23, 22.8, 0.05, 1.0]]]
degree_u=1
degree_v=3
nNodes_u=2
nNodes_v=5
knot_v=[0, 0.5256099762388414, 1]
knot_v_mults=[4, 1, 4]
knot_u=[0,1]
knot_u_mults=[2, 2]
NURBS_Cubic_surf=Part.BSplineSurface()
NURBS_Cubic_surf.increaseDegree(degree_u,degree_v)
for i in range(0,len(knot_u)): #-1):
NURBS_Cubic_surf.insertUKnot(knot_u[i],knot_u_mults[i],0.0000001)
for i in range(0,len(knot_v)): #-1):
NURBS_Cubic_surf.insertVKnot(knot_v[i],knot_v_mults[i],0.0000001)
poles_xyz=[]
for ii in range(0, len(poles)):
poles_xyz.append([])
for jj in range(0, len(poles[ii])):
poles_xyz[ii].append(FreeCAD.Base.Vector(poles[ii][jj][0], poles[ii][jj][1], poles[ii][jj][2]))
NURBS_Cubic_surf.setPole(ii+1, jj+1, poles_xyz[ii][jj], poles[ii][jj][3])
Last edited by silent_missile on Thu Aug 08, 2019 7:23 am, edited 2 times in total.
Re: how can I create a free NURBS surface?
You need to instruct freecad to show the object you created.silent_missile wrote: ↑Thu Aug 08, 2019 5:41 am after I run it, there was no error hint, so it should run well, but nothing is displayed on the screen, could you please give me some more advise?
Add the following line:
Code: Select all
Part.show(NURBS_Cubic_surf.toShape())