| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | __title__ = "FreeCAD CutPlane" |
| | __author__ = "Jonathan Wiedemann" |
| | __url__ = "https://www.freecad.org" |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | import FreeCAD |
| | import ArchCommands |
| | import Draft |
| | import Part |
| |
|
| | if FreeCAD.GuiUp: |
| | from PySide import QtCore, QtGui |
| | import FreeCADGui |
| | from draftutils.translate import translate |
| | else: |
| | |
| | def translate(ctxt, txt): |
| | return txt |
| |
|
| | |
| |
|
| |
|
| | |
| | def _getShapes(sels): |
| | """Check and process the user selection. |
| | Returns a tuple: (baseObj, baseShp, cutterShp). |
| | baseShp and cutterShp are in the global coordinate system, cutterShp is a planar face. |
| | If the selection is not valid one or more items in the tuple will be `None`. |
| | """ |
| | if not sels: |
| | return None, None, None |
| | objs = [] |
| | needSubEle = False |
| | for sel in sels: |
| | for sub in sel.SubElementNames if sel.SubElementNames else [""]: |
| | objs.append(Part.getShape(sel.Object, sub, needSubElement=needSubEle, retType=1)) |
| | needSubEle = True |
| | if len(objs) != 2: |
| | return None, None, None |
| | baseShp, _, baseObj = objs[0] |
| | cutterShp, _, _ = objs[1] |
| | if baseShp.isNull(): |
| | return baseObj, None, None |
| | if cutterShp.isNull(): |
| | return baseObj, baseShp, None |
| | if cutterShp.ShapeType == "Edge": |
| | if isinstance(cutterShp.Curve, Part.Line): |
| | cutterShp = _extrudeEdge(cutterShp) |
| | else: |
| | try: |
| | cutterShp = Part.Face(Part.Wire(cutterShp)) |
| | except Part.OCCError: |
| | pass |
| | elif cutterShp.ShapeType == "Wire": |
| | if len(cutterShp.Edges) == 1 and isinstance(cutterShp.Edges[0].Curve, Part.Line): |
| | cutterShp = _extrudeEdge(cutterShp.Edges[0]) |
| | else: |
| | try: |
| | cutterShp = Part.Face(cutterShp) |
| | except Part.OCCError: |
| | pass |
| | if not cutterShp.Faces and cutterShp.Vertexes: |
| | plane = cutterShp.findPlane() |
| | if plane is not None: |
| | |
| | |
| | |
| | pt_main = cutterShp.Vertexes[0].Point |
| | mtx = plane.Rotation.toMatrix() |
| | pt_u = mtx.col(0) + pt_main |
| | pt_v = mtx.col(1) + pt_main |
| | cutterShp = Part.Face(Part.makePolygon([pt_main, pt_u, pt_v, pt_main])) |
| | |
| | if not cutterShp.Faces or cutterShp.Faces[0].Area < 1e-6 or cutterShp.findPlane() is None: |
| | return baseObj, baseShp, None |
| | return baseObj, baseShp, cutterShp.Faces[0] |
| |
|
| |
|
| | def _extrudeEdge(edge): |
| | """Exrude an edge along the WP normal""" |
| | import WorkingPlane |
| |
|
| | return edge.extrude(WorkingPlane.get_working_plane().axis) |
| |
|
| |
|
| | def cutComponentwithPlane(baseObj, cutterShp=None, side=0): |
| | """cut an object with a plane defined by a face. |
| | |
| | Parameters |
| | ---------- |
| | baseObj: Part::FeaturePython object or selection set (a list of Gui::SelectionObject objects) |
| | Object to be cut or a selection set: `FreeCADGui.Selection.getSelectionEx("", 0)`. |
| | If a selection set is provided it should contain baseObj and cutterShp, in that order. |
| | |
| | cutterShp: Part.Shape, optional |
| | Defaults to `None` in which case cutterShp should be in the baseObj selection set. |
| | Either a face or an edge. An edge is extruded along the Draft working plane normal. |
| | The shape should be in the global coordinate system. |
| | |
| | side: 0 or 1, optional |
| | Defaults to 0. |
| | Behind = 0, front = 1. |
| | """ |
| | if ( |
| | isinstance(baseObj, list) |
| | and len(baseObj) >= 1 |
| | and baseObj[0].isDerivedFrom("Gui::SelectionObject") |
| | ): |
| | baseObj, baseShp, cutterShp = _getShapes(baseObj) |
| | baseParent = baseObj.getParentGeoFeatureGroup() |
| | else: |
| | baseShp = baseObj.Shape |
| | baseParent = baseObj.getParentGeoFeatureGroup() |
| | if baseParent is not None: |
| | baseShp = baseShp.transformGeometry(baseParent.getGlobalPlacement().toMatrix()) |
| |
|
| | if cutterShp.ShapeType != "Face": |
| | cutterShp = _extrudeEdge(cutterShp) |
| |
|
| | cutVolume = ArchCommands.getCutVolume(cutterShp, baseShp) |
| | cutVolume = cutVolume[2] if side == 0 else cutVolume[1] |
| | if cutVolume: |
| | obj = FreeCAD.ActiveDocument.addObject("Part::Feature", "CutVolume") |
| | if baseParent is not None: |
| | cutVolume.Placement = baseParent.getGlobalPlacement().inverse() |
| | obj.Shape = Part.Compound([cutVolume]) |
| | if baseParent is not None: |
| | baseParent.addObject(obj) |
| | if "Additions" in baseObj.PropertiesList: |
| | ArchCommands.removeComponents(obj, baseObj) |
| | else: |
| | Draft.format_object(obj, baseObj) |
| | cutObj = FreeCAD.ActiveDocument.addObject("Part::Cut", "CutPlane") |
| | if baseParent is not None: |
| | baseParent.addObject(cutObj) |
| | cutObj.Base = baseObj |
| | cutObj.Tool = obj |
| |
|