Draft/BIM: change BezCurve, BSpline and Wire to Part::FeaturePython
Fixes: #7387. See comment: https://github.com/FreeCAD/FreeCAD/issues/7387#issuecomment-2915599566 PR to change the base object of BezCurve, BSpline and Wire to `Part::FeaturePython`. This will only affect new objects. So code will have to also keep handling the old object type (`Part::Part2DObjectPython`). The modification of BimPreflight.py needs to be verified. The steps in the old code lacked logic IMO. But I may have misunderstood.
This commit is contained in:
@@ -1703,6 +1703,7 @@ def makeWindow(baseobj=None, width=None, height=None, parts=None, name=None):
|
||||
1. If baseobj is not a closed shape, the tool may not create a proper solid figure.
|
||||
"""
|
||||
import Draft
|
||||
import DraftGeomUtils
|
||||
from draftutils import todo
|
||||
|
||||
if baseobj and Draft.getType(baseobj) == "Window" and FreeCAD.ActiveDocument:
|
||||
@@ -1730,8 +1731,12 @@ def makeWindow(baseobj=None, width=None, height=None, parts=None, name=None):
|
||||
window.WindowParts = parts
|
||||
else:
|
||||
if baseobj:
|
||||
if baseobj.getLinkedObject().isDerivedFrom("Part::Part2DObject"):
|
||||
# Base object is a 2D object (sketch or wire)
|
||||
linked_obj = baseobj.getLinkedObject(True)
|
||||
if (linked_obj.isDerivedFrom("Part::Part2DObject")
|
||||
or Draft.getType(linked_obj) in ["BezCurve", "BSpline", "Wire"]) \
|
||||
and DraftGeomUtils.isPlanar(baseobj.Shape):
|
||||
# "BezCurve", "BSpline" and "Wire" objects created with < v1.1 are "Part::Part2DObject" objects.
|
||||
# In all versions these objects need not be planar.
|
||||
if baseobj.Shape.Wires:
|
||||
part_type = "Frame"
|
||||
if len(baseobj.Shape.Wires) == 1:
|
||||
|
||||
@@ -768,11 +768,14 @@ def pruneIncluded(objectslist,strict=False,silent=False):
|
||||
for parent in obj.InList:
|
||||
if not parent.isDerivedFrom("Part::Feature"):
|
||||
pass
|
||||
elif Draft.getType(parent) in ["Space","Facebinder","Window","Roof","Clone","Site","Project"]:
|
||||
pass
|
||||
elif parent.isDerivedFrom("Part::Part2DObject"):
|
||||
# don't consider 2D objects based on arch elements
|
||||
pass
|
||||
elif Draft.getType(parent) in [
|
||||
"BezCurve", "BSpline", "Clone", "Facebinder", "Wire",
|
||||
"Project", "Roof", "Site", "Space", "Window"
|
||||
]:
|
||||
pass
|
||||
elif parent.isDerivedFrom("PartDesign::FeatureBase"):
|
||||
# don't consider a PartDesign_Clone that references obj
|
||||
pass
|
||||
|
||||
@@ -577,7 +577,16 @@ def getDXF(obj):
|
||||
return result
|
||||
if not allOn:
|
||||
objs = Draft.removeHidden(objs)
|
||||
objs = [o for o in objs if ((not(Draft.getType(o) in ["Space","Dimension","Annotation"])) and (not (o.isDerivedFrom("Part::Part2DObject"))))]
|
||||
objs = [
|
||||
obj
|
||||
for obj in objs
|
||||
if (
|
||||
not obj.isDerivedFrom("Part::Part2DObject")
|
||||
and Draft.getType(obj) not in [
|
||||
"BezCurve", "BSpline", "Wire", "Annotation", "Dimension", "Space"
|
||||
]
|
||||
)
|
||||
]
|
||||
vshapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,cutplane,onlySolids,clip,False,showHidden)
|
||||
if vshapes:
|
||||
result.append(TechDraw.projectToDXF(Part.makeCompound(vshapes),direction))
|
||||
|
||||
@@ -256,28 +256,20 @@ class BIM_Preflight_TaskPanel:
|
||||
objs = FreeCADGui.Selection.getSelection()
|
||||
# clean objects list of unwanted types
|
||||
objs = Draft.get_group_contents(objs, walls=True, addgroups=True)
|
||||
objs = [obj for obj in objs if not obj.isDerivedFrom("Part::Part2DObject")]
|
||||
objs = [obj for obj in objs if not obj.isDerivedFrom("App::Annotation")]
|
||||
objs = [
|
||||
obj
|
||||
for obj in objs
|
||||
if (
|
||||
hasattr(obj, "Shape")
|
||||
not obj.isDerivedFrom("App::DocumentObjectGroup")
|
||||
and not obj.isDerivedFrom("App::Annotation")
|
||||
and not obj.isDerivedFrom("Part::Part2DObject")
|
||||
and Draft.getType(obj) not in ["BezCurve", "BSpline", "Wire", "WorkingPlaneProxy"]
|
||||
and hasattr(obj, "Shape")
|
||||
and obj.Shape
|
||||
and not (obj.Shape.Edges and (not obj.Shape.Faces))
|
||||
)
|
||||
]
|
||||
objs = Arch.pruneIncluded(objs)
|
||||
objs = [
|
||||
obj for obj in objs if not obj.isDerivedFrom("App::DocumentObjectGroup")
|
||||
]
|
||||
objs = [
|
||||
obj
|
||||
for obj in objs
|
||||
if Draft.getType(obj)
|
||||
not in ["DraftText", "Material", "MaterialContainer", "WorkingPlaneProxy"]
|
||||
]
|
||||
return objs
|
||||
return Arch.pruneIncluded(objs)
|
||||
|
||||
def getToolTip(self, test):
|
||||
"gets the toolTip text from the ui file"
|
||||
|
||||
@@ -282,9 +282,12 @@ def export(exportList, filename, colors=None, preferences=None):
|
||||
annotations = []
|
||||
specials = []
|
||||
for obj in objectslist:
|
||||
if obj.isDerivedFrom("Part::Part2DObject"):
|
||||
annotations.append(obj)
|
||||
elif obj.isDerivedFrom("App::Annotation") or (Draft.getType(obj) in ["DraftText","Text","Dimension","LinearDimension","AngularDimension"]):
|
||||
if obj.isDerivedFrom("Part::Part2DObject") \
|
||||
or obj.isDerivedFrom("App::Annotation") \
|
||||
or Draft.getType(obj) in [
|
||||
"BezCurve", "BSpline", "Wire",
|
||||
"DraftText", "Text", "Dimension", "LinearDimension", "AngularDimension"
|
||||
]:
|
||||
annotations.append(obj)
|
||||
elif hasattr(obj, "Proxy") and hasattr(obj.Proxy, "export_ifc"):
|
||||
specials.append(obj)
|
||||
|
||||
@@ -215,7 +215,10 @@ def is_annotation(obj):
|
||||
return True
|
||||
elif obj.isDerivedFrom("App::Annotation"):
|
||||
return True
|
||||
elif Draft.getType(obj) in ["DraftText",
|
||||
elif Draft.getType(obj) in ["BezCurve",
|
||||
"BSpline",
|
||||
"Wire",
|
||||
"DraftText",
|
||||
"Text",
|
||||
"Dimension",
|
||||
"LinearDimension",
|
||||
|
||||
@@ -57,7 +57,7 @@ def fuse(object1, object2):
|
||||
if len(f.Wires) > 1:
|
||||
holes = True
|
||||
if DraftGeomUtils.isCoplanar(object1.Shape.fuse(object2.Shape).Faces) and not holes:
|
||||
obj = App.ActiveDocument.addObject("Part::Part2DObjectPython","Fusion")
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", "Fusion")
|
||||
Wire(obj)
|
||||
if App.GuiUp:
|
||||
ViewProviderWire(obj.ViewObject)
|
||||
@@ -65,10 +65,10 @@ def fuse(object1, object2):
|
||||
obj.Tool = object2
|
||||
elif holes:
|
||||
# temporary hack, since Part::Fuse objects don't remove splitters
|
||||
obj = App.ActiveDocument.addObject("Part::Feature","Fusion")
|
||||
obj = App.ActiveDocument.addObject("Part::Feature", "Fusion")
|
||||
obj.Shape = fshape
|
||||
else:
|
||||
obj = App.ActiveDocument.addObject("Part::Fuse","Fusion")
|
||||
obj = App.ActiveDocument.addObject("Part::Fuse", "Fusion")
|
||||
obj.Base = object1
|
||||
obj.Tool = object2
|
||||
if App.GuiUp:
|
||||
|
||||
@@ -563,7 +563,9 @@ def upgrade(objects, delete=False, force=None):
|
||||
_msg(translate("draft", "Found object with several coplanar faces: refining them"))
|
||||
|
||||
# only one object: if not parametric, we "draftify" it
|
||||
elif len(objects) == 1 and not objects[0].isDerivedFrom("Part::Part2DObjectPython"):
|
||||
elif len(objects) == 1 \
|
||||
and not objects[0].isDerivedFrom("Part::Part2DObjectPython") \
|
||||
and not utils.get_type(objects[0]) in ["BezCurve", "BSpline", "Wire"]:
|
||||
result = _draftify(objects[0])
|
||||
if result:
|
||||
_msg(translate("draft", "Found 1 non-parametric object: draftifying it"))
|
||||
@@ -603,7 +605,8 @@ def upgrade(objects, delete=False, force=None):
|
||||
# only one object: if not parametric, we "draftify" it
|
||||
elif len(objects) == 1 \
|
||||
and len(edges) == 1 \
|
||||
and not objects[0].isDerivedFrom("Part::Part2DObjectPython"):
|
||||
and not objects[0].isDerivedFrom("Part::Part2DObjectPython") \
|
||||
and not utils.get_type(objects[0]) in ["BezCurve", "BSpline", "Wire"]:
|
||||
edge_type = DraftGeomUtils.geomType(objects[0].Shape.Edges[0])
|
||||
# currently only support Line and Circle
|
||||
if edge_type in ("Line", "Circle"):
|
||||
|
||||
@@ -39,6 +39,7 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
import FreeCADGui as Gui
|
||||
from draftguitools import gui_base_original
|
||||
from draftguitools import gui_tool_utils
|
||||
from draftutils import utils
|
||||
from draftutils import gui_utils
|
||||
from draftutils.messages import _msg
|
||||
from draftutils.translate import translate
|
||||
@@ -115,10 +116,12 @@ class SubelementHighlight(gui_base_original.Modifier):
|
||||
def get_editable_objects_from_selection(self):
|
||||
"""Get editable Draft objects for the selection."""
|
||||
for obj in Gui.Selection.getSelection():
|
||||
if obj.isDerivedFrom("Part::Part2DObject"):
|
||||
if (obj.isDerivedFrom("Part::Part2DObject")
|
||||
or utils.get_type(obj) in ["BezCurve", "BSpline", "Wire"]):
|
||||
self.editable_objects.append(obj)
|
||||
elif (hasattr(obj, "Base")
|
||||
and obj.Base.isDerivedFrom("Part::Part2DObject")):
|
||||
and (obj.Base.isDerivedFrom("Part::Part2DObject")
|
||||
or utils.get_type(obj.Base) in ["BezCurve", "BSpline", "Wire"])):
|
||||
self.editable_objects.append(obj.Base)
|
||||
|
||||
def highlight_editable_objects(self):
|
||||
|
||||
@@ -81,7 +81,8 @@ def make_bezcurve(pointslist,
|
||||
utils.type_check([(placement,App.Placement)], "make_bezcurve")
|
||||
if len(pointslist) == 2: fname = "Line"
|
||||
else: fname = "BezCurve"
|
||||
obj = App.ActiveDocument.addObject("Part::Part2DObjectPython",fname)
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", fname)
|
||||
obj.addExtension("Part::AttachExtensionPython")
|
||||
BezCurve(obj)
|
||||
obj.Points = pointslist
|
||||
if degree:
|
||||
|
||||
@@ -50,7 +50,8 @@ def make_block(objectslist):
|
||||
if not App.ActiveDocument:
|
||||
App.Console.PrintError("No active document. Aborting\n")
|
||||
return
|
||||
obj = App.ActiveDocument.addObject("Part::Part2DObjectPython","Block")
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", "Block")
|
||||
obj.addExtension("Part::AttachExtensionPython")
|
||||
Block(obj)
|
||||
obj.Components = objectslist
|
||||
if App.GuiUp:
|
||||
|
||||
@@ -92,7 +92,8 @@ def make_bspline(pointslist, closed=False, placement=None, face=None, support=No
|
||||
utils.type_check([(placement,App.Placement)], "make_bspline")
|
||||
if len(pointslist) == 2: fname = "Line"
|
||||
else: fname = "BSpline"
|
||||
obj = App.ActiveDocument.addObject("Part::Part2DObjectPython",fname)
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", fname)
|
||||
obj.addExtension("Part::AttachExtensionPython")
|
||||
BSpline(obj)
|
||||
obj.Closed = closed
|
||||
obj.Points = pointslist
|
||||
|
||||
@@ -67,10 +67,16 @@ def make_clone(obj, delta=None, forcedraft=False):
|
||||
if not isinstance(obj,list):
|
||||
obj = [obj]
|
||||
|
||||
if (len(obj) == 1) and obj[0].isDerivedFrom("Part::Part2DObject"):
|
||||
cl = App.ActiveDocument.addObject("Part::Part2DObjectPython","Clone2D")
|
||||
if len(obj) == 1 \
|
||||
and obj[0].isDerivedFrom("Part::Part2DObject") \
|
||||
and utils.get_type(obj[0]) not in ["BezCurve", "BSpline", "Wire"]:
|
||||
# "BezCurve", "BSpline" and "Wire" objects created with < v1.1
|
||||
# are "Part::Part2DObject" objects but they need not be 2D.
|
||||
cl = App.ActiveDocument.addObject("Part::Part2DObjectPython", "Clone2D")
|
||||
cl.Label = prefix + obj[0].Label + " (2D)"
|
||||
elif (len(obj) == 1) and (hasattr(obj[0],"CloneOf") or (utils.get_type(obj[0]) == "BuildingPart")) and (not forcedraft):
|
||||
elif len(obj) == 1 \
|
||||
and (hasattr(obj[0], "CloneOf") or utils.get_type(obj[0]) == "BuildingPart") \
|
||||
and not forcedraft:
|
||||
# arch objects can be clones
|
||||
try:
|
||||
import Arch
|
||||
@@ -106,7 +112,7 @@ def make_clone(obj, delta=None, forcedraft=False):
|
||||
|
||||
# fall back to Draft clone mode
|
||||
if not cl:
|
||||
cl = App.ActiveDocument.addObject("Part::FeaturePython","Clone")
|
||||
cl = App.ActiveDocument.addObject("Part::FeaturePython", "Clone")
|
||||
cl.addExtension("Part::AttachExtensionPython")
|
||||
cl.Label = prefix + obj[0].Label
|
||||
Clone(cl)
|
||||
|
||||
@@ -108,7 +108,8 @@ def make_wire(pointslist, closed=False, placement=None, face=None, support=None,
|
||||
else:
|
||||
fname = "Wire"
|
||||
|
||||
obj = App.ActiveDocument.addObject("Part::Part2DObjectPython", fname)
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", fname)
|
||||
obj.addExtension("Part::AttachExtensionPython")
|
||||
Wire(obj)
|
||||
obj.Points = pointslist
|
||||
obj.Closed = closed
|
||||
|
||||
@@ -66,9 +66,7 @@ class DraftObject(object):
|
||||
allows distinguishing among various types of objects
|
||||
derived from the same C++ class.
|
||||
|
||||
>>> print(A.TypeId, "->", A.Proxy.Type)
|
||||
Part::Part2DObjectPython -> Wire
|
||||
>>> print(B.TypeId, "->", B.Proxy.Type)
|
||||
>>> print(obj.TypeId, "->", obj.Proxy.Type)
|
||||
Part::Part2DObjectPython -> Circle
|
||||
|
||||
This class attribute is accessible through the `Proxy` object:
|
||||
|
||||
@@ -121,8 +121,8 @@ def process(filename):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or None.
|
||||
The created Draft Wire object or None if the file contains less
|
||||
Part::Feature or None.
|
||||
The created object or None if the file contains fewer
|
||||
than 3 points.
|
||||
"""
|
||||
# Regex to identify data rows and throw away unused metadata
|
||||
|
||||
@@ -795,7 +795,7 @@ def drawLine(line, forceShape=False):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Edge')
|
||||
Part::Feature or Part::TopoShape ('Edge')
|
||||
The returned object is normally a `Wire`, if the global
|
||||
variables `dxfCreateDraft` or `dxfCreateSketch` are set,
|
||||
and `forceShape` is `False`.
|
||||
@@ -847,7 +847,7 @@ def drawPolyline(polyline, forceShape=False, num=None):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Wire', 'Face', 'Shell')
|
||||
Part::Feature or Part::TopoShape ('Wire', 'Face', 'Shell')
|
||||
It returns `None` if it fails producing a shape.
|
||||
|
||||
If the polyline has a `width` and the global variable
|
||||
@@ -1292,7 +1292,7 @@ def drawSplineIterpolation(verts, closed=False, forceShape=False,
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Edge', 'Face')
|
||||
Part::Feature or Part::TopoShape ('Edge', 'Face')
|
||||
The returned object is normally a `Draft Wire` or `Draft BSpline`,
|
||||
if the global variables `dxfCreateDraft` or `dxfCreateSketch` are set,
|
||||
and `forceShape` is `False`.
|
||||
@@ -1350,7 +1350,7 @@ def drawSplineOld(spline, forceShape=False):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Edge', 'Face')
|
||||
Part::Feature or Part::TopoShape ('Edge', 'Face')
|
||||
The returned object is normally a `Draft Wire` or `Draft BSpline`
|
||||
as returned from `drawSplineIterpolation()`.
|
||||
|
||||
@@ -1409,7 +1409,7 @@ def drawSpline(spline, forceShape=False):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Edge', 'Face')
|
||||
Part::Feature or Part::TopoShape ('Edge', 'Face')
|
||||
The returned object is normally a `Draft BezCurve`
|
||||
created with `Draft.make_bezcurve(controlpoints, degree=degree)`,
|
||||
if `forceShape` is `False` and there are no weights.
|
||||
@@ -1813,7 +1813,7 @@ def drawLayerBlock(objlist, name="LayerBlock"):
|
||||
|
||||
Returns
|
||||
-------
|
||||
Part::Part2DObject or Part::TopoShape ('Compound')
|
||||
Part::Feature or Part::TopoShape ('Compound')
|
||||
If the global variables `dxfCreateDraft` or `dxfCreateSketch` are set,
|
||||
and no element in `objlist` is a `Part.Shape`,
|
||||
it will try to return a `Draft Block`.
|
||||
@@ -1910,9 +1910,8 @@ def addObject(shape, name="Shape", layer=None):
|
||||
-------
|
||||
Part::Feature or Part::Part2DObject
|
||||
If the `shape` is a simple `Part.Shape`, it will be encapsulated
|
||||
inside a `Part::Feature` object and this will be returned.
|
||||
Otherwise, it is assumed it is already a Draft object
|
||||
(`Part::Part2DObject`) and will just return this.
|
||||
inside a `Part::Feature` object and this will be returned. Otherwise,
|
||||
it is assumed it is already a Draft object which will just be returned.
|
||||
|
||||
It applies the text and line color by calling `formatObject()`
|
||||
before returning the new object.
|
||||
@@ -1941,8 +1940,6 @@ def addObject(shape, name="Shape", layer=None):
|
||||
l = layerObjects[lay]
|
||||
l.append(newob)
|
||||
|
||||
|
||||
|
||||
formatObject(newob)
|
||||
return newob
|
||||
|
||||
|
||||
Reference in New Issue
Block a user