Nurbs editor

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Nurbs editor

Post by microelly2 »

The next version of the needle editor

https://youtu.be/XInDSQjoVmI

There are two basic functionalities:
edit a closed/periodic curve (rib)
edit a open curve(backbone)

both can be edited by access to a spreadsheet but also by mouse key action over the 3d view
I use a helper document window with special information placed in. This window is the editor window. After finishing the edition the data are transformed back to the large model.

At the moment I provide 7 directions for pole movement. I still was not able to reuse the Draft tools for the case when the curves are real 3D an not only planar.
I think this way of a graphical editor can be adapted to the full nurbs surface:
select a pole by vertex selection or selection of two isoLines/segments
and then move the pole

I found a way to get the spreadsheet as separate window, so the mdi area can used for 3D and somewhere else the tabular data can be accessed.
I wonder whether it is possible to use spreadsheets as temporary views to other data sets too (subsets of point clouds)
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Nurbs editor

Post by triplus »

I will need to spend some time going through this therefore expect feedback in the following days from my side (likely over the weekend).
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Nurbs editor

Post by triplus »

I had an extra hour of free time therefore i decided to look into it. Nice video as when watching it i now understand the backbone/rib concept better. After watching the video i tried the example myself. As for the rib editor i like the fact control points can now be modified more directly. As for backbone concept i was getting too much performance issues and couldn’t test it much.

But i get it and see where you are taking this. If ribs could have different geometry that would be a nice addition.
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Nurbs editor

Post by triplus »

Thinking about it if in the future Sketcher will have BSPline support user will be able to create "rib" and position it in 3D space? Therefore maybe rib editor could simply be Sketcher in the future?
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Nurbs editor

Post by microelly2 »

triplus wrote:I had an extra hour of free time therefore i decided to look into it. Nice video as when watching it i now understand the backbone/rib concept better. After watching the video i tried the example myself. As for the rib editor i like the fact control points can now be modified more directly. As for backbone concept i was getting too much performance issues and couldn’t test it much.

But i get it and see where you are taking this. If ribs could have different geometry that would be a nice addition.
thank you for testing it.
I will just spend some time to refine this tool before I generalize it to full nurbs.
using multiple kinds of ribs is a good idea so something like a chain of pearls will be possible
if any ribs is different we will have the sweep reimplemented.

Tomorrow I will do some runtime profiles to see where the backbone consumes to much time.
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Nurbs editor

Post by microelly2 »

triplus wrote:Thinking about it if in the future Sketcher will have BSPline support user will be able to create "rib" and position it in 3D space? Therefore maybe rib editor could simply be Sketcher in the future?
Yes indeed, I had to write my own rib editor because Sketcher and Draft Tools did not support a comfortable way to edit real 3D curves.
At the moment I can move any pole in all 3D directions and bend the curve without restrictions.
The way to set the move commands as letter keys is common in Blender Gx, Rx ..., so this concept can be reused here.
In the eventserver I still do not use the changing mouse coordinates but this is a possible step to drag and drop a pole to a helper object like the Draft Move and Rotate methods already do.
There may be useful constraints to place the poles like "the curvature should have value ..." in future.
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Nurbs editor

Post by triplus »

Hi @microelly2.

I was watching the progress you where making in this thread and gave you suggestions and today i finally decided to test things out with Draft BSpline. As i was almost sure achieving some way to use Draft Snap set of tools to modify Draft BSpline must be possible. I created a few code snippets like getting a list of Draft BSPline points and converting them to real points. And after moving the points to set back the Draft BSplIne points to correct position vectors. I was thinking on how to additionally explain to you when clicking on BSpline feature on how that should open some sort of editor (Task sidebar) to make all this possible. And then the reality struck. I double clicked on Draft BSpline object in the tree view and there it was. A Draft BSpline editor where you can add or remove points. Great i thought to myself. Less work for @microelly2 if he decides to go down this road. As just an additional button is missing to move the points. And just before closing the editor i looked in the 3D view and have seen the Draft BSpline points are highlighted. I thought to myself there is like 0 chance if i click on one of the Draft BSpline points i will be able to move it around. And that is exactly what i was able to do.
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Nurbs editor

Post by microelly2 »

Yes, there is an editor in Draft for BSplines and the Needle object supports these Draft BSplines too.

I hold this opportunity open:
There is a property ribtemplateSource and a backboneSource. If these parameters are filled with links to external bsplines and the externalSourcesOff flag is set to False then the external objects are used and the data in the spreadsheet are updated with their values.
the external objects can be edited and the needle is updated.

One reason why I do not use this feature by default is:
The Draft methods do not allow a direct access to the poles. Here some points on the curve are edited and then the curve is interpolated.
In the needle spreadsheet there are pole data under direct control. So someone can access these data without extra programming knowledge.

From pole information it is always possible to calculate the surface but interpolation may go wrong.

The other reason:
I want to have the possibility to place the points very exact, a simple mouse drag and drop is not good enough. writuing the data into a spreadsheet cell is possible but moving in space with the mouse wheel and some keys is faster and shows the (simplified) results in realtime.
bp_310.png
bp_310.png (220.45 KiB) Viewed 1956 times
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Nurbs editor

Post by triplus »

If i run this code snippet:

Code: Select all

import FreeCAD,Draft
p1 = FreeCAD.Vector(0,0,0)
p2 = FreeCAD.Vector(1,1,0)
p3 = FreeCAD.Vector(0,2,0)
p4 = FreeCAD.Vector(-1,1,0)
Draft.makeBSpline([p1,p2,p3,p4],closed=True)
One could expect symmetry but this is the result:
Result.png
Result.png (3.62 KiB) Viewed 1938 times
Opinions?

As for the rib editor in Nurbs WB. Could you provide additional standalone command. It would do only one thing and that is if Draft BSpline feature is selected (if not create new one) it would open spreadsheet and list its Points X, Y ,Z values. When changing the point values in spreadsheet original Draft BSpline feature points would change accordingly. Basically automation of exchanging a list of points between Draft BSpline/Spreadsheet. I would like to have this additional possibility without using the more complete rib/backbone feature. Adding additional row in spreadsheet would therefore simply add additional point to Draft BSpline.
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Nurbs editor

Post by microelly2 »

@triplus
I have done a small script to load the BSpline Data in a Spreadsheet
Clicking into the first column should open a dialog to write the data back
I will write a short tutorial how to reuse the idea
and integrate it into the nurbs wb

Code: Select all

# version 0.1

import FreeCAD,Draft
import  nurbswb.needle
from nurbswb.needle import npa2ssa,ssa2npa

def updateSS(ss,curve):
	'''update curve data into spreadsheet'''
	ss.clearAll()
	npa2ssa(curve,ss,2,3,(1.0,1.0,0.5))
	ss.set('B1',str(len(curve)))
	App.activeDocument().recompute()


def updateDraft(ss,obj):
	'''update Draft Bspline object points from spreadsheet ss'''
	cl=int(ss.get('B1'))
	curve=ssa2npa(ss,2,3,4,3+cl-1)
	obj.Points=[FreeCAD.Vector(c) for c in curve]

global writeBack,ss,obj2

def writeBack():
	global ss
	global obj2
	updateDraft(ss,obj2)
	App.activeDocument().recompute()
	Gui.SendMsgToActiveView("ViewFit")

def mybutton(pos):

	msgBox = QtGui.QMessageBox()
	msgBox.setText("You have clicked:")
	msgBox.setInformativeText(str(pos))
	msgBox.setStandardButtons( QtGui.QMessageBox.Save |  QtGui.QMessageBox.Discard |  QtGui.QMessageBox.Cancel)
	msgBox.setDefaultButton( QtGui.QMessageBox.Cancel)
	ret = msgBox.exec_()
	print ret
	if ret == 2048:
		print "write back .." 
		writeBack()


class MyEditor(QtGui.QWidget):
	''' cell pressed dialog'''

	def __init__(self,pos=-1,title="undefined"):
		super(MyEditor, self).__init__()
		self.title=title
		self.pos=pos
		self.initUI()

	def initUI(self):      
		self.btn = QtGui.QPushButton('My Action', self)
		self.btn.move(20, 20)
		self.btn.clicked.connect(lambda:mybutton(self.pos))
		self.setGeometry(750, 30, 390, 250)
		self.setWindowTitle(self.title)
		self.show()


def pressed(index):
	if  index.column() == 0:
		w=MyEditor(index,"My Cell Pressed Dialog")

def clicked():
	pass

def undock(ss):
	''' open the data spreadsheet as top level window'''

	label=ss.Label
	mw=FreeCADGui.getMainWindow()
	mdiarea=mw.findChild(QtGui.QMdiArea)

	ss.ViewObject.startEditing(0)
	subw=mdiarea.subWindowList()

	for i in subw:
		if i.widget().metaObject().className() == "SpreadsheetGui::SheetView":
			sheet = i.widget()
			table=sheet.findChild(QtGui.QTableView)
			print "table found"
			break

#	table.clicked.connect(clicked)
	table.pressed.connect(pressed)

	sws=mdiarea.subWindowList()
	print "windows ..."
	for w2 in sws:
		print str(w2.windowTitle())
		if str(w2.windowTitle()).startswith(label):
			sw=w2
			print "found"
			bl=w2.children()[3]
			blcc=bl.children()[2].children()

			w=QtGui.QWidget()
			w.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

			box = QtGui.QVBoxLayout()
			w.setLayout(box)
			ss=blcc[3]
			box.addWidget(ss)
			w.setGeometry(50, 30, 650, 350)
			w.show()
			sw.close()
			return w



# test  case

#create the Bspline
p1 = FreeCAD.Vector(0,0,0)
p2 = FreeCAD.Vector(1,1,0)
p3 = FreeCAD.Vector(0,2,0)
p4 = FreeCAD.Vector(-1,1,0)
Draft.makeBSpline([p1,p2,p3,p4],closed=True)

# extract the data 
obj=App.ActiveDocument.ActiveObject
bc=obj.Shape.Edge1.Curve
poles=bc.getPoles()
knots=bc.getKnots()
we=bc.getWeights()
mults=bc.getMultiplicities()

pts=obj.Points


poles
knots
we
mults


# create a d fill the spreadsheet
ss = App.activeDocument().addObject('Spreadsheet::Sheet','Spreadsheet')
updateSS(ss,pts)


# create an other Draft BSpline
p1 = FreeCAD.Vector(0,0,0)
p2 = FreeCAD.Vector(10,1,0)
p3 = FreeCAD.Vector(0,2,0)
Draft.makeBSpline([p1,p2,p3],closed=True)
obj2=App.ActiveDocument.ActiveObject
Gui.SendMsgToActiveView("ViewFit")

# write Points back 
updateDraft(ss,obj2)

# open Spreadsheet
w=undock(ss)


The problem of the asymmetry depends on the multiplicities
Usage of overall mutliplicity 2 will generate symmetric curves (at the moment I don't understand why)

Code: Select all

pts=[[-200,-150,0],[-200,-300,0],[200,-300,0],[200,-100,0],[200,100,0],[200,300,0],[-200,300,0],[-200,150,0]]
c=[FreeCAD.Vector(tuple(p)) for p in pts]

# symmetric 
k=[1,2,3,4,5]
m=[2,2,2,2,2]

# draft like
#k=[1,2,3,4,5,6,7,8]
#m=[2,1,1,1,1,1,1,2]


bsg=Part.BSplineCurve()
bsg.buildFromPolesMultsKnots(c,m,k,True,3)
Part.show(bsg.toShape())

Draft.makeBSpline(c,closed=True)

c.reverse()

bsg=Part.BSplineCurve()
bsg.buildFromPolesMultsKnots(c,m,k,True,3)
Part.show(bsg.toShape())

Draft.makeBSpline(c,closed=True)


Post Reply