Make a Thread like in OCC Bottle Example, is possible?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Make a Thread like in OCC Bottle Example, is possible?

Post by onekk »

Hello,

I'm studying some example on OpenCascade tutorials, and I've seen the Part about "OCC Bottle".

https://dev.opencascade.org/doc/occt-7. ... orial.html

There is a similar part in the wiki:

https://wiki.freecadweb.org/Topological_data_scripting

But it lacks of the thread part.

This is the relevant code in the OCC example

Code: Select all

    // Threading : Define 2D Curves
    gp_Pnt2d aPnt(2. * M_PI, myNeckHeight / 2.);
    gp_Dir2d aDir(2. * M_PI, myNeckHeight / 4.);
    gp_Ax2d anAx2d(aPnt, aDir);
    Standard_Real aMajor = 2. * M_PI;
    Standard_Real aMinor = myNeckHeight / 10;
    Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor);
    Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4);
    Handle(Geom2d_TrimmedCurve) anArc1 = new Geom2d_TrimmedCurve(anEllipse1, 0, M_PI);
    Handle(Geom2d_TrimmedCurve) anArc2 = new Geom2d_TrimmedCurve(anEllipse2, 0, M_PI);
    gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0);
    gp_Pnt2d anEllipsePnt2 = anEllipse1->Value(M_PI);
    Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2);
    // Threading : Build Edges and Wires
    TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
    TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1);
    TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2);
    TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2);
    TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1);
    TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2);
    BRepLib::BuildCurves3d(threadingWire1);
    BRepLib::BuildCurves3d(threadingWire2);
I'm stuck with two things:

Code: Select all

anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor);
Ellipse have an axis as first parameter to orient the build of the ellipse

Code: Select all

anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
It seems that is projecting anArc1 over the cylindrical surface to obtain the thread building it using these edges.

Is this feasible in FC?

I've put together some verbose code, but is has errors and surely "some very bad coding in it"
OCC_thread.py
(5.89 KiB) Downloaded 20 times
It is more a question that a real need, but just in case someone is interested... :D

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Make a Thread like in OCC Bottle Example, is possible?

Post by Chris_G »

Sorry, its time to go to bed, so I'll be short.
Ellipse2d has a constructor that can match our needs :

Code: Select all

 |  Part.Geom2d.Ellipse2d(S1,S2,Center)
 |      Creates an ellipse centered on the point Center,
 |                          its major axis is defined by Center and S1,
 |                          its major radius is the distance between Center and S1, and
 |                          its minor radius is the distance between S2 and the major axis.
For the projection on a surface, we have :

Code: Select all

a_Geom2d.toShape(a_surface3D)
Here is the part modified part of code :

Code: Select all

aPnt = vec2(2.0 * pi, myNeckHeight / 2.0)
aDir = vec2(0, myNeckHeight / 4.0)

aMajor = 2.0 * pi
aMinor = myNeckHeight / 10


anAx2d = Part.Geom2d.Line2d(aPnt, aDir)
S1 = anAx2d.value(aMajor)
anAx2d.rotate(aPnt, pi/2)
S2 = anAx2d.value(aMinor)
S3 = anAx2d.value(aMinor / 4.0)
anEllipse1 = Part.Geom2d.Ellipse2d(S1, S2, aPnt)
anEllipse2 = Part.Geom2d.Ellipse2d(S1, S3, aPnt)

anEdge1OnSurf1 = anEllipse1.toShape(aCyl1.Face1.Surface)
# anEdge2OnSurf1 = Part.Edge(anArc1, aCyl1)
anEdge1OnSurf2 = anEllipse2.toShape(aCyl2.Face1.Surface)
# anEdge2OnSurf2 = Part.Edge(anArc1, aCyl1)
Part.show(anEdge1OnSurf1, "anEdge1OnSurf1")
Part.show(anEdge1OnSurf2, "anEdge1OnSurf2")
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Make a Thread like in OCC Bottle Example, is possible?

Post by onekk »

Chris_G wrote: Sat Jan 29, 2022 10:30 pm Sorry, its time to go to bed, so I'll be short.
No problem at all, thanks for you kindness.

Here some other question :D

Code: Select all

    Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2);
This could be made as:

Code: Select all

aSegment = Part.Geom2d.Line2dSegment(anEllipsePnt1, anEllipsePnt2)

Code: Select all

    // Threading : Build Edges and Wires
    TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
    TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2);
These you have kindly made as:

Code: Select all

anEdge1OnSurf1 = anEllipse1.toShape(aCyl1.Face1.Surface)
anEdge1OnSurf2 = anEllipse2.toShape(aCyl2.Face1.Surface) 
But where is anArc1 starting point as in the OCCT code?

Code: Select all

    
    TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1);
    TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2);
    TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1);
    TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2);
    BRepLib::BuildCurves3d(threadingWire1);
    BRepLib::BuildCurves3d(threadingWire2);

And I could not catch how to translate above pieces of code.

Images seems to show a very similar thing, so maybe it sill suffice.

Images to be put later

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Make a Thread like in OCC Bottle Example, is possible?

Post by Chris_G »

onekk wrote: Sun Jan 30, 2022 3:23 pm But where is anArc1 starting point as in the OCCT code?
I somehow missed that the 2 profiles of the threading are made from an arc of ellipse (from 0 to pi) and a line segment (the major axis).
So we would need to do like this :

Code: Select all

anArc1 = Part.Geom2d.ArcOfEllipse2d(anEllipse1, 0, pi)
anArc2 = Part.Geom2d.ArcOfEllipse2d(anEllipse2, 0, pi)
...
# Map the 2D curves on their target surfaces
anEdge1OnSurf1 = anArc1.toShape(aCyl1.Face1.Surface)
anEdge2OnSurf1 = aSegment.toShape(aCyl1.Face1.Surface)
anEdge1OnSurf2 = anArc2.toShape(aCyl2.Face1.Surface)
anEdge2OnSurf2 = aSegment.toShape(aCyl2.Face1.Surface)

# We don't need the BRepLib::BuildCurves3d
# This is done automatically by FreeCAD.
# Proof :
print(anEdge1OnSurf1.Curve)
# returns the 3D curve

threadingWire1 = Part.Wire((anEdge1OnSurf1, anEdge2OnSurf1))
threadingWire2 = Part.Wire((anEdge1OnSurf2, anEdge2OnSurf2))

# The ThruSection (Loft) Part
threadingWires = [threadingWire1, threadingWire2]
loft = Part.makeLoft(threadingWires, True, True)
Part.show(loft, "Thread_loft")
Unfortunately, FC fails to make the loft as a solid ...
onekk wrote: Sun Jan 30, 2022 3:23 pm

Code: Select all

    BRepLib::BuildCurves3d(threadingWire1);
    BRepLib::BuildCurves3d(threadingWire2);
And I could not catch how to translate above pieces of code.
This is not needed. FreeCAD does it automatically when we create a shape from a 2D geometry.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Make a Thread like in OCC Bottle Example, is possible?

Post by onekk »

New file.

Sadly cut is not done, it will be useful to show section, but, there is mark if you made a common instead of cut that will show that the loft is done with the two surfaces,

Upper and lower thread, so it lacks the two part, the face that lies on the neck, and the outer face of the thread.

Probably using the wires to close make the two surfaces, or aSegment, is used to make such closing faces?
OCC_thread.py
(6.78 KiB) Downloaded 15 times
Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply