Extruding along a 3D path (Solved!)
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Extruding along a 3D path (Solved!)
I have a 2D shape that I would like to extrude along a 3D path. I tried a number of methods, and nothing worked.
I've created a wireframe of the 3D object, but I seemingly cannot create faces that are not along planes. I tried makePipeShell and makeLoft (possibly incorrectly) but the resulting objects in no way honored the 2D shape I was trying to extrude and, while it was hard to tell, didn't seem to actually end with the faces parallel either (i.e. my direct object is *not* a semi-circle or fraction thereof, though it is close)
I've attached a python script which generates the wireframe along with my two attempts (each assignment to myObject.Shape represents an attempt).
Any ideas?
I've created a wireframe of the 3D object, but I seemingly cannot create faces that are not along planes. I tried makePipeShell and makeLoft (possibly incorrectly) but the resulting objects in no way honored the 2D shape I was trying to extrude and, while it was hard to tell, didn't seem to actually end with the faces parallel either (i.e. my direct object is *not* a semi-circle or fraction thereof, though it is close)
I've attached a python script which generates the wireframe along with my two attempts (each assignment to myObject.Shape represents an attempt).
Any ideas?
- Attachments
-
- x.py
- (1.73 KiB) Downloaded 75 times
Last edited by SRCAD on Mon Nov 20, 2017 4:11 pm, edited 1 time in total.
- microelly2
- Veteran
- Posts: 4688
- Joined: Tue Nov 12, 2013 4:06 pm
- Contact:
Re: Extruding along a 3D path
Welcome to the forum,
please read this first https://forum.freecadweb.org/viewtopic.php?f=3&t=2264
we need some information about your environment to support you.
please read this first https://forum.freecadweb.org/viewtopic.php?f=3&t=2264
we need some information about your environment to support you.
Re: Extruding along a 3D path
Hi,
Since we don't have any information on the FC and OCC version you are running, I don't know if the following code will work for you :
Since we don't have any information on the FC and OCC version you are running, I don't know if the following code will work for you :
Code: Select all
import Part
import Mesh
from FreeCAD import Base
#import png
#import urllib
App.closeDocument("d")
doc = FreeCAD.newDocument("d")
selfholdoff = 4.25
wall_thickness = 1.75
radius_tube = 12
straight = 95
height = 2.0*straight/3
ringheight = height/2.0
#myObject=App.ActiveDocument.addObject("Part::Feature","Sweep")
def makeArc(x,z):
V1 = Base.Vector(selfholdoff,radius_tube+wall_thickness+x-.6,ringheight+z)
V2 = Base.Vector(radius_tube+wall_thickness+x,0,ringheight+z)
V3 = Base.Vector(selfholdoff,-radius_tube-wall_thickness-x+.6,ringheight+z)
rp_a = Part.Arc(V1,V2,V3)
rp_s = Part.Shape([rp_a])
rp_w = Part.Wire(rp_s.Edges)
return(rp_w,V1,V3)
points=((0,0),(wall_thickness,wall_thickness),(2*wall_thickness,wall_thickness),(2*wall_thickness,-wall_thickness),(wall_thickness,-wall_thickness))
a1 = makeArc(*points[0])
a2 = makeArc(*points[1])
a3 = makeArc(*points[2])
a4 = makeArc(*points[3])
a5 = makeArc(*points[4])
def makeFaceWire(a1,a2):
#wire = Part.Wire([a1[0],Part.makeLine(a1[1],a2[1]),a2[0],Part.makeLine(a2[2],a1[2])])
rs = Part.makeRuledSurface(a1[0],a2[0])
#Part.show(rs)
return(rs.Faces[0]) # rs is a shell. We want only the first face
f1 = makeFaceWire(a1,a2)
f2 = makeFaceWire(a2,a3)
f3 = makeFaceWire(a3,a4)
f4 = makeFaceWire(a4,a5)
f5 = makeFaceWire(a5,a1)
w6 = Part.makePolygon([a1[1],a2[1],a3[1],a4[1],a5[1],a1[1]])
f6 = Part.Face(w6)
#Part.show(f6)
w7 = Part.makePolygon([a1[2],a2[2],a3[2],a4[2],a5[2],a1[2]])
f7 = Part.Face(w7)
#Part.show(f7)
sh = Part.Shell([f1,f2,f3,f4,f5,f6,f7])
so = Part.Solid(sh)
Part.show(so)
# ----- Alternate method -------
# Sweeps the 2 end faces along a path
ps = Part.BRepOffsetAPI.MakePipeShell(a1[0])
ps.add(w6)
ps.add(w7)
if ps.isReady():
ps.build()
ps.makeSolid()
Part.show(ps.shape())
Re: Extruding along a 3D path
My apologies, I tried to update my post last night with the necessary information but it was held or something so I couldn't do it.
I'll take a look at your suggested code and give it a try. Ruled surfaces. Hmm. I didn't research what those were when I saw passing references to them.
OS: "Fedora release 25 (Twenty Five)"
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.Unknown
Build type: Unknown
Python version: 2.7.13
Qt version: 4.8.7
Coin version: 3.1.3
OCC version: 6.8.0.oce-0.17
I'll take a look at your suggested code and give it a try. Ruled surfaces. Hmm. I didn't research what those were when I saw passing references to them.
OS: "Fedora release 25 (Twenty Five)"
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.Unknown
Build type: Unknown
Python version: 2.7.13
Qt version: 4.8.7
Coin version: 3.1.3
OCC version: 6.8.0.oce-0.17
Re: Extruding along a 3D path (Solved)
Thanks Chris_G, both of your techniques worked great!
I imagine I understand what a ruled surface is (I have not stumbled on a good definition of it in my quick searches) and so in my imagination it makes sense that it would work. I'll keep it in the back of my mind the next time I need that sort of correspondence.
I see your second method provides a few critical adjustments to the makePipeShell I tried. I've have to study your example more closely to understand which of the changes had which affect.
Thanks!
I imagine I understand what a ruled surface is (I have not stumbled on a good definition of it in my quick searches) and so in my imagination it makes sense that it would work. I'll keep it in the back of my mind the next time I need that sort of correspondence.
I see your second method provides a few critical adjustments to the makePipeShell I tried. I've have to study your example more closely to understand which of the changes had which affect.
Thanks!
Re: Extruding along a 3D path
ps = Part.BRepOffsetAPI.MakePipeShell。About this method.I have a question,can this method sweep along two paths from one section to another section?I have tried many times,the second pss.add will cover the first.Hope your reply!Chris_G wrote: ↑Mon Nov 20, 2017 9:12 am Hi,
Since we don't have any information on the FC and OCC version you are running, I don't know if the following code will work for you :Code: Select all
import Part import Mesh from FreeCAD import Base #import png #import urllib App.closeDocument("d") doc = FreeCAD.newDocument("d") selfholdoff = 4.25 wall_thickness = 1.75 radius_tube = 12 straight = 95 height = 2.0*straight/3 ringheight = height/2.0 #myObject=App.ActiveDocument.addObject("Part::Feature","Sweep") def makeArc(x,z): V1 = Base.Vector(selfholdoff,radius_tube+wall_thickness+x-.6,ringheight+z) V2 = Base.Vector(radius_tube+wall_thickness+x,0,ringheight+z) V3 = Base.Vector(selfholdoff,-radius_tube-wall_thickness-x+.6,ringheight+z) rp_a = Part.Arc(V1,V2,V3) rp_s = Part.Shape([rp_a]) rp_w = Part.Wire(rp_s.Edges) return(rp_w,V1,V3) points=((0,0),(wall_thickness,wall_thickness),(2*wall_thickness,wall_thickness),(2*wall_thickness,-wall_thickness),(wall_thickness,-wall_thickness)) a1 = makeArc(*points[0]) a2 = makeArc(*points[1]) a3 = makeArc(*points[2]) a4 = makeArc(*points[3]) a5 = makeArc(*points[4]) def makeFaceWire(a1,a2): #wire = Part.Wire([a1[0],Part.makeLine(a1[1],a2[1]),a2[0],Part.makeLine(a2[2],a1[2])]) rs = Part.makeRuledSurface(a1[0],a2[0]) #Part.show(rs) return(rs.Faces[0]) # rs is a shell. We want only the first face f1 = makeFaceWire(a1,a2) f2 = makeFaceWire(a2,a3) f3 = makeFaceWire(a3,a4) f4 = makeFaceWire(a4,a5) f5 = makeFaceWire(a5,a1) w6 = Part.makePolygon([a1[1],a2[1],a3[1],a4[1],a5[1],a1[1]]) f6 = Part.Face(w6) #Part.show(f6) w7 = Part.makePolygon([a1[2],a2[2],a3[2],a4[2],a5[2],a1[2]]) f7 = Part.Face(w7) #Part.show(f7) sh = Part.Shell([f1,f2,f3,f4,f5,f6,f7]) so = Part.Solid(sh) Part.show(so) # ----- Alternate method ------- # Sweeps the 2 end faces along a path ps = Part.BRepOffsetAPI.MakePipeShell(a1[0]) ps.add(w6) ps.add(w7) if ps.isReady(): ps.build() ps.makeSolid() Part.show(ps.shape())
Re: Extruding along a 3D path (Solved!)
The "Auxiliary spine" mode is supposed to do this, when its "Contact" option is set to "Contact on border".
Unfortunately, this is broken upstream (in OpenCascade). I have never seen this working.
A workaround is to use the Gordon surface of the Curves workbench.
It builds a surface from a curve network. The guides and profiles must form a grid pattern.
Or you can also give a try at the Surface workbench and its "Filling" tool.
Unfortunately, this is broken upstream (in OpenCascade). I have never seen this working.
A workaround is to use the Gordon surface of the Curves workbench.
It builds a surface from a curve network. The guides and profiles must form a grid pattern.
Or you can also give a try at the Surface workbench and its "Filling" tool.
Re: Extruding along a 3D path (Solved!)
Thanks!Do you have an example about how to build a surface from a curve network,I need a .FCMacro file.If you have ,I would really appreciate your offer!Chris_G wrote: ↑Wed Aug 07, 2019 10:52 am The "Auxiliary spine" mode is supposed to do this, when its "Contact" option is set to "Contact on border".
Unfortunately, this is broken upstream (in OpenCascade). I have never seen this working.
A workaround is to use the Gordon surface of the Curves workbench.
It builds a surface from a curve network. The guides and profiles must form a grid pattern.
Or you can also give a try at the Surface workbench and its "Filling" tool.
Re: Extruding along a 3D path (Solved!)
Here is an example script, that work in the python console.
Update the Curves workbench, if you had already installed it, because I pushed a fix this morning.
Update the Curves workbench, if you had already installed it, because I pushed a fix this morning.
Code: Select all
import FreeCAD
from FreeCAD import Vector
import Part
# Create the curve network
poles0 = [Vector (0.0, 0.0, 0.0), Vector (0.16666666666666666, 0.0, 0.20000000794728598), Vector (0.49999999999999994, 0.0, 0.40000001589457196), Vector (0.8333333333333334, 0.0, 0.20000000794728598), Vector (1.0, 0.0, 0.0)]
weights0 = [1.0, 1.0, 1.0, 1.0, 1.0]
knots0 = [0.0, 0.5830951956177974, 1.1661903912355949]
mults0 = [4, 1, 4]
periodic0 = False
degree0 = 3
rational0 = False
bs0 = Part.BSplineCurve()
bs0.buildFromPolesMultsKnots(poles=poles0, mults=mults0, knots=knots0, periodic=periodic0, degree=degree0, weights=weights0, CheckRational=rational0)
obj0 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve0")
obj0.Shape = bs0.toShape()
poles1 = [Vector (0.013121589026499694, 0.7915876947955887, 0.0008571221601094414), Vector (-0.00885599845935274, 0.7914868593215942, 0.40897222572543346), Vector (0.06419121554803943, 0.7914868593215942, 0.9506049970258048), Vector (0.4267428298127499, 0.7914868593215942, 0.5416327713003715), Vector (0.7273027300834656, 0.7914868593215942, 0.0)]
weights1 = [1.0, 1.0, 1.0, 1.0, 1.0]
knots1 = [0.0, 0.7053976507426758, 1.6396089746603792]
mults1 = [4, 1, 4]
periodic1 = False
degree1 = 3
rational1 = False
bs1 = Part.BSplineCurve()
bs1.buildFromPolesMultsKnots(poles=poles1, mults=mults1, knots=knots1, periodic=periodic1, degree=degree1, weights=weights1, CheckRational=rational1)
bs1.getKnots()
obj1 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve1")
obj1.Shape = bs1.toShape(bs1.FirstParameter, bs1.LastParameter)
poles2 = [Vector (-0.29265061020851135, 1.7891597747802734, 0.0), Vector (0.556077287533451, 1.7891597747802734, 0.7004100558512543), Vector (1.2192605936714151, 1.7891597747802732, 0.9304442719319388), Vector (1.2656674010425126, 1.7891597747802734, 0.23003421608068433), Vector (1.2394413948059082, 1.7891597747802734, 0.0)]
weights2 = [1.0, 1.0, 1.0, 1.0, 1.0]
knots2 = [0.0, 1.5852100266723423, 2.105837254626154]
mults2 = [4, 1, 4]
periodic2 = False
degree2 = 3
rational2 = False
bs2 = Part.BSplineCurve()
bs2.buildFromPolesMultsKnots(poles=poles2, mults=mults2, knots=knots2, periodic=periodic2, degree=degree2, weights=weights2, CheckRational=rational2)
bs2.getKnots()
obj2 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve2")
obj2.Shape = bs2.toShape()
poles3 = [Vector (0.0, 0.0, 0.0), Vector (0.01980706605738829, 0.13102204117622993, 0.03582234726635581), Vector (0.04193204614098622, 0.39521243838553644, 0.05609202982516635), Vector (0.011570412468109364, 1.0063177946409716, -0.02655385582891836), Vector (-0.12865621642847969, 1.4740525911095985, -0.12251780016751808), Vector (-0.29265061020851135, 1.7891597747802734, 0.0)]
weights3 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
knots3 = [0.0, 0.55, 1.841346800327301]
mults3 = [4, 2, 4]
periodic3 = False
degree3 = 3
rational3 = False
bs3 = Part.BSplineCurve()
bs3.buildFromPolesMultsKnots(poles=poles3, mults=mults3, knots=knots3, periodic=periodic3, degree=degree3, weights=weights3, CheckRational=rational3)
obj3 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve3")
obj3.Shape = bs3.toShape()
FreeCAD.ActiveDocument.recompute()
poles4 = [Vector (0.37568899989128113, 0.0, 0.2814561426639557), Vector (0.1979298550637957, 0.2528165565557051, 0.5073158012737045), Vector (0.012426622785748864, 0.8217413994502759, 0.8116662306235015), Vector (0.25350408566703514, 1.4418752936204768, 0.7220463662761115), Vector (0.5054633617401123, 1.7891597747802734, 0.5606870651245117)]
weights4 = [1.0, 1.0, 1.0, 1.0, 1.0]
knots4 = [0.0, 0.9339859674161192, 2.0140618136101445]
mults4 = [4, 1, 4]
periodic4 = False
degree4 = 3
rational4 = False
bs4 = Part.BSplineCurve()
bs4.buildFromPolesMultsKnots(poles=poles4, mults=mults4, knots=knots4, periodic=periodic4, degree=degree4, weights=weights4, CheckRational=rational4)
obj4 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve4")
obj4.Shape = bs4.toShape()
poles5 = [Vector (1.0, 0.0, 0.0), Vector (0.7962455246105475, 0.23471487235329058, -0.07387134852685648), Vector (0.6630578583047347, 0.6931604531973199, -0.02306488701337041), Vector (0.8347851190761894, 1.346445916688191, 0.09673176665963677), Vector (1.0782930244160058, 1.6595823128097014, 0.07573943536620759), Vector (1.2394413948059082, 1.7891597747802734, 0.0)]
weights5 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
knots5 = [0.0, 0.837147057056427, 1.3702200651168823, 1.9922663569450378]
mults5 = [4, 1, 1, 4]
periodic5 = False
degree5 = 3
rational5 = False
bs5 = Part.BSplineCurve()
bs5.buildFromPolesMultsKnots(poles=poles5, mults=mults5, knots=knots5, periodic=periodic5, degree=degree5, weights=weights5, CheckRational=rational5)
obj5 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve5")
obj5.Shape = bs5.toShape()
# Create the Gordon surface
import gordon
gordon = gordon.InterpolateCurveNetwork([bs0,bs1,bs2],[bs3,bs4,bs5],0.1,0.001)
Part.show(gordon.surface().toShape())
Re: Extruding along a 3D path (Solved!)
Can this work in version 0.16?Chris_G wrote: ↑Fri Aug 09, 2019 11:57 am Here is an example script, that work in the python console.
Update the Curves workbench, if you had already installed it, because I pushed a fix this morning.
Code: Select all
import FreeCAD from FreeCAD import Vector import Part # Create the curve network poles0 = [Vector (0.0, 0.0, 0.0), Vector (0.16666666666666666, 0.0, 0.20000000794728598), Vector (0.49999999999999994, 0.0, 0.40000001589457196), Vector (0.8333333333333334, 0.0, 0.20000000794728598), Vector (1.0, 0.0, 0.0)] weights0 = [1.0, 1.0, 1.0, 1.0, 1.0] knots0 = [0.0, 0.5830951956177974, 1.1661903912355949] mults0 = [4, 1, 4] periodic0 = False degree0 = 3 rational0 = False bs0 = Part.BSplineCurve() bs0.buildFromPolesMultsKnots(poles=poles0, mults=mults0, knots=knots0, periodic=periodic0, degree=degree0, weights=weights0, CheckRational=rational0) obj0 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve0") obj0.Shape = bs0.toShape() poles1 = [Vector (0.013121589026499694, 0.7915876947955887, 0.0008571221601094414), Vector (-0.00885599845935274, 0.7914868593215942, 0.40897222572543346), Vector (0.06419121554803943, 0.7914868593215942, 0.9506049970258048), Vector (0.4267428298127499, 0.7914868593215942, 0.5416327713003715), Vector (0.7273027300834656, 0.7914868593215942, 0.0)] weights1 = [1.0, 1.0, 1.0, 1.0, 1.0] knots1 = [0.0, 0.7053976507426758, 1.6396089746603792] mults1 = [4, 1, 4] periodic1 = False degree1 = 3 rational1 = False bs1 = Part.BSplineCurve() bs1.buildFromPolesMultsKnots(poles=poles1, mults=mults1, knots=knots1, periodic=periodic1, degree=degree1, weights=weights1, CheckRational=rational1) bs1.getKnots() obj1 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve1") obj1.Shape = bs1.toShape(bs1.FirstParameter, bs1.LastParameter) poles2 = [Vector (-0.29265061020851135, 1.7891597747802734, 0.0), Vector (0.556077287533451, 1.7891597747802734, 0.7004100558512543), Vector (1.2192605936714151, 1.7891597747802732, 0.9304442719319388), Vector (1.2656674010425126, 1.7891597747802734, 0.23003421608068433), Vector (1.2394413948059082, 1.7891597747802734, 0.0)] weights2 = [1.0, 1.0, 1.0, 1.0, 1.0] knots2 = [0.0, 1.5852100266723423, 2.105837254626154] mults2 = [4, 1, 4] periodic2 = False degree2 = 3 rational2 = False bs2 = Part.BSplineCurve() bs2.buildFromPolesMultsKnots(poles=poles2, mults=mults2, knots=knots2, periodic=periodic2, degree=degree2, weights=weights2, CheckRational=rational2) bs2.getKnots() obj2 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve2") obj2.Shape = bs2.toShape() poles3 = [Vector (0.0, 0.0, 0.0), Vector (0.01980706605738829, 0.13102204117622993, 0.03582234726635581), Vector (0.04193204614098622, 0.39521243838553644, 0.05609202982516635), Vector (0.011570412468109364, 1.0063177946409716, -0.02655385582891836), Vector (-0.12865621642847969, 1.4740525911095985, -0.12251780016751808), Vector (-0.29265061020851135, 1.7891597747802734, 0.0)] weights3 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] knots3 = [0.0, 0.55, 1.841346800327301] mults3 = [4, 2, 4] periodic3 = False degree3 = 3 rational3 = False bs3 = Part.BSplineCurve() bs3.buildFromPolesMultsKnots(poles=poles3, mults=mults3, knots=knots3, periodic=periodic3, degree=degree3, weights=weights3, CheckRational=rational3) obj3 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve3") obj3.Shape = bs3.toShape() FreeCAD.ActiveDocument.recompute() poles4 = [Vector (0.37568899989128113, 0.0, 0.2814561426639557), Vector (0.1979298550637957, 0.2528165565557051, 0.5073158012737045), Vector (0.012426622785748864, 0.8217413994502759, 0.8116662306235015), Vector (0.25350408566703514, 1.4418752936204768, 0.7220463662761115), Vector (0.5054633617401123, 1.7891597747802734, 0.5606870651245117)] weights4 = [1.0, 1.0, 1.0, 1.0, 1.0] knots4 = [0.0, 0.9339859674161192, 2.0140618136101445] mults4 = [4, 1, 4] periodic4 = False degree4 = 3 rational4 = False bs4 = Part.BSplineCurve() bs4.buildFromPolesMultsKnots(poles=poles4, mults=mults4, knots=knots4, periodic=periodic4, degree=degree4, weights=weights4, CheckRational=rational4) obj4 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve4") obj4.Shape = bs4.toShape() poles5 = [Vector (1.0, 0.0, 0.0), Vector (0.7962455246105475, 0.23471487235329058, -0.07387134852685648), Vector (0.6630578583047347, 0.6931604531973199, -0.02306488701337041), Vector (0.8347851190761894, 1.346445916688191, 0.09673176665963677), Vector (1.0782930244160058, 1.6595823128097014, 0.07573943536620759), Vector (1.2394413948059082, 1.7891597747802734, 0.0)] weights5 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] knots5 = [0.0, 0.837147057056427, 1.3702200651168823, 1.9922663569450378] mults5 = [4, 1, 1, 4] periodic5 = False degree5 = 3 rational5 = False bs5 = Part.BSplineCurve() bs5.buildFromPolesMultsKnots(poles=poles5, mults=mults5, knots=knots5, periodic=periodic5, degree=degree5, weights=weights5, CheckRational=rational5) obj5 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve5") obj5.Shape = bs5.toShape() # Create the Gordon surface import gordon gordon = gordon.InterpolateCurveNetwork([bs0,bs1,bs2],[bs3,bs4,bs5],0.1,0.001) Part.show(gordon.surface().toShape())