Edit:microelly2 wrote: ↑Sat Apr 21, 2018 3:11 pmCode: Select all
# -*- coding: utf-8 -*- #------------------------------------------------- #-- create a sketch for a closed bezier curves chain #-- #-- microelly 2018 0.1 #-- #-- GNU Lesser General Public License (LGPL) #------------------------------------------------- import FreeCAD,FreeCADGui,Sketcher,Part App = FreeCAD Gui = FreeCADGui import numpy as np import time import random class FeaturePython: ''' basic defs''' def __init__(self, obj): obj.Proxy = self self.Object = obj def attach(self, vobj): self.Object = vobj.Object def claimChildren(self): return self.Object.Group def __getstate__(self): return None def __setstate__(self, state): return None class ViewProvider: ''' basic defs ''' def __init__(self, obj): obj.Proxy = self self.Object = obj def __getstate__(self): return None def __setstate__(self, state): return None def setupContextMenu(self, obj, menu): menu.clear() action = menu.addAction("MyMethod #1") action.triggered.connect(lambda:self.methodA(obj.Object)) action = menu.addAction("MyMethod #2") menu.addSeparator() action.triggered.connect(lambda:self.methodB(obj.Object)) action = menu.addAction("Edit Sketch") action.triggered.connect(lambda:self.myedit(obj.Object)) def myedit(self,obj): self.methodB(None) Gui.activeDocument().setEdit(obj.Name) obj.ViewObject.show() self.methodA(None) def methodA(self,obj): print "my Method A" FreeCAD.activeDocument().recompute() def methodB(self,obj): print "my method B" FreeCAD.activeDocument().recompute() def methodC(self,obj): print "my method C" FreeCAD.activeDocument().recompute() def unsetEdit(self,vobj,mode=0): self.methodC(None) def doubleClicked(self,vobj): print "double clicked" self.myedit(vobj.Object) print "Ende double clicked" def getNamedConstraint(sketch,name): '''get the index of a constraint name''' for i,c in enumerate (sketch.Constraints): if c.Name==name: return i print ('Constraint name "'+name+'" not in ' +sketch.Label) raise Exception ('Constraint name "'+name+'" not in ' + sketch.Label) def clearReportView(name): from PySide import QtGui mw=Gui.getMainWindow() r=mw.findChild(QtGui.QTextEdit, "Report view") r.clear() import time now = time.ctime(int(time.time())) App.Console.PrintWarning("Cleared Report view " +str(now)+" by " + name+"\n") ##\endcond class BezierSketch(FeaturePython): '''Sketch Object with Python for Bezier Curve''' ##\cond def __init__(self, obj, icon='/home/thomas/.FreeCAD/Mod/freecad-nurbs/icons/draw.svg'): obj.Proxy = self self.Type = self.__class__.__name__ self.obj2 = obj self.aa = None obj.addProperty("App::PropertyInteger",'polescount',).polescount=12 obj.addProperty("App::PropertyBool",'init') ViewProvider(obj.ViewObject) ##\endcond def execute(proxy,obj): obj.Shape=run(obj) def run(sk): gc=sk.GeometryCount ap=gc/3 print ("geometry count, poles, constraints count",gc,ap,sk.ConstraintCount) try: if sk.init: if sk.ConstraintCount <= 150: for i in range(ap-1): rc=sk.addConstraint(Sketcher.Constraint('Parallel',3*i+3,3*i+2)) # sk.setVirtualSpace(rc, True) sk.solve() rc=sk.addConstraint(Sketcher.Constraint('Parallel',gc-1,0)) # sk.setVirtualSpace(rc, True) sk.init=False for i in range(90): # must become parameteric, depends on the number sk.polescount #if i in [2,3,8,9,15,16,]: # for 3 # if i in [0,1,6,7,13,14,19,20]: # for 5 if i in [0,1, 6,7, 13,14, 20,21, 27,28, 34,35, 41,42, 47,48 ]: # for 7 sk.setDriving(i,False) sk.setVirtualSpace(i, True) jj=sk.addConstraint(Sketcher.Constraint('Distance',0,10)) sk.setDriving(jj,False) sk.setVirtualSpace(jj, True) jj=sk.addConstraint(Sketcher.Constraint('Distance',20,10)) sk.setDriving(jj,False) sk.setVirtualSpace(jj, True) print "done" except: pass # for c in range(sk.ConstraintCount): # sk.setVirtualSpace(c, True) try: #poles=[ sk.getPoint(i,1) +FreeCAD.Vector(0,0,random.random()*2000) for i in range(sk.polescount)] #poles=[ sk.getPoint(i,1) +FreeCAD.Vector(0,0,0) for i in range(sk.polescount*3)] # gleich doppelte Punkte poles=[] for i in range(sk.polescount*3): p=sk.getPoint(i,1) if i%3== 0: poles += [p,p,p] # corner pole -- multiplicity 3 else: poles += [p] # tangent pole cc=Part.BSplineCurve(poles+[poles[0]]) return cc.toShape() except: return Part.Shape() def init_bezierring(sk,count=5,source=None): if source <> None: ptsa=source.Shape.Wires[0].discretize(count*2*10) ptsb=[] # read some exact point p for the pole and a approx tangent p2-p, pv-p for the tangent indicators for n in range(count): p=ptsa[2*n*10] p2=p+ (ptsa[2*n*10+1]-p).normalize()*10 pv=p+((p-p2).normalize())*(10) if n==0: last=pv ptsb += [p,p2] else: ptsb += [pv,p,p2] # the tangent from the first pole ptsb += [last] # map from xz scan to xy sketch pts=[FreeCAD.Vector(p.x,p.z,0) for p in ptsb] else: # a generated circle with some noise r=100 pts=[] for i in range(count): p=FreeCAD.Vector(r*np.cos(2*i*np.pi/count),r*np.sin(2*i*np.pi/count),0) p2=FreeCAD.Vector(r*np.cos((2*i+1)*np.pi/count),r*np.sin((2*i+1)*np.pi/count),0) p2 += FreeCAD.Vector((0.5-random.random())*0.2*r,(0.5-random.random())*0.2*r) pm=(p+p2)*0.5 pts +=[p,pm,p2] for i in range(count): if i <> 0: # connect to the last segment with a connector line lc=sk.addGeometry(Part.LineSegment(pts[3*i-1],pts[3*i]),False) sk.addConstraint(Sketcher.Constraint('Coincident',lb,2,lc,1)) la=sk.addGeometry(Part.LineSegment(pts[3*i],pts[3*i+1]),False) lb=sk.addGeometry(Part.LineSegment(pts[3*i+1],pts[3*i+2]),False) if 1: # avoid moving of points p2=sk.getPoint(lb,1) cc=sk.addConstraint(Sketcher.Constraint('DistanceX',lb,1,p2.x)) sk.addConstraint(Sketcher.Constraint('DistanceY',lb,1,p2.y)) sk.renameConstraint(cc, u'aa ' + str(i)) p2=sk.getPoint(la,1) cc=sk.addConstraint(Sketcher.Constraint('DistanceX',la,1,p2.x)) sk.addConstraint(Sketcher.Constraint('DistanceY',la,1,p2.y)) sk.renameConstraint(cc, u'bb ' + str(i)) # blocking does not work (unsolvable by sketcher) why? # sk.addConstraint(Sketcher.Constraint('Block',lb)) sk.addConstraint(Sketcher.Constraint('Coincident',la,2,lb,1)) if i <> 0: # connect connector line to the new created segment sk.addConstraint(Sketcher.Constraint('Coincident',lc,2,la,1)) # close the figure # the last connector la=sk.addGeometry(Part.LineSegment(pts[3*i],pts[0]),False) p2=sk.getPoint(la,1) cc=sk.addConstraint(Sketcher.Constraint('DistanceX',la,1,p2.x)) sk.addConstraint(Sketcher.Constraint('DistanceY',la,1,p2.y)) sk.renameConstraint(cc, u'cc ' + str(i)) # connect head and foot sk.addConstraint(Sketcher.Constraint('Coincident',lb,2,la,1)) sk.addConstraint(Sketcher.Constraint('Coincident',la,2,0,1)) def createBezierSketch(name="BezierRing",source=None): if source <> None: name="Sk_"+source.Label+'_' obj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObjectPython",name) BezierSketch(obj) obj.polescount=7 init_bezierring(obj,count=obj.polescount,source=source) obj.init=True return obj def createBezierRingSketch(name="BezierRing",source=None): return createBezierSketch(name,source) if __name__ == '__main__': createBezierRingSketch()
Sketcher: Bezier curves
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
- microelly2
- Veteran
- Posts: 4688
- Joined: Tue Nov 12, 2013 4:06 pm
- Contact:
Re: Sketcher: Bezier curves
Re: Sketcher: Bezier curves
Ach so!
So if I give you a python console, you do not actually need a lever and a fulcrum
It is not the way I intend for the Sketcher, as the B-spline/Bezier is not really there, but I must admit really like how you tackled the problem. You are at a level of python+FC knowledge that you could actually write a book about it
EDIT: I saw your edit with the B-Spline inside the sketch. When I will consider this further I will come back here to this thread.
Re: Sketcher: Bezier curves
I have a question about the usage of the B-spline.
Would it be possible to create the points where the B-spline is crossing(intersecting) against now the that we edit the control points.
I think in method editing the crossing points is more intuitive as editing the control points.
I have created a model in creo. with 4 construction (yellow dots) lines equal spaced and 5 points 4 on the lines and 1 floating above the center point.
The red lines with the points are what i called the crossing/ intersection points. the blue ..-..-..- lines are the lines between the crossing points.
from user perspective i think that the intersection points are more easy to edit than the control points. When editing the dimension (32.92) all control points are moving but the points where i want the model is still there.
Would it be possible to create the points where the B-spline is crossing(intersecting) against now the that we edit the control points.
I think in method editing the crossing points is more intuitive as editing the control points.
I have created a model in creo. with 4 construction (yellow dots) lines equal spaced and 5 points 4 on the lines and 1 floating above the center point.
The red lines with the points are what i called the crossing/ intersection points. the blue ..-..-..- lines are the lines between the crossing points.
from user perspective i think that the intersection points are more easy to edit than the control points. When editing the dimension (32.92) all control points are moving but the points where i want the model is still there.
Re: Sketcher: Bezier curves
There is basically minimum support for B-Spline in GCS. Therefore what we can do with B-splines is very basic. No point on curve. No tangency other than endpoints... seen from another point of view, it is almost a miracle that we have the support we have with the little the solver knows about B-Splines.
At some moment we will hopefully find new momentum to do that "quite a bit of effort" DeepSOIC is talking about.
At some moment we will hopefully find new momentum to do that "quite a bit of effort" DeepSOIC is talking about.
Re: Sketcher: Bezier curves
Based on an idea of wmayer I have a section in my sketcher document on how to simulate tangents to a B-spline. Perhaps this technique can be refined by automatically splitting the spline.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
Re: Sketcher: Bezier curves
I hope at some point the solver is powerfull enough that this kind of functionallity is possible...
- microelly2
- Veteran
- Posts: 4688
- Joined: Tue Nov 12, 2013 4:06 pm
- Contact:
Re: Sketcher: Bezier curves
I use Sketcher only to hold the control points for a Bezier curve and than I calculate the Bezier curve as a shape.
Working with Bezier curves is easier than with BSplines in general
https://youtu.be/zRhb5vDPEWM
https://youtu.be/GPKJVlakQ8Y
https://youtu.be/PPJ55ghd4KE
Working with Bezier curves is easier than with BSplines in general
https://youtu.be/zRhb5vDPEWM
https://youtu.be/GPKJVlakQ8Y
https://youtu.be/PPJ55ghd4KE
Re: Sketcher: Bezier curves
But that's exactly how the spline in the sketcher also works... I want the reversed. not editing the control points(without a clue where the lines are...) but editing some points on the lines without care how and what the control points are.microelly2 wrote: ↑Wed Nov 14, 2018 8:15 am I use Sketcher only to hold the control points for a Bezier curve and than I calculate the Bezier curve as a shape.
Working with Bezier curves is easier than with BSplines in general
- microelly2
- Veteran
- Posts: 4688
- Joined: Tue Nov 12, 2013 4:06 pm
- Contact:
Re: Sketcher: Bezier curves
In case of Bezier curve the control points are on the curve. So when you move the controlpoints the curve always follows them.Jee-Bee wrote: ↑Wed Nov 14, 2018 8:34 amBut that's exactly how the spline in the sketcher also works... I want the reversed. not editing the control points(without a clue where the lines are...) but editing some points on the lines without care how and what the control points are.microelly2 wrote: ↑Wed Nov 14, 2018 8:15 am I use Sketcher only to hold the control points for a Bezier curve and than I calculate the Bezier curve as a shape.
Working with Bezier curves is easier than with BSplines in general