gumyr / build123d

A python CAD programming library
Apache License 2.0
569 stars 94 forks source link

STEP file of filleted cylinder invalid according to OnShape #693

Open jdegenstein opened 2 months ago

jdegenstein commented 2 months ago
with BuildPart() as test:
    with BuildSketch(Plane.XY):
        Circle(11.15)
    extrude(amount=38/2, both=True)
    fillet(test.edges().filter_by(GeomType.CIRCLE), 0.5)

with BuildPart() as test2:
    with BuildSketch(Plane.XZ):
        Rectangle(11.15, 38, align=(Align.MIN, Align.CENTER))
    revolve(axis=Axis.Z)
    fillet(test2.edges().filter_by(GeomType.CIRCLE), 0.5)

Exporting test as STEP produces a file that is invalid according to OnShape and SolidWorks but valid according to Mayo and FreeCAD. Exporting test2 as STEP produces a file that is valid according to all 4 of the above softwares. I have attached both below in a zip file: tests.zip

EDIT also:

test.part.volume == test2.part.volume

Returns True

gumyr commented 2 months ago

The first Circle has two numeric parameters where it should only have one - I assume that doesn't change how OnShape & SolidWorks sees the STEP file - correct?

Does the problem persist without the extrude(..., both=True)?

jdegenstein commented 2 months ago

Sorry for that error in test --> I edited the above and re-tested it in OnShape and it is still invalid. Regarding your other idea:

with BuildPart() as test3:
    with BuildSketch(Plane.XY):
        Circle(11.15)
    extrude(amount=38)
    fillet(test3.edges().filter_by(GeomType.CIRCLE), 0.5)

Also produces an invalid STEP file according to OnShape.

gumyr commented 2 months ago

Is the fillet required to see the problem in OnShape?

jdegenstein commented 2 months ago

Yes, a regular cylinder imports to OnShape just fine.

Here is a screenshot of the STEP file from test-- and only one of the two fillets appears to be problematic (the one lower in z-value) image

jdegenstein commented 2 months ago

Another data point: if I export STEP of test from build123d and import/export using Mayo or FreeCAD the resulting file IS valid according to OnShape. I have attached one from Mayo here: test_cyl_MAYO.zip

I ran diff between the input and output files:

--- test_cyl.step   2024-09-10 09:35:31.863184200 -0500
+++ test_cyl_MAYO.step  2024-09-10 09:39:01.567041400 -0500
@@ -1,9 +1,8 @@
 ISO-10303-21;
 HEADER;
-FILE_DESCRIPTION(('Open CASCADE Model'),'2;1');
-FILE_NAME('Open CASCADE Shape Model','2024-09-10T09:35:31',('Author'),(
-    'Open CASCADE'),'Open CASCADE STEP processor 7.7','Open CASCADE 7.7'
-  ,'Unknown');
+FILE_DESCRIPTION(('OpenCascade Model'),'2;1');
+FILE_NAME('Open CASCADE Shape Model','2024-09-10T09:39:01',(''),(''),
+  'Open CASCADE STEP processor 7.7','Open CASCADE 7.6','Unknown');
 FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
 ENDSEC;
 DATA;
@@ -44,7 +43,7 @@
 #33 = AXIS2_PLACEMENT_3D('',#34,#35,#36);
 #34 = CARTESIAN_POINT('',(0.,0.,0.));
 #35 = DIRECTION('',(0.,0.,1.));
-#36 = DIRECTION('',(1.,0.,0.));
+#36 = DIRECTION('',(1.,0.,-0.));
 #37 = DEFINITIONAL_REPRESENTATION('',(#38),#42);
 #38 = LINE('',#39,#40);
 #39 = CARTESIAN_POINT('',(6.28318530718,-19.));
@@ -56,7 +55,7 @@
 #43 = PCURVE('',#32,#44);
 #44 = DEFINITIONAL_REPRESENTATION('',(#45),#49);
 #45 = LINE('',#46,#47);
-#46 = CARTESIAN_POINT('',(0.,-19.));
+#46 = CARTESIAN_POINT('',(4.138911435803E-13,-19.));
 #47 = VECTOR('',#48,1.);
 #48 = DIRECTION('',(-0.,1.));
 #49 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
@@ -119,14 +118,14 @@
 #98 = DIRECTION('',(1.,0.,-0.));
 #99 = DEFINITIONAL_REPRESENTATION('',(#100),#104);
 #100 = LINE('',#101,#102);
-#101 = CARTESIAN_POINT('',(-0.,0.));
+#101 = CARTESIAN_POINT('',(6.28318530718,0.));
 #102 = VECTOR('',#103,1.);
 #103 = DIRECTION('',(-1.,0.));
 #104 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
 PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
   ) );
 #105 = ADVANCED_FACE('',(#106),#94,.T.);
-#106 = FACE_BOUND('',#107,.F.);
+#106 = FACE_BOUND('',#107,.T.);
 #107 = EDGE_LOOP('',(#108,#130,#131,#132));
 #108 = ORIENTED_EDGE('',*,*,#109,.F.);
 #109 = EDGE_CURVE('',#22,#110,#112,.T.);
@@ -142,8 +141,8 @@
 #119 = DEFINITIONAL_REPRESENTATION('',(#120),#123);
 #120 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#121,#122),.UNSPECIFIED.,.F.,.F.,
   (2,2),(0.,1.570796326795),.PIECEWISE_BEZIER_KNOTS.);
-#121 = CARTESIAN_POINT('',(0.,0.));
-#122 = CARTESIAN_POINT('',(0.,1.570796326795));
+#121 = CARTESIAN_POINT('',(-4.138911435803E-13,0.));
+#122 = CARTESIAN_POINT('',(-4.138911435803E-13,1.570796326795));
 #123 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
 PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
   ) );
@@ -151,8 +150,8 @@
 #125 = DEFINITIONAL_REPRESENTATION('',(#126),#129);
 #126 = B_SPLINE_CURVE_WITH_KNOTS('',1,(#127,#128),.UNSPECIFIED.,.F.,.F.,
   (2,2),(0.,1.570796326795),.PIECEWISE_BEZIER_KNOTS.);
-#127 = CARTESIAN_POINT('',(-6.28318530718,0.));
-#128 = CARTESIAN_POINT('',(-6.28318530718,1.570796326795));
+#127 = CARTESIAN_POINT('',(6.28318530718,0.));
+#128 = CARTESIAN_POINT('',(6.28318530718,1.570796326795));
 #129 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
 PARAMETRIC_REPRESENTATION_CONTEXT() REPRESENTATION_CONTEXT('2D SPACE',''
   ) );
@@ -169,7 +168,7 @@
 #140 = PCURVE('',#94,#141);
 #141 = DEFINITIONAL_REPRESENTATION('',(#142),#146);
 #142 = LINE('',#143,#144);
-#143 = CARTESIAN_POINT('',(-0.,1.570796326795));
+#143 = CARTESIAN_POINT('',(6.28318530718,1.570796326795));
 #144 = VECTOR('',#145,1.);
 #145 = DIRECTION('',(-1.,0.));
 #146 = ( GEOMETRIC_REPRESENTATION_CONTEXT(2) 
@@ -181,7 +180,7 @@
 #150 = CARTESIAN_POINT('',(-1.226403706313E-15,3.540108884225E-17,-19.)
   );
 #151 = DIRECTION('',(0.,0.,1.));
-#152 = DIRECTION('',(1.,0.,0.));
+#152 = DIRECTION('',(1.,0.,-0.));
 #153 = DEFINITIONAL_REPRESENTATION('',(#154),#158);
 #154 = CIRCLE('',#155,10.65);
 #155 = AXIS2_PLACEMENT_2D('',#156,#157);
@@ -245,7 +244,7 @@
 #203 = AXIS2_PLACEMENT_3D('',#204,#205,#206);
 #204 = CARTESIAN_POINT('',(-1.226403706313E-15,3.540108884225E-17,19.));
 #205 = DIRECTION('',(0.,0.,1.));
-#206 = DIRECTION('',(1.,0.,0.));
+#206 = DIRECTION('',(1.,0.,-0.));
 #207 = DEFINITIONAL_REPRESENTATION('',(#208),#212);
 #208 = CIRCLE('',#209,10.65);
 #209 = AXIS2_PLACEMENT_2D('',#210,#211);
jdegenstein commented 2 months ago

I was able to manually fix the file as indicated by the diff above, I simply changed one character from #106 = FACE_BOUND('',#107,.F.); to #106 = FACE_BOUND('',#107,.T.); and now it happily imports into OnShape. see attached file here: test_cyl_T.zip

Based on my research the F and T are booleans in the STEP format.

gumyr commented 2 months ago

There is a difference in the Open CASCADE 7.7 (OCCT) vs. 'Open CASCADE 7.6' (Mayo) - could a bug with FACE_BOUND have been introduced?