-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding extrude/cutBlind untilNextSurf option #776
Comments
NB: it is already supported by OCCT (e.g. https://dev.opencascade.org/doc/refman/html/class_b_rep_feat___make_d_prism.html#a39fa6af774981a949eeca992bda75adf). It "just" needs to be properly exposed. |
Should this be exposed at I notice aswell that the For reference, my little test : import cadquery as cq
from OCP.BRepFeat import BRepFeat_MakeDPrism
from OCP.TopoDS import TopoDS_Face
from jupyter_cadquery.viewer.client import show
def extrude_until_next(solid, wire, until_face):
face = cq.Face.makeFromWires(wire)
maker = BRepFeat_MakeDPrism(solid.wrapped, face.wrapped, TopoDS_Face(), 0, 1, True)
maker.Perform(until_face.wrapped)
shape = maker.Shape()
return shape
box = cq.Workplane().box(10,10,10)
wire = box.faces(">X").workplane().rect(4,2).val()
end_face = cq.Workplane(origin=(30,0,0)).sphere(10).split(keepBottom=True).rotate((30,0,0),(30,1,0),90).faces("<X").val()
s = extrude_until_next(box.val(), wire, end_face )
s = cq.Shape.cast(s)
show(s, end_face, cad_width = 1500, height = 900, default_edgecolor = (0,0,0), axes=True) |
What is your question actually? OCP is used in |
Ok sorry, my question is : should this be implemented in the fluent API directly from OCP or should there first be a intermediate layer in From what I understand, the plans with cadquery is to have several layers of abstraction, OCP, occ_impl and the fluent API. And I assume that when exposing new features you usually want to add them first in |
@Jojain I think it may be helpful for you to look at how Workplane.extrude -> Workplane._extrude -> occ_impl.shapes.Solid.extrudeLinear |
I have been working on it and got it working but before going too deep in the implementation I would like to have a consensus of how it should be implemented.
Given the following calls for an extrusion from a
|
You cannot return OCCT objects. Which new class do you want to wrap and why?
Probably a new method in the occ_impl layer would be better. |
It was more to know if I could do that, I don't think I will need to wrap a new class there is several workaround. To share more of my process, I started to write this as a "face selector" def _getNthFace(self, n: int, alongNormal: bool = True, tol: float = 1e-4):
"""
Returns the Nth face from the current object on the stack on the specified direction
To do so it computes the distance from the center of mass object to the intersection point
of a given face with the line defined by the object center of mass and the Workplane.plane.zDir
:param n: Nth face to select
:param alongNormal: If True search along plane normal else along vector opposite to plane normal
:param tol: Line on face intersection tolerance
"""
cog = gp_Pnt(*self.val().Center().toTuple())
dir = gp_Dir(self.plane.zDir.wrapped)
line = gce_MakeLin(cog, dir).Value()
tol = tol
shape = self.findSolid().wrapped
intersectMaker = BRepIntCurveSurface_Inter()
intersectMaker.Init(shape, line, tol)
faces = []
while intersectMaker.More():
interPt = intersectMaker.Pnt()
interDir = gce_MakeDir(cog, interPt)
if interDir.IsDone():
interDir = interDir.Value()
else:
intersectMaker.Next()
continue
distance = cog.SquareDistance(interPt)
if distance < tol: # intersection with the face where the wire is lying
intersectMaker.Next()
continue
if not interDir.IsOpposite(dir, tol):
faces.append((intersectMaker.Face(), distance))
intersectMaker.Next()
faces.sort(key= lambda x: x[1])
return faces[n][0] Now I'm trying to break it down in several parts to be in accordance with the cadquery layers I end up with this intermediary function : def facesIntersectedByLine(point: VectorLike, axis: VectorLike, shape: "Shape", tol: float = 1e-4, direction: Optional[str] = None ):
"""
Computes the intersections between the provided line and the faces of the provided shape
"""
point = gp_Pnt(*point.toTuple()) if isinstance(point, Vector) else gp_Pnt(*point)
axis = gp_Dir(Vector(axis)) if not isinstance(axis, Vector) else gp_Dir(axis)
line = gce_MakeLin(point, axis).Value()
shape = shape.wrapped
intersectMaker = BRepIntCurveSurface_Inter()
intersectMaker.Init(shape, line, tol)
faces = []
while intersectMaker.More():
interPt = intersectMaker.Pnt()
interDirMk = gce_MakeDir(point, interPt)
distance = point.SquareDistance(interPt)
# interDir is not done when `point` and `axis` have the same coord
if interDirMk.IsDone():
interDir = interDirMk.Value()
else:
interDir = None
if direction == "AlongAxis":
if interDir is not None and not interDir.IsOpposite(axis, tol) and distance > tol:
faces.append((intersectMaker.Face(), distance))
elif direction == "Opposite":
if interDir is not None and interDir.IsOpposite(axis, tol) and distance > tol:
faces.append((intersectMaker.Face(), distance))
elif direction is not None:
raise ValueError("Unvalid direction specification.\nValid specification are 'AlongAxis' and 'Opposite'.")
else:
faces.append((intersectMaker.Face(), abs(distance)))
intersectMaker.Next()
faces = [face[0] for face in faces.sorted(key = lambda x: x[1])]
return [TopoDS_Face.cast(face) for face in faces] But I don't really find place for it, it is kindof a selector but at occ_impl level, maybe in |
I'd propose to add the method to the |
Resolved in #875 |
Hello,
I wanted to discuss about a possible new feature for extruding and cutting with prisms.
In Catia V5 and maybe in other CAD softwares there is a nice option when extruding or cutting material from a part which is the
untilNextSurf
. Below is an exemple of what the behavior would be :It is quite trivial for planar faces but it would be expected to work also for non planar faces destinations. I guess for non planar faces we couldn't use the
Solid.extrudeLinear
so it would need to be done through lofting or another operation, so it would require a bit more changes.The text was updated successfully, but these errors were encountered: