[finished] project: Making Part Extrude taking care of inner structure

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
adrianinsaval
Veteran
Posts: 5548
Joined: Thu Apr 05, 2018 5:15 pm

Re: project: Making Part Extrude taking care of inner structure

Post by adrianinsaval »

uwestoehr wrote: Mon Jan 10, 2022 6:37 pm The draft feature is applied to a face and the face number changes during the design process. Therefore I never use drafts in real-life documents anymore. It is just pain to repair the drafts again and again (like with fillets).
Understandable but what I meant is, can't we use Draft's method (that apparently gives better results) instead of the loft approach?
the OCC kernel has problems to shrink small wires - the smaller e.g. the diameter of an inner circle, the more likely it crashes, no matter how small you make the negative offset (negative angle).
does FreeCAD crash too? Does this warrant a bug submission to OCCT? Does the crash happen using the draft method or the loft method? (or both?)
Therefore I am once more convinced that taking care of inner wires should be the second step for PD Pad/Pocket.
And I on the other hand am more weary about integrating this wonky feature now that we have even less indication that it will get better, if it will be that limited IMO it's better to let Draft deal with this and wait for the TN algorithm so it's actually usable. edit: never mind this last sentence, thinking a little longer maybe counting on the TN algo is not a good idea considering how awfully stalled the merge is, planning shouldn't be done based on fairy tales.
Last edited by adrianinsaval on Mon Jan 10, 2022 8:39 pm, edited 1 time in total.
davidosterberg
Posts: 529
Joined: Fri Sep 18, 2020 5:40 pm

Re: project: Making Part Extrude taking care of inner structure

Post by davidosterberg »

adrianinsaval wrote: Mon Jan 10, 2022 8:12 pm What I meant is, can't we use Draft's method (that apparently gives better results) instead of the loft approach?
Exactly. Draft is using an OCC class called BRepOffsetAPI_DraftAngle.

There are some other interesting OCC classes referenced in the Draft code:
  • LocOpe_DPrism can create a stand-alone draft prism (a drafted pad). The sketch can only have a single wire, though
  • BRepFeat_MakeDPrism requires a support for the operation but will probably support multiple wires in the sketch
I am doing some experiments with LocOpe_DPrism now. We shall see if it will create BSplines or planar faces.
User avatar
uwestoehr
Veteran
Posts: 4961
Joined: Sun Jan 27, 2019 3:21 am
Location: Germany
Contact:

Re: project: Making Part Extrude taking care of inner structure

Post by uwestoehr »

davidosterberg wrote: Mon Jan 10, 2022 8:26 pm Exactly. Draft is using an OCC class called BRepOffsetAPI_DraftAngle.
As I wrote this acts on a face: https://dev.opencascade.org/doc/refman/ ... angle.html
-> toponaming alert
davidosterberg wrote: Mon Jan 10, 2022 8:26 pm
  • BRepFeat_MakeDPrism requires a support for the operation but will probably support multiple wires in the sketch
This could be a candidate.

However, can someone please explain me on an example the issue with the B-spline. I still haven't understand it.
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: project: Making Part Extrude taking care of inner structure

Post by TheMarkster »

Line 519, setting the first argument to false means you get shells instead of solids in this intermediate step, but the final shape is still a solid. This is probably why sewing was failing.

Code: Select all

             for (auto& wires : extrusionSections) {
-                BRepOffsetAPI_ThruSections mkTS(params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True, Precision::Confusion());
+               // BRepOffsetAPI_ThruSections mkTS(params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True, Precision::Confusion());
+                BRepOffsetAPI_ThruSections mkTS(Standard_False, /*ruled=*/Standard_True, Precision::Confusion());
 
I'd prefer to use FaceMaker Bullseye because it can manage nested inner wires, such as a bullseye. See line 301.
User avatar
uwestoehr
Veteran
Posts: 4961
Joined: Sun Jan 27, 2019 3:21 am
Location: Germany
Contact:

Re: project: Making Part Extrude taking care of inner structure

Post by uwestoehr »

TheMarkster wrote: Tue Jan 11, 2022 2:30 am Line 519, setting the first argument to false means you get shells instead of solids in this intermediate step, but the final shape is still a solid. This is probably why sewing was failing.
I could identify the problem to this:
- on making the offset wire, the resulting wire ends up at an arbitrary location. This only occurs for inner wires, outer wires keep their positions.
- when all offset wires would keep the position, the sewer succeeds. I could manage to make this work in the PD workbench, and there the trick is to make the offset of a wire and then move it to the desired direction. First moving, the offsetting fails.
- for the Part WB, no matter what I try, just making an offset of an inner wires moves the result to a strange location. Also other face this issue: https://dev.opencascade.org/content/bre ... d-occt-740
TheMarkster wrote: Tue Jan 11, 2022 2:30 am I'd prefer to use FaceMaker Bullseye because it can manage nested inner wires, such as a bullseye. See line 301.
Fine with me. But also this needs all offset wired at the same plane, the inner and the outer ones.
davidosterberg
Posts: 529
Joined: Fri Sep 18, 2020 5:40 pm

Re: project: Making Part Extrude taking care of inner structure

Post by davidosterberg »

uwestoehr wrote: Tue Jan 11, 2022 12:58 am As I wrote this acts on a face: https://dev.opencascade.org/doc/refman/ ... angle.html
-> toponaming alert
I don't think you are right here. PartDesign_Draft is TNP sensitive because it relies on FreeCAD's face numbering. The OCC function does not use face numbers, as long as we can identify what faces should be drafted inside the feature code, everything will be fine with respect to TNP.
uwestoehr wrote: Tue Jan 11, 2022 12:58 am However, can someone please explain me on an example the issue with the B-spline. I still haven't understand it.
Actually topological naming is a good example. Imagine that you create a pad with taper=0. You create a sketch on its side face and continue modeling. Then you change taper angle of the pad. You will then get a failed model.

Addendum:
I will try to make a proposal for how we can use BRepOffsetAPI_DraftAngle to add the draft to the pad before it is fused/cut from the baseshape. It will not rely on topological naming. Any face that is perpendicular to the pad direction will be drafted, inner and outer wires does not matter. And I expect FreeCAD face numbering will remain constant with taper angle 0 or other.
User avatar
-alex-
Veteran
Posts: 1861
Joined: Wed Feb 13, 2019 9:42 pm
Location: France

Re: project: Making Part Extrude taking care of inner structure

Post by -alex- »

davidosterberg wrote: Tue Jan 11, 2022 6:50 am
uwestoehr wrote: Tue Jan 11, 2022 12:58 am However, can someone please explain me on an example the issue with the B-spline. I still haven't understand it.
Actually topological naming is a good example. Imagine that you create a pad with taper=0. You create a sketch on its side face and continue modeling. Then you change taper angle of the pad. You will then get a failed model.
Exactely.
https://forum.freecadweb.org/viewtopic.php?f=8&t=63211

Addendum:
And I expect FreeCAD face numbering will remain constant with taper angle 0 or other.
+1
And with constant linear and planar elements as well I hope.
+1000
chrisb
Veteran
Posts: 54186
Joined: Tue Mar 17, 2015 9:14 am

Re: project: Making Part Extrude taking care of inner structure

Post by chrisb »

uwestoehr wrote: Tue Jan 11, 2022 12:58 am However, can someone please explain me on an example the issue with the B-spline. I still haven't understand it.
Here you are, it's the augmented example from my post above:
chrisb wrote: Mon Jan 10, 2022 1:11 am It is probably better to follow PartDesign Draft than Loft. The attachment shows: While Draft creates Planes, does Loft create BSpline surfaces. This has in the past often lead to problems.
I can use point-on-object on the upper external reference (Draft), but not the lower (Loft):
Attachments
SnipScreenshot-8c9e1e.png
SnipScreenshot-8c9e1e.png (9.13 KiB) Viewed 1655 times
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
User avatar
onekk
Veteran
Posts: 6205
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: project: Making Part Extrude taking care of inner structure

Post by onekk »

uwestoehr wrote: Mon Jan 10, 2022 5:38 pm Most of my real-life sketches contains B-Splines (I even wrote this Wiki page: https://wiki.freecadweb.org/B-Splines ;) ). B-Splines are a basic feature of CAD in my opinion.
Therefore I need to understand the issue properly.

But Bsplines are not scalable, as they a are defined by a math formula that may use "control points" "poles?", "knots?", that are difficult to "transpose".

EDIT:
Interesting reading could be:

https://www.cl.cam.ac.uk/teaching/2000/ ... node4.html

At least for the concluding consideration:
If there are no pressing reasons for doing otherwise, your B-spline should be defined as follows:

k=4 (cubic);
no multiple control points;
uniform (for a closed curve) or open uniform (for an open curve) knot vector.
END EDIT

EDIT2
Some more research, if I have guessed weel you could transform you bspline, apllying the tansformation to the control points.
According to this text.

http://home.iitk.ac.in/~jrkumar/downloa ... %20New.pdf
The entire B-spline curve can be affinely transformed by transforming the control points and redrawing the curve from the transformed points.
END EDIT2

EDIT3

I'have noted the absence of @Chris_G in this disccussion.
Chris_G wrote: Mon Dec 27, 2021 3:35 pm
Sorry for poking :D

Maybe he could help.

END EDIT3

I have had some problems with B-Splines, and usually you could use this approach:
  • discretize the B-Spline segment
  • transform the points to the new shape
  • use the "transformed points" to obtain a new B-Spline in the final objects
Usually as you are making a transformation, you have to create a new in this case a new face.

In case of taper you could also join two corresponding b-splines if they have "same number of edges" with a ruled surface, but this is only a guess as I have not used it in real code, usually I approximate them to BiArcs and operate on them.

Hoping having guessed the problem right.

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
onekk
Veteran
Posts: 6205
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: project: Making Part Extrude taking care of inner structure

Post by onekk »

Some experimenting:

Code: Select all

"""spline_surface.py

   This code was written as an sample code 
   for "FreeCAD Scripting Guide" 
     
   Author: Carlo Dormeletti
   Copyright: 2022
   Licence: CC BY-NC-ND 4.0 IT 
"""

import os
from math import pi, sin, cos

import FreeCAD
from FreeCAD import Placement, Rotation, Vector
import Part


DOC_NAME = "spline_surface"

def activate_doc():
    """activate document"""
    FreeCAD.setActiveDocument(DOC_NAME)
    FreeCAD.ActiveDocument = FreeCAD.getDocument(DOC_NAME)
    FreeCADGui.ActiveDocument = FreeCADGui.getDocument(DOC_NAME)
    print("{0} activated".format(DOC_NAME))


def setview():
    """Rearrange View"""
    DOC.recompute()
    VIEW.viewAxometric()
    VIEW.setAxisCross(True)
    VIEW.fitAll()


def deleteObject(obj):
    if hasattr(obj, "InList") and len(obj.InList) > 0:
        for o in obj.InList:
            deleteObject(o)
            try:
                DOC.removeObject(o.Name)
            except RuntimeError as rte:
                errorMsg = str(rte)
                if errorMsg != "This object is currently not part of a document":
                    FreeCAD.Console.PrintError(errorMsg)
                    return False
    return True


def clear_DOC():
    """
    Clear the active DOCument deleting all the objects
    """
    while DOC.Objects:
        obj = DOC.Objects[0]
        name = obj.Name

        if not hasattr(DOC, name):
            continue

        if not deleteObject(obj):
            FreeCAD.Console.PrintError("Exiting on error")
            os.sys.exit()

        DOC.removeObject(obj.Name)

        DOC.recompute()


if FreeCAD.ActiveDocument is None:
    FreeCAD.newDocument(DOC_NAME)
    print("Document: {0} Created".format(DOC_NAME))

# test if there is an active document with a "proper" name
if FreeCAD.ActiveDocument.Name == DOC_NAME:
    print("DOC_NAME exist")
else:
    print("DOC_NAME is not active")
    # test if there is a document with a "proper" name
    try:
        FreeCAD.getDocument(DOC_NAME)
    except NameError:
        print("No Document: {0}".format(DOC_NAME))
        FreeCAD.newDocument(DOC_NAME)
        print("Document Created".format(DOC_NAME))

DOC = FreeCAD.getDocument(DOC_NAME)
GUI = FreeCADGui.getDocument(DOC_NAME)
VIEW = GUI.ActiveView    

activate_doc()

clear_DOC()

ROT0 = Rotation(0,0,0)

### CODE START HERE ###

# from /Mod/Draft/draftfunctions/scale.py
# implemented by Dion Moult during 0.19 dev cycle

points = [
    Vector(0.0, 0.0, 0.0),
    Vector(0.0, 0.0, 100.0),
    Vector(100.0, 100.0, 200.0),
    Vector(100.0, 300.0, 200.0),
    Vector(0.0, 400.0, 100.0),
    Vector(0.0, 400.0, 0.0)
    ]

spline = Part.BSplineCurve()
spline.interpolate(points)

DOC.recompute()

sp_curv1 = Part.Wire(spline.toShape())

# Part.show(sp_curv1, "Spline")

scale = Vector(0.5, 0.5, 0.5)
center = Vector(0, 0, 0)

poles = spline.getPoles()

npoles = []

for index, point in enumerate(poles):
    npoint = point.sub(center).scale(scale.x, scale.y, scale.z).add(center)
    npoles.append(npoint)

spline2 = Part.BSplineCurve()
spline2.interpolate(npoles)

sp_curv2 = Part.Wire(spline2.toShape())
sp_curv2.Placement = Placement(Vector(1500, 0, 0), ROT0)

DOC.recompute()

# Part.show(sp_curv2, "Spline2")

surf = Part.makeRuledSurface(sp_curv1, sp_curv2)

Part.show(surf, "surface")


setview()
After having inspected some Draft code, I derived the scaling for points, using a center, (for simplicity i put it at the origin) it uses only vector methods, so I think is robust enough, hope it helps.
spline_scaled.png
spline_scaled.png (22.84 KiB) Viewed 1573 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