Using shell on an extruded spline fails

203 views
Skip to first unread message

Wink Saville

unread,
Jul 13, 2020, 8:12:14 PM7/13/20
to CadQuery
I'm unable to shell a wing created with a spline based airfoil file. I get
the error "Null TopoDS_Shape object", here is the file, nwing.py:

(cqgui-master) wink:~/prgs/CadQuery/projects/wing4 (master)
$ python nwing.py 
Traceback (most recent call last):
  File "nwing.py", line 30, in <module>
    halfWingShell = halfWing.shell(-0.1)
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/cq.py", line 1123, in shell
    s = solidRef.shell(faces, thickness)
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 1630, in shell
    s1 = self.__class__(shell_builder.Shape()).Shells()[0].wrapped
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 312, in __init__
    self.wrapped = downcast(obj)
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 286, in downcast
    f_downcast: Any = downcast_LUT[shapetype(obj)]
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 276, in shapetype
    raise ValueError("Null TopoDS_Shape object")
ValueError: Null TopoDS_Shape object



 (cqgui-master) wink:~/prgs/CadQuery/projects/wing4 (master)
 $ python ewing.py 



Jeremy Wright

unread,
Jul 13, 2020, 10:18:11 PM7/13/20
to CadQuery
I can get it to work if I select one of the X faces and use a positive shell value.

halfWingShell = halfWing.faces("<X").shell(0.1)

Screenshot from 2020-07-13 22-16-58.png

Wink Saville

unread,
Jul 14, 2020, 3:18:00 AM7/14/20
to Jeremy Wright, CadQuery
Yep, I just tried it and it did work when using `halfWingShell = halfWing.faces("<X").shell(0.1)`.
But get the error below with -0.1,  `halfWingShell = halfWing.faces("<X").shell(-0.1)`:

(cqgui-master) wink@3900x:~/prgs/CadQuery/projects/wing4 (master)

$ python nwing.py
Traceback (most recent call last):
  File "nwing.py", line 31, in <module>
    halfWingShell = halfWing.faces("<X").shell(-0.1)

  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/cq.py", line 1123, in shell
    s = solidRef.shell(faces, thickness)
  File "/opt/anaconda/envs/cqgui-master/lib/python3.7/site-packages/cadquery/occ_impl/shapes.py", line 1622, in shell
    rv = shell_builder.Shape()
OCP.StdFail.StdFail_NotDone: BRep_API: command not done

I now notice the trailing edge looks funny even without the shell but looks fine if "fattenTe" is NOT used.
Although even without "fattenTe" it still fails as above with not only -0.1 but also -0.01 and -0.001. So the problem
doesn't seem directly related to using "fattenTe".

I'll investigate the trailing edge problem and report back tomorrow.

Good night/Good morning :)

--
cadquery home: https://github.com/dcowden/cadquery
post issues at https://github.com/dcowden/cadquery/issues
run it at home at : https://github.com/jmwright/cadquery-freecad-module
see it in action at http://www.parametricparts.com
---
You received this message because you are subscribed to a topic in the Google Groups "CadQuery" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cadquery/_7JI1Ffl2N4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cadquery+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cadquery/fb82c8ee-3719-4423-a898-88a902b1135fn%40googlegroups.com.

Jeremy Wright

unread,
Jul 14, 2020, 7:52:59 AM7/14/20
to CadQuery
> BRep_API: command not done

Yeah, I dread that error. It usually means it's a kernel problem and doesn't give you any information for tracking it down. Adam might have an idea on what the problem is, but I'm not sure. As a work-around, offset2D was recently merged. You could try to offset the spline inward and then extrude the inner and outer profiles as a shell. No guarantee, but it might work for you. https://github.com/CadQuery/cadquery/pull/397

I notice the weird rendering artifacts in CQ-editor. I'm not sure if the exported mesh would have those same artifacts or not.

Wink Saville

unread,
Jul 14, 2020, 3:52:26 PM7/14/20
to CadQuery
I've looked at the trailing edge problem using nwing.py, below, from my cq-wing4 repo.

(cqgui-master) wink:~/prgs/CadQuery/projects/wing4 (master)
$ cat nwing.py
from naca5305 import naca5305
from scale import scaleListOfTuple
from fattenTe import fattenTe

import cadquery as cq # type: ignore

chord: float = 50 
h = 100

# Normalize, Scale, fattenTe
scaleFactor = 1/naca5305[0][0]
nNaca5305 = scaleListOfTuple(naca5305, scaleFactor)
sNaca5305 = scaleListOfTuple(nNaca5305, chord)
#fNaca5305 = fattenTe(sNaca5305, 0.25, 10)
fNaca5305 = sNaca5305

# Create the 2D airfoil then extrude
airfoil = cq.Workplane("YZ").spline(fNaca5305).close()
halfWing = airfoil.extrude(h)

# Shell the halfWing
halfWingShell = halfWing.shell(0.1)
show_object(halfWingShell)
#show_object(halfWing)

I've taken some screen shots, the first one, halfWingShell-nrmlTe-shell_+0.1-yAxis-3.png
shows the "normal trailing edge" with a "full" positive shell and it looks "clean":

halfWingShell-nrmlTe-shell_+0.1-yAxis-3.png

But if you look at the "fattened trailing edge" you can see a big "notch" and and other "divits":

halfWingShell-fatTe-shell_+0.1-yAxis-3.png

So fundementally the fattenTe logic seems to generating a contigious trailing edge
although the simple interpolation isn't the smoothest it's weird it would causes the
discontinuities we see along the trailing edge. Here are pics of the 2D airfoil for both
normal and fattened:

Normal:
airfoil-nrmlTe-shell_+0.1.png

Fattened:
airfoil-fatTe-shell_+0.1.png

Actually with a fattening of 1 you can see a small ridge on the top because I assume the
points are equally distributed. Maybe that's part of the problem?

airfoil-fatTe_1-shell_+0.1.png

I'll keep looking, but wanted to post what I've learned so far.

Adam Urbanczyk

unread,
Jul 15, 2020, 12:21:51 PM7/15/20
to CadQuery
It seems that you reached some kind of limit of the CAD kernel. Here are some  ideas:

(1) If you have the exact function that describes your profile you can try if parametricCurve and higher number of points would help.
(2) If you know the tangents at every point you could also use those, possible making the spline more well-behaved
(3) The other option, as Jeremy mentioned, is to try offset2D.

Wink Saville

unread,
Jul 16, 2020, 2:22:21 AM7/16/20
to CadQuery
So I've done some experiments with ellipses which are "kinda-like-airfoils". Since they can't be done well, it's no wonder my airfoils don't do well. So I think I'll try the `offset2D` suggestion from Jeremy.

The reason for choosing that is in general the airfoil can be many different shapes and in most cases not computable. Although, in actual fact, the one I'm trying now, naca5305, could probably be turned into a "parametricCurve", but since shell can't handle ellipses well, I don't have much hope it could handle something that is round on one end and very very thin on the other.

Actually, I may have to handle the entire wing my self. Along those lines, I'm wondering, if I use "wires" or "edges" can I create manifolds of "arbitrary" shapes?

Jeremy Wright

unread,
Jul 16, 2020, 1:42:44 PM7/16/20
to CadQuery
This WIP PR might be of interest to you: https://github.com/CadQuery/cadquery/pull/406

With that you might be able to define your airfoil profile as a DXF, import that, then extrude it. It probably won't fix the shelling issue, but would give you some extra flexibility on how you create the outer and inner profiles of the airfoil.

Wink Saville

unread,
Jul 16, 2020, 3:30:12 PM7/16/20
to CadQuery
That is very interesting, I've subscribed to them so I can follow along, txs.

Wink Saville

unread,
Jul 18, 2020, 7:58:12 PM7/18/20
to CadQuery
In repo cq-offset2DvsShell I explore the two commands, and indeed
offset2D does work in cases where shell doesn't.

My explanation for this is that if the number of vertices for the "inner"
object is not equal to the number of vertices in the outer object you
get a `ValueError`.

I could be totally wrong, but that is my guess.

This intformation, with the "actual" reason it fails, might be useful
addition to the documentation. Be glad to add it if there is an appropriate
place for this type of information in the documentation.



Adam Urbanczyk

unread,
Jul 19, 2020, 1:22:44 PM7/19/20
to CadQuery
The offset algo does not work (yet) with self-intersections (see https://www.opencascade.com/doc/occt-7.4.0/refman/html/class_b_rep_offset_a_p_i___make_thick_solid.html#a96e66fd6d047d844eb6f261b86e0a9a5 ) and that is why you saw weird result for offsets >minor radius on an ellipse. I don't think though that is is the same issue for the simple object you linked above.

Wink Saville

unread,
Jul 19, 2020, 4:22:36 PM7/19/20
to CadQuery
Could defintely be two different problems.

One other note, my son-in-law has SolidWorks and its shell command
was able to produce reasonable results for both the simple "airfoil" with
the thick trailing edge and the ellipse.

Adam Urbanczyk

unread,
Jul 22, 2020, 3:57:48 PM7/22/20
to CadQuery
If I set the Intersection arg to true (see link above) your example works. SolidWorks has no relation to CQ (i.e. different CAD kernel), so I'm not sure how it is supposed to help.

Wink Saville

unread,
Jul 23, 2020, 3:10:48 PM7/23/20
to CadQuery
On Wednesday, July 22, 2020 at 12:57:48 PM UTC-7 Adam Urbanczyk wrote:
If I set the Intersection arg to true (see link above) your example works. SolidWorks has no relation to CQ (i.e. different CAD kernel), so I'm not sure how it is supposed to help.

I've probably done something wrong, I changed "def shell" in shapes.py
to set Intersection to True and it didn't make any difference for me. As for
SolidWorks, it was just a check to see if it was valid on other platorms, for
all I knew it was totally invalid.

I also needed to change increase the "Deviation" by 10x, to be at least "0.0001",
in 3DViewer preferences, otherwise cq-editor didn't finish within a few minutes.
As you can see in the screenshot I was using "Deviation=0.01" the these tests.

Here is the shapes.py diff:

(cq-dev4) wink@3900x:~/prgs/CadQuery/forks/cadquery (master)
$ git diff
diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py
index c26889d..7f33f41 100644
--- a/cadquery/occ_impl/shapes.py
+++ b/cadquery/occ_impl/shapes.py
@@ -1677,20 +1677,23 @@ class Mixin3D(object):
 
         occ_faces_list = TopTools_ListOfShape()
 
+        intersection=True
         if faceList:
+            print(f'shapes.shell with faceList, Intersection={intersection}')
             for f in faceList:
                 occ_faces_list.Append(f.wrapped)
 
             shell_builder = BRepOffsetAPI_MakeThickSolid(
-                self.wrapped, occ_faces_list, thickness, tolerance
+                self.wrapped, occ_faces_list, thickness, tolerance, Intersection=intersection
             )
 
             shell_builder.Build()
             rv = shell_builder.Shape()
 
         else:  # if no faces provided a watertight solid will be constructed
+            print(f'shapes.shell NO faceList, Intersection={intersection}')
             shell_builder = BRepOffsetAPI_MakeThickSolid(
-                self.wrapped, occ_faces_list, thickness, tolerance
+                self.wrapped, occ_faces_list, thickness, tolerance, Intersection=intersection
             )
 
             shell_builder.Build()

Here is the output at the terminal:

(cq-dev4) wink@3900x:~/prgs/CadQuery/projects/shellellipse (master)
$ cq-editor shellellipse.py 
Namespace(filename='shellellipse.py')
TKOpenGl | Type: Other | ID: 0 | Severity: Medium | Message:
  OpenGl_Window::CreateWindow: window Visual is incomplete: no stencil buffer
Font_FontMgr, warning: unable to find font 'Courier' [regular]; 'Cantarell' [aspects: regular,bold] [paths: /usr/share/fonts/cantarell/Cantarell-Regular.otf;/usr/share/fonts/cantarell/Cantarell-Bold.otf] is used instead
shapes.shell with faceList, Intersection=True
(cq-dev4) wink@3900x:~/prgs/CadQuery/projects/shellellipse (master)
$ cq-editor shellellipse.py 
Namespace(filename='shellellipse.py')
TKOpenGl | Type: Other | ID: 0 | Severity: Medium | Message:
  OpenGl_Window::CreateWindow: window Visual is incomplete: no stencil buffer
Font_FontMgr, warning: unable to find font 'Courier' [regular]; 'Cantarell' [aspects: regular,bold] [paths: /usr/share/fonts/cantarell/Cantarell-Regular.otf;/usr/share/fonts/cantarell/Cantarell-Bold.otf] is used instead
shapes.shell with faceList, Intersection=False

And here a screen shot, it is the same whether I left the code unchanged or
set intersection to True or False:

ss-intersection-set.png


Jeremy Wright

unread,
Aug 21, 2020, 7:26:22 PM8/21/20
to CadQuery
@Wink I wondered if there's maybe some things you could gather from this article for your work with airfoils. https://hackaday.com/2020/08/14/quick-3d-printed-airfoils-with-these-openscad-helpers/

Wink Saville

unread,
Aug 22, 2020, 5:11:20 PM8/22/20
to CadQuery
Txs for the info!

Adam Urbanczyk

unread,
Aug 22, 2020, 6:15:08 PM8/22/20
to CadQuery
This looks relevant too: https://github.com/chiefenne/PyAero . Especially the "airfoil splining and refining" part.

Op zaterdag 22 augustus 2020 om 23:11:20 UTC+2 schreef Wink Saville:

Wink Saville

unread,
Aug 24, 2020, 11:21:49 AM8/24/20
to CadQuery
Very nice, txs.
Reply all
Reply to author
Forward
0 new messages