surface flattening

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
User avatar
Chris_G
Posts: 1030
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: surface flattening

Postby Chris_G » Fri Sep 08, 2017 8:38 am

Hi looo,
looo wrote:
Fri Sep 08, 2017 6:43 am
I always thought nurbs are the only splines which can model a circle exactly. But non rational B-Splines can do that too?
From what I learned and understood about nurbs, only rational splines can model conics.
I think this is even the only reason why they were created.
looo wrote:
Fri Sep 08, 2017 6:43 am
But what Is it a nurbs without weights or a bspline which has non uniform knot vectors?
NURBS = Non Uniform Rational Basis Spline
A nurbs without weights is not rational, so it could be called a NUBS.
Same for a Bspline whose parametrization is not uniform.

Off-topic :
Personally, What I would really like to know is what makes "uniform" parametrization so special that all other splines get called Non-Uniform ?
I mean : why a Uniform / Non-Uniform segregation ?
Why not Chord-Length / Non-Chord-Length ?
Or Arc-Length / Non-Arc-Length ? ( this one would make sense to me )
looo wrote:
Fri Sep 08, 2017 6:43 am
1. looking at pictures of rhino [1], it seems the degree of the flat faces is higher. So maybe there is a nurbs-base with a higher degree which can give an exact solution. I think it is possible to find such a nurbs-base which can exactly map some poles to the derivatives of the spline....
Do you say this because of the number of inner lines ?
I have never used Rhino, but I suspect them to be only isocurves, for visualisation purpose, with no relation with degree or knots.
looo wrote:
Fri Sep 08, 2017 6:43 am
2. Another mapping could be introduced. This maps the uv-coordinate on exactly the same uv-boundary, but removes the varying derivatives.
I think I faced a similar kind of problem recently with a ruled surface that was not looking good :
ruledsurf_bad.jpg
ruledsurf_bad.jpg (26.2 KiB) Viewed 777 times
My 2 curves don't have a good matching parametrization.
In that kind of cases, it is probably possible to go through a reparametrization function, to map a user-defined parametrization to the real curve parametrization.

Werner will surely be able to bring more light on all this ...
EDIT : cross-posting. He did :D
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Fri Sep 08, 2017 9:41 am

wmayer wrote: No, only real nurbs can model a circle exactly because you need control points with different weights. And this property of different weights is what makes a spline rational. With a non-rational B-Spline you can only approximate a circle which is actually obvious because the base curves are only polynomials.
ok, so nurbs are the one and only. All others are only special-cases. quite difficult.

BS -> could be also called NUBS
UBS -> Uniform BSpline = cardinal BSpline
URBS -> UBS with weights
NURBS -> BS with weights


I tried the 2. idea posted above. But result is not much better. But it's interesting that in this case the mapped uv-space is different from the origin uv-space. The boarders are the same, but the mesh has changed slightly. Also I am not sure if this is the same as a re-parametrization. It's basically mapping the uv-nodes to the same boarder.

Code: Select all


// A = nurbs-functions computed on uv-nodes
// nu = class for computing nurbs-function and derivatives
// unit-poles = poles which are equally spaced on uv-grid
// ze-nodes = mesh to be approximated

    this->uv_nodes = this->A * this->unit_poles;
    this->A = this->nu.getInfluenceMatrix(this->uv_nodes);  //re-parametrization?
    Eigen::LeastSquaresConjugateGradient<spMat > solver;
    solver.compute(this->A);
    this->ze_poles = solver.solve(this->ze_nodes);
A unwrapped cone can be represented by two arcs. As an arc is also conic, only a real NURBS can represent it exactly. So the new base has to be a NURBS. But somehow the Base can't stay the same. So the idea is to find a Base which allows the same arc-lengths in 3d and 2d.
Chris_G wrote:Do you say this because of the number of inner lines ?
I have never used Rhino, but I suspect them to be only isocurves, for visualisation purpose, with no relation with degree or knots.
Yep I suspect that the reduction of these lines has something to do with the nurbsbase. Maybe someone with rhino installed can give us some insights. (controllpoints of flat and 3d surfaces)
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Fri Sep 08, 2017 4:49 pm

While it is maybe an interesting topic, the exact unwrapping is not really important as the mesh unwrapping already introduce some amount of approximation... So maybe it's better to simple work with some higher degree + more poles nurbs and approximate the flatten mesh. Are there any examples around how to set the degree higher and change the number of poles?
wmayer
Site Admin
Posts: 14345
Joined: Thu Feb 19, 2009 10:32 am

Re: surface flattening

Postby wmayer » Fri Sep 08, 2017 7:04 pm

Code: Select all

circle=Part.Circle()
circle.Radius=50

nurbs=circle.toNurbs()
len(nurbs.getPoles())
nurbs.Degree

nurbs.increaseDegree(5)
nurbs.Degree
len(nurbs.getPoles())

nurbs.getKnots()
nurbs.insertKnot(2,3)
len(nurbs.getPoles())
nurbs.getKnots()
nurbs.getMultiplicities()

Part.show(nurbs.toShape())
Part.show(circle.toShape())
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Fri Sep 08, 2017 8:20 pm

thanks.
I allready tried this, but wasn't aware nurbs.increaseDegree(v1, v2) sets the degree... wouldn't setDegree be a better name? The current name looks like it adds the values to the current degree (like +=)

With this methode I am quite happy:
aproximation.png
aproximation.png (53.36 KiB) Viewed 723 times
no fem so far. Only the lscm was used.
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Sat Sep 09, 2017 6:07 am

next are multiple faces flattening / flattening of shells:

trying to find a flat shape for multiple faces has some more problems to be solved:
1. edges between faces must align. Therefore the edges must have the same number of poles.
--> get mesh-node-numbers corresponding to edges
--> weight edge nodes higher. As the boundary is the most interesting area, it should be approximated with a smaller error. This is not only true for multiple faces.

If it is true that poles in the inner of a boundary-fixed nurbs-surface have no influence on the boundary, then the computation can be spitted in (1) setting corner-nodes, (2) for every edge, find the edge-poles with corner-nodes fixed (ls-solve), (3) for every face ls-solve the inner region with fixed boundaries and weighted inner curves (pc_curves).

A simple approach is to do all the solving at once and simple weight edges higher. But maybe there is also a solution already provided by occ?
wmayer
Site Admin
Posts: 14345
Joined: Thu Feb 19, 2009 10:32 am

Re: surface flattening

Postby wmayer » Sat Sep 09, 2017 8:47 am

I allready tried this, but wasn't aware nurbs.increaseDegree(v1, v2) sets the degree... wouldn't setDegree be a better name? The current name looks like it adds the values to the current degree (like +=)
IncreaseDegree is the name OCC have chosen and I want to be as close as possible to the OCC API. Furthermore, you can increase the degree of a spline without changing its shape but decreasing it is in general not possible without changing it. Thus increaseDegree makes indeed more sense, IMO.
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Mon Sep 11, 2017 9:48 am

I have a short question regarding this function:

Code: Select all

virtual const Handle< Geom_Surface >& BRep_CurveRepresentation::Surface1 	( 		) 	const

Code: Select all

virtual const Handle< Geom_Surface >& BRep_CurveRepresentation::Surface2 	( 		) 	const
https://www.opencascade.com/doc/occt-7. ... d146b1d0c2

Does this mean a curve can only belong to 2 surfaces?
And is it also possible to get all curves belonging to a surface? Somehow I need to have access to all the data:
shape: triangulation and faces
faces: node_ids of triangulation, u-v nodes, curves
curves: nurbs information (poles + base) of faces, uv-node_ids

but as my occt knowledge is really limited, I think it's better to stall this project. For multiple faces an occt-expert is needed...
wmayer
Site Admin
Posts: 14345
Joined: Thu Feb 19, 2009 10:32 am

Re: surface flattening

Postby wmayer » Mon Sep 11, 2017 12:39 pm

Does this mean a curve can only belong to 2 surfaces?
No, an edge can be shared by more than two faces.

Just open the sketcher and draw three lines that end all at the same point. Then switch to the Part workbench and extrude the sketch. The creates a shell with three faces sharing a common edge.
When entering this code snippet

Code: Select all

f1=App.ActiveDocument.Extrude.Shape.Face1
f2=App.ActiveDocument.Extrude.Shape.Face2
f3=App.ActiveDocument.Extrude.Shape.Face3

f1.Edge2.isPartner(f2.Edge2) # True
f3.Edge2.isPartner(f2.Edge2) # True
f1.Edge2.isPartner(f3.Edge2) # True
it says that the edge is partner of all the faces. This means that internally it uses the same TShape and thus must share the same geometry.

Note, BRep_CurveRepresentation is an abstract base class which actually has no meaningful implementation. The methods Surface() and Surface2() are implemented in the class BRep_CurveOn2Surfaces which as its name says only handles the case when a curve belongs to two surfaces.

And is it also possible to get all curves belonging to a surface? Somehow I need to have access to all the data:
If you have a face then you get all its edges. In Python you can use the "Edges" attribute of the shape class.
shape: triangulation and faces
faces: node_ids of triangulation, u-v nodes, curves
I guess from C++ everything should be available.
curves: nurbs information (poles + base) of faces, uv-node_ids
Don't know about the uv nodes.
looo
Posts: 2599
Joined: Mon Nov 11, 2013 5:29 pm

Re: surface flattening

Postby looo » Mon Sep 11, 2017 1:53 pm

thanks for the clarification, but i am still struggle to get a good picture...
wmayer wrote:Just open the sketcher and draw three lines that end all at the same point. Then switch to the Part workbench and extrude the sketch. The creates a shell with three faces sharing a common edge.
Flattening such a shell really doesn't make much sense. It's also not possible as the mesh-flattener also assert 2 triangles sharing one edge. Maybe therefor "BRep_CurveOn2Surfaces" make sense to be used?

regarding edges:
The problem is that faces that are sewed together in 3d (via edges) should also match for the flatten case. Therefore a special treatment is necessary. I guess there are two cases how faces are sewed together:

1: via curve/edge which is approximated in uv-coordinates (by finding the intersection of two faces). This edge is a bspline-curve inside of the uv-grid. This is the more difficult face connection, as it is not possible to find a exactly matching approximation for this edge in 2d. The problem is the leastsquare solution which only approximate the edge. But also in 3d such a connection does't fully connect the edges... I don't know if there is a good solution for such a shell. A possibility would be to find a mean-curve of the flattened curves and compute new uv-curves. But then the mapping from 2d->3d will have problems.
But the question is also, if there is really a use-case for such a situation. Maybe the simplest solution is to treat such connections as two different unfold problems, which are not connected in any way.

2: via a curve/edge which is on any boundary of the uv-grid. (u=umin, u=umax, v=vmin or v=vmax) By knowing the uv-position of the edge on face1 and on face2 the pole.ids belonging to the curve can be extracted from the faces and the equation-matrix can be substituted. So if it is somehow possible to get the edge-position on a face-uv-grid this should be possible.

But still there is another problem:
How to get the full triangulation of the shell. BRep_Tools::Triangulation only allow a face as argument. No idea how to get the full triangulation. And also the node ids of faces belonging to the shell mesh have to be known.
Don't know about the uv nodes.
Does occ provide methods to get the nurbs-base for a uv-grid? If so my work with nurbs was quite useless ;)