Open kkpal3 opened 3 years ago
I think that @winksaville has done some work along these lines.
Potentially related discussion: https://groups.google.com/g/cadquery/c/_7JI1Ffl2N4/m/LbVVfSC3CAAJ
There might be some potentially useful info here, although loft is being used instead of sweep.
Is there a simple example you can post of what you're trying to accomplish?
Thank you Jeremy! I will have a look the references you mentioned. Meanwhile, here is a sketch of what I want to do, and a test case is also attached. testCase.zip
I have information of the blade stored in "BladeInfo.dat". It specifies the the following: BlSpan: spanwise location of the airfoil section BlTwist: local twist angle of the airfoil section BlChord: local chord length of the airfoil BlAFID: the index of airfoil type. The coordinates of different airfoils are stored in files named nacaxxxx.txt. They have the same number of points for different airfoils.
For now, I can build the airfoil sections in cad-query. I wanted to construct the blade from these sectional data. If I use the same type of airfoils, i.e., the last column of "BladeInfo.dat" (BlAFID) having the same value, the sweep operation is successful. However, when I use different values of BlAFID, errors as I mentioned previously occurs!
I can run your code without any issue using the master version of CQ / CQ-editor. Which version are you using?
I can run your code without any issue using the master version of CQ / CQ-editor.
@adam-urbanczyk just to be sure, the example as @kkpal3 provided it does run, but when you modify the provided BladeInfo.dat
and change one of the numbers in the last column to eg. 2, then it doesn't run. Is that the case for you?
When I change the last profile from 1 to 2, I get about 5 minutes of 100% cpu usage then Standard_ConstructionError: BRepFill :: profiles are inconsistent
.
Thank you @adam-urbanczyk and @marcus7070 for the discussions, and sorry for not being clear about my questions. Yes, I meant when I use a different type of airfoil along the spanwise direction, for example, change the last profile from 1 to 2, it will give me errors.
I just checked my code again and found that I made a mistake!! I was not using the same number of points for the airfoil type 1, naca 6412. Once I discard this type and use the rest of the three airfoils for the test, cad-query seems to work well!!
Good to hear @kkpal3 . You might be also interested ins using spline
instead of polyline
and note that one profile is misisng or the spine should not start at (0,0,0). You can also just used loft
and not specify any extrusion path at all.
Thanks @adam-urbanczyk for the suggestions.
I investigated my codes a little bit more, and found that the sweep
operation still failed when there is a large change in the sectional geometry, for example, from a circle to a thin airfoil, using the same number of points for both geometries.
Anyway, I will try what you suggested and report more thorough results later.
Did you mange to get some interesting result @kkpal3 ? I'm really curious.
Sorry for the delay @adam-urbanczyk. I haven't got a satisfactory wind blade model yet. I will explain what I have tried so far. Let me know if you have any suggestions! The code is here. dtuTest.zip
Firstly, there is always problem when I try to loft over more than 2 blade sections whose shape changes drastically, say from circle to airfoil, see the fig below.
Secondly, even with similar airfoil shapes, there seems to be wiggles over a large number of sections, which is undesirable, see the fig below.
Thirdly, sweep seems to perform inferior to loft, so I did not try it much.
The best I can get so far is to loft segment-by-segment, as loft with two any TWO sections always work nicely. However, when using a lot number of sections, this approach also results in error (this error can be reproduced when using "BladeInfo.dat" instead of "BladeInfo2.dat", the latter is an abridged version of the former). The problem with this approach is that the surface of the blade is no longer smooth, as the slope at intersecting airfoil sections of two loft process is not ensured to match.
For wings a Gordon algorithm would be a better fit imo. Not sure if it can be made easily available but here they ported it to python from tigl c++ https://github.com/tpaviot/pythonocc-core/issues/409
@kkpal3 I could not get this to work either. One way to slightly improve the situation is to use BRepOffsetAPI_ThruSections.SetMaxDegree
from OCC (not exposed currently). Probably you'll need to investigate using Gordon Surface for this as mentioned above. It is not implemented in CQ (PR would be very welcome). You could use https://github.com/DLR-SC/tigl or https://github.com/tomate44/CurvesWB to check if it solves the issue.
Thanks for the comments. I just found a piece of code based on open cascade here. It seems to work nicely. I'm very new to open cascade, but do you think it's possible to implement it in cadquery?
Interesting, I must say I find it difficult to follow the intent of the code you linked to. It seems that it is using multiple lofts with additional smoothing. CadQuery is based on OCP which wraps opencascade/OCCT so you could in principle directly translate the code to Python.
Hi, I just learned that it is possible to directly use opencascade method in CadQuery in here. I would like to try to translate this BB3D code into an plugin and use it in CadQuery to make the wind turbine blade.
However, I'm stuck at the first step...
Using the following tutorial code in CQ would result in an error "name BRepPrimAPI_MakeBox is not defined".
return cq.Shape.cast(BRepPrimAPI_MakeBox(gp_Ax2(Vector(-0.1, -1.0, -1.5), Vector(0, 0, 1)), 1.0, 2.0, 3.0).Shape())
How can I link/include the Opencascade functionality in CQ correctly?
You need to import it first: from OCP.BRepPrimAPI import BRepPrimAPI_MakeBox
. Not that you'll also need to use gp_Vec
and not Vector
.
Hello, I have a similar code to create a fan wing. I did the same operations mentioned by @kkpal3, however, the final result that I get is a hollow solid, since i created a loft between a set of airfoils created as wires.
What I want, however, is a rigid solid body. How could I change the code to get to the result I want?
@joaotcarvalho Can you share sample code that produces the result above?
Yes, sure! The code and the data (3d points for the blade's airfoil) are attached. You can unzip the file and open the script in Cq-Editor to see the result.
This is what I found in the documentation regarding "cq.Solid.makeLoft", but for some reason it seems that the conversion to faces is just not possible for me, and I don't know how to fix it.
"makes a loft from a list of wires The wires will be converted into faces when possible– it is presumed that nobody ever actually wants to make an infinitely thin shell for a real FreeCADPart"
Here is a workaround. Currently loft is unable to cap non-planar sections, so I did that manually using makeNSidedSurface
.
#%%
import pandas as pd
import cadquery as cq
import os
from cadquery.vis import show
#%%
path = os.getcwd()
print("\n", path)
airfoil_pts_dict = {}
for i in range(11):
airfoil_df = pd.read_table(path+"\\data\\perfil_{}.txt".format(i), sep=" ", names=['X', 'Y', 'Z'])
airfoil_pts = []
for row in range(len(airfoil_df)):
airfoil_pts.append(tuple(airfoil_df.loc[row]))
airfoil_pts_dict["airfoil_{}_pts".format(i)] = airfoil_pts
airfoil_splines_dict = {}
for i in airfoil_pts_dict:
airfoil_splines_dict["spline_{}".format(i)] = cq.Workplane("XY").spline(airfoil_pts_dict[i]).close().wire().val()
sections = list(airfoil_splines_dict.values())
cap0 = cq.Face.makeNSidedSurface(sections[:1],[])
cap1 = cq.Face.makeNSidedSurface(sections[-1:],[])
sides = cq.Solid.makeLoft(sections).Faces()
shell = cq.Shell.makeShell(sides + [cap0, cap1])
result = cq.Solid.makeSolid(shell)
#%%
show(result, *sections)
Works fine! Thank you very much for the help :)
Hi, I'm trying to use cadquery to build a wind turbine blade. I'm defining the blade sections by sections along the spanwise direction. Each section has a specific airfoil shape, twist and chord length. I have successfully build the airfoils sections along the span by inputting coordinates and closing them by polyline() function.
After all the sections are built, I define a path along the spanwise direction to do the sweep() function. However, I always get errors like "Standard_ConstructionError: BRepFIll:: profiles are inconsistent", or "Standard_NoSuchObject:BRepFill::SameNumberByPolarMethod failed", even though I use the same number of coordinates for each airfoil section! I believe this problem is caused by the different airfoil shape along the span, as I can successfully build the blade using the same airfoil for all spanwise locations.
Does anyone have suggestions how to solve this problem? Many thanks!